diff --git a/middleware/v2/.gitignore b/middleware/v2/.gitignore new file mode 100644 index 000000000..a941e67d4 --- /dev/null +++ b/middleware/v2/.gitignore @@ -0,0 +1,111 @@ +*.d +*.o +*.a +*.so +*.dep +*.dwo + +lib +bin +include +tags + +*_asan +sample/audio/sample_audio +sample/audio/sample_audio_aec +sample/audio/sample_audio_nr +sample/audio/sample_audio_resample +sample/audio/sample_audio_transcode +sample/audio/sample_audio_rtos +sample/cipher/sample_cipher +sample/cvg/sample_cvg +sample/mipi_tx/sample_dsi +sample/fisheye/sample_fisheye +sample/overlay/sample_overlay +sample/region/sample_region +sample/venc/sample_vcodec +sample/vdec/sample_vdec +sample/venc/sample_venc +sample/vio/sample_vio +sample/vdecvo/sample_vdecvo +sample/multivenc/sample_multivenc +sample/ir_auto/ir_auto +sample/ive/sample_16bitto8bit +sample/ive/sample_add +sample/ive/sample_and +sample/ive/sample_bernsen +sample/ive/sample_bgmodel +sample/ive/sample_cannyedge +sample/ive/sample_cannyhysedge +sample/ive/sample_csc +sample/ive/sample_dilate +sample/ive/sample_dma +sample/ive/sample_erode +sample/ive/sample_filter +sample/ive/sample_filterandcsc +sample/ive/sample_framediffmotion +sample/ive/sample_gmm +sample/ive/sample_gmm2 +sample/ive/sample_gradfg +sample/ive/sample_hist +sample/ive/sample_integ +sample/ive/sample_lbp +sample/ive/sample_magandang +sample/ive/sample_map +sample/ive/sample_ncc +sample/ive/sample_normgrad +sample/ive/sample_or +sample/ive/sample_ordstatfilter +sample/ive/sample_query +sample/ive/sample_resize +sample/ive/sample_sad +sample/ive/sample_sobel +sample/ive/sample_stcandicorner +sample/ive/sample_sub +sample/ive/sample_thresh +sample/ive/sample_thresh_S16 +sample/ive/sample_thresh_U16 +sample/ive/sample_xor +sample/osdc/sample_osdc +sample/scene_auto/sample_scene_auto +sample/sensor_test/sensor_test + +self_test/cvi_test/cvi_test +self_test/cvi_test/res +self_test/tpu/sample_tpu +self_test/vip_fpga/vip_fpga +self_test/vi_ut/vi_ut +self_test/vpss_ut/vpss_ut +self_test/vpss_ut/vpss_ut_client +self_test/vo_ut/vo_ut +self_test/rgn_ut/rgn_ut +self_test/dwa_ut/dwa_ut +self_test/vb_ut/vb_ut +self_test/sys_ut/sys_ut +self_test/fast_image_ut/fast_image_ut +self_test/audio/aud_auto_test_sample/cvi_auto_play +self_test/audio/aud_auto_test_sample/cvi_auto_record +self_test/audio/aud_auto_test_sample/cvi_auto_special +self_test/audio/audio_aec/sample_audio_aec +self_test/audio/audio_anr/sample_audio_nr +self_test/audio/audio_pcm/sample_audio_internal +self_test/audio/audio_resample/sample_audio_resample +self_test/audio/audio_transcode/sample_audio_transcode + + + +modules/venc/vc/jpeg/driver/bm_jpg_test +modules/venc/vc/jpeg/driver/bmjpuapi/bmjpegdec +modules/venc/vc/jpeg/driver/bmjpuapi/bmjpegenc +modules/venc/vc/vcodec/codebase/cvi_h265_enc_test +modules/venc/vc/vcodec/codebase/cvi_h264_dec +modules/venc/vc/vcodec/codebase/cvi_h265_dec +modules/venc/vc/jpeg/driver/cvi_jpg_codec + +modules/venc/vc/vcodec/codebase/sample/cvi_vcodec_version.h +modules/venc/vc/jpeg/driver/include/version.h + +.vscode/settings.json + +modules/isp + diff --git a/middleware/v2/Makefile.param b/middleware/v2/Makefile.param new file mode 100644 index 000000000..c11614980 --- /dev/null +++ b/middleware/v2/Makefile.param @@ -0,0 +1,199 @@ +SHELL = /bin/bash + +include $(BUILD_PATH)/.config + +## setup path ## +ROOT_DIR:=$(shell dirname $(realpath $(PARAM_FILE))) +export MW_PATH:= $(ROOT_DIR) +export MW_INC := $(MW_PATH)/include +export MW_LIB := $(MW_PATH)/lib +export MW_3RD_LIB := $(MW_PATH)/lib/3rd + +ifeq ($(KERNEL_DIR), ) +KERNEL_PATH ?= $(ROOT_DIR)/../../$(KERNEL_SRC) +ifeq ($(PROJECT_FULLNAME), ) + $(error PROJECT_FULLNAME not defined! Please check!) +else + KERNEL_DIR = $(KERNEL_PATH)/build/$(PROJECT_FULLNAME) +endif +endif + +ifeq ($(SDK_VER), 32bit) + export CROSS_COMPILE = $(CROSS_COMPILE_32) + SYSROOT := $(ROOT_DIR)/../../ramdisk/sysroot/sysroot-glibc-linaro-2.23-2017.05-arm-linux-gnueabihf/ + KERNEL_INC := $(KERNEL_DIR)/arm/usr/include + OPT_LEVEL := -O3 +else ifeq ($(SDK_VER), 64bit) + export CROSS_COMPILE = $(CROSS_COMPILE_64) + SYSROOT := $(ROOT_DIR)/../../ramdisk/sysroot/sysroot-glibc-linaro-2.23-2017.05-aarch64-linux-gnu/ + KERNEL_INC := $(KERNEL_DIR)/arm64/usr/include + OPT_LEVEL := -O3 +else ifeq ($(SDK_VER), uclibc) + export CROSS_COMPILE = $(CROSS_COMPILE_UCLIBC) + SYSROOT := $(ROOT_DIR)/../../ramdisk/sysroot/sysroot-uclibc/ + KERNEL_INC := $(KERNEL_DIR)/arm/usr/include + OPT_LEVEL := -Os +else ifeq ($(SDK_VER), glibc_riscv64) + export CROSS_COMPILE = $(CROSS_COMPILE_GLIBC_RISCV64) + SYSROOT := $(ROOT_DIR)/../../host-tools/gcc/riscv64-linux-x86_64/sysroot + KERNEL_INC := $(KERNEL_DIR)/riscv/usr/include + OPT_LEVEL := -Os + OPT_LEVEL += -march=rv64imafdcvxthead -mcmodel=medany -mabi=lp64dv +else ifeq ($(SDK_VER), musl_riscv64) + export CROSS_COMPILE = $(CROSS_COMPILE_MUSL_RISCV64) + SYSROOT := $(ROOT_DIR)/../../host-tools/gcc/riscv64-linux-musl-x86_64/sysroot + KERNEL_INC := $(KERNEL_DIR)/riscv/usr/include + OPT_LEVEL := -Os + OPT_LEVEL += -march=rv64imafdcvxthead -mcmodel=medany -mabi=lp64d +endif + +## INCLUDE PATH ## +COMMON_INC = $(MW_PATH)/sample/common/include +SYS_INC = $(MW_PATH)/modules/sys/include +VPU_INC = $(MW_PATH)/modules/vpu/include +AUD_INC = $(MW_PATH)/modules/audio/include +OSDC_INC = $(MW_PATH)/modules/osdc/include +BIN_INC = $(MW_PATH)/modules/bin/include + +MODULES_DIR = $(shell if [ -d $(MW_PATH)/modules ]; then echo "exist"; else echo "noexist"; fi) + +ifeq ("$(MODULES_DIR)" , "noexist") +ISP_INC = $(MW_INC)/isp/$(shell echo $(CHIP_ARCH) | tr A-Z a-z) +else +ISP_INC = $(MW_PATH)/modules/isp/include/$(shell echo $(CHIP_ARCH) | tr A-Z a-z) +endif + +## LIBRARY ## +ISP_LIB := -lisp -lawb -lae -laf +ISP_OBJ := $(MW_LIB)/libisp.a $(MW_LIB)/libae.a $(MW_LIB)/libawb.a $(MW_LIB)/libaf.a + +ifeq ($(CHIP_ARCH), CV183X) +else ifeq ($(CHIP_ARCH), $(filter $(CHIP_ARCH), CV182X MARS PHOBOS CV181X CV180X)) +ISP_LIB += -lisp_algo +ISP_OBJ += $(MW_LIB)/libisp_algo.a +else +ifeq ($(SUBTYPE), fpga) +ISP_LIB += -lisp_algo +ISP_OBJ += $(MW_LIB)/libisp_algo.a +else +$(error UNKNOWN chip architecture - $(CHIP_ARCH)) +endif +endif + +## DEFINES ## +export PROJ_CFLAGS = -DF10 + +ifeq ($(SUBTYPE), fpga) +export FPGA_PORTING := true +else +export FPGA_PORTING := false +endif + +MW_GLIBC_DEPENDENT := $(SYSROOT)/lib + +## GCC COMPILER ## +CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +AR = $(CROSS_COMPILE)ar +LD = $(CROSS_COMPILE)ld +NM = $(CROSS_COMPILE)nm +RANLIB = $(CROSS_COMPILE)ranlib +STRIP = $(CROSS_COMPILE)strip +OBJCOPY = $(CROSS_COMPILE)objcopy + +### COMMON COMPILER FLAGS ### +# +# export TARGET_PACKAGES_INCLUDE and TARGET_PACKAGES_LIBDIR from build/Makefile +# +WARNING_LEVEL=-Wall -Wextra -Werror + +#Generate object files by CC +CFLAGS = $(OPT_LEVEL) -std=gnu11 -g $(WARNING_LEVEL) -fPIC -ffunction-sections -fdata-sections -Wl,--gc-sections $(CVI_TARGET_PACKAGES_INCLUDE) +#Generate object files by CXX +CXXFLAGS = $(OPT_LEVEL) -std=gnu++11 -g $(WARNING_LEVEL) -fPIC -ffunction-sections -fdata-sections -Wl,--gc-sections $(CVI_TARGET_PACKAGES_INCLUDE) +#Generate dependencies files by CC and CXX +DEPFLAGS = -MMD + +### COMMON AR and LD FLAGS ### +#Generate archive file by AR +ARFLAGS = rcs +#Generate shared library by LD +LDFLAGS = -shared -fPIC --gc-sections -export-dynamic -L$(MW_LIB) -L$(MW_3RD_LIB) --sysroot $(SYSROOT) $(CVI_TARGET_PACKAGES_LIBDIR) + +### COMMON ELF FLAGS ### +#Generate ELF files by CC and CXX +ELFFLAGS = $(OPT_LEVEL) -Wl,--gc-sections -rdynamic -L$(MW_LIB) -L$(MW_3RD_LIB) $(CVI_TARGET_PACKAGES_LIBDIR) + +ifeq ($(SDK_VER), glibc_riscv64) +CFLAGS += -mno-ldd +CXXFLAGS += -mno-ldd +else ifeq ($(SDK_VER), musl_riscv64) +CFLAGS += -mno-ldd +CXXFLAGS += -mno-ldd +endif + +ifeq ($(CONFIG_DEBUG_INFO), y) +ifeq ($(CONFIG_DEBUG_INFO_SPLIT), y) +CFLAGS += -gsplit-dwarf +CXXFLAGS += -gsplit-dwarf +else ifeq ($(CONFIG_DEBUG_INFO_DWARF4), y) +CFLAGS += -gdwarf-4 +CXXFLAGS += -gdwarf-4 +else ifeq ($(CONFIG_DEBUG_INFO_REDUCED), y) +CFLAGS += -femit-struct-debug-baseonly -fno-var-tracking +CXXFLAGS += -femit-struct-debug-baseonly -fno-var-tracking +else +CFLAGS += -Og +CXXFLAGS += -Og +endif +endif + +ifeq ($(MTRACE), y) +ifneq ($(SDK_VER),uclibc) +CFLAGS += -DMTRACE +endif +endif + +ifeq ($(FPGA_PORTING), true) +CFLAGS += -DFPGA_PORTING +endif + +ifeq ($(CONFIG_DDR_64MB_SIZE), y) +CFLAGS += -DDDR_64MB_SIZE +endif + +SAMPLE_STATIC ?= 1 +SELF_TEST_STATIC ?= 1 +SAMPLE_TPU_ENABLE ?= 0 +ENABLE_ISP_C906L = 0 + +ifeq ($(CONFIG_ENABLE_SDK_ASAN), y) +CFLAGS += -fsanitize=address -fno-omit-frame-pointer +CXXFLAGS += -fsanitize=address -fno-omit-frame-pointer +ELFFLAGS += -fsanitize=address -fno-omit-frame-pointer -g +LDFLAGS += -fsanitize=address -fno-omit-frame-pointer -fno-common -g +SAMPLE_STATIC = 0 +SELF_TEST_STATIC = 0 +endif + +CFLAGS += -DARCH_$(CHIP_ARCH) + +ifeq ("$(CVIARCH)", "CV181X") +CFLAGS += -D__CV181X__ +endif +ifeq ("$(CVIARCH)", "CV180X") +CFLAGS += -D__CV180X__ +endif + +## COLOR ## +BLACK = "\e[30;1m" +RED = "\e[31;1m" +GREEN = "\e[32;1m" +YELLOW = "\e[33;1m" +BLUE = "\e[34;1m" +PURPLE = "\e[35;1m" +CYAN = "\e[36;1m" +WHITE = "\e[37;1m" + +END= "\e[0m" + diff --git a/middleware/v2/component/isp/Makefile b/middleware/v2/component/isp/Makefile new file mode 100644 index 000000000..2dc7ee95f --- /dev/null +++ b/middleware/v2/component/isp/Makefile @@ -0,0 +1,16 @@ +SHELL = /bin/bash + +include $(BUILD_PATH)/.config +include sensor.mk + +chip_arch = $(shell echo $(CVIARCH) | tr A-Z a-z) + +all: + pushd sensor/$(chip_arch) && \ + $(MAKE) all && \ + popd; + +clean: + pushd sensor/$(chip_arch) && \ + $(MAKE) clean && \ + popd; diff --git a/middleware/v2/component/isp/sensor.mk b/middleware/v2/component/isp/sensor.mk new file mode 100644 index 000000000..53dccade1 --- /dev/null +++ b/middleware/v2/component/isp/sensor.mk @@ -0,0 +1,103 @@ +ifeq ($(CHIP_ARCH),CV183X) +sensor-$(CONFIG_SENSOR_GCORE_GC2053) += gcore_gc2053 +sensor-$(CONFIG_SENSOR_GCORE_GC2053_SLAVE) += gcore_gc2053_slave +sensor-$(CONFIG_SENSOR_GCORE_GC2053_1L) += gcore_gc2053_1L +sensor-$(CONFIG_SENSOR_GCORE_GC2093) += gcore_gc2093 +sensor-$(CONFIG_SENSOR_GCORE_GC2093_SLAVE) += gcore_gc2093_slave +sensor-$(CONFIG_SENSOR_GCORE_GC4653) += gcore_gc4653 +sensor-$(CONFIG_SENSOR_GCORE_GC4653_SLAVE) += gcore_gc4653_slave +sensor-$(CONFIG_SENSOR_NEXTCHIP_N5) += nextchip_n5 +sensor-$(CONFIG_SENSOR_OV_OS02D10) += ov_os02d10 +sensor-$(CONFIG_SENSOR_OV_OS02D10_SLAVE) += ov_os02d10_slave +sensor-$(CONFIG_SENSOR_OV_OS02K10_SLAVE) += ov_os02k10_slave +sensor-$(CONFIG_SENSOR_OV_OS04C10) += ov_os04c10 +sensor-$(CONFIG_SENSOR_OV_OS04C10_SLAVE) += ov_os04c10_slave +sensor-$(CONFIG_SENSOR_OV_OS08A20) += ov_os08a20 +sensor-$(CONFIG_SENSOR_OV_OS08A20_SLAVE) += ov_os08a20_slave +sensor-$(CONFIG_SENSOR_PICO_384) += pico_384 +sensor-$(CONFIG_SENSOR_PICO_640) += pico_640 +sensor-$(CONFIG_SENSOR_PIXELPLUS_PR2020) += pixelplus_pr2020 +sensor-$(CONFIG_SENSOR_PIXELPLUS_PR2100) += pixelplus_pr2100 +sensor-$(CONFIG_SENSOR_SMS_SC035HGS) += sms_sc035hgs +sensor-$(CONFIG_SENSOR_SMS_SC200AI) += sms_sc200ai +sensor-$(CONFIG_SENSOR_SMS_SC401AI) += sms_sc401ai +sensor-$(CONFIG_SENSOR_SMS_SC850SL) += sms_sc850sl +sensor-$(CONFIG_SENSOR_SMS_SC3335) += sms_sc3335 +sensor-$(CONFIG_SENSOR_SMS_SC3335_SLAVE) += sms_sc3335_slave +sensor-$(CONFIG_SENSOR_SMS_SC3336) += sms_sc3336 +sensor-$(CONFIG_SENSOR_SMS_SC4210) += sms_sc4210 +sensor-$(CONFIG_SENSOR_SMS_SC8238) += sms_sc8238 +sensor-$(CONFIG_SENSOR_SOI_F23) += soi_f23 +sensor-$(CONFIG_SENSOR_SOI_F35) += soi_f35 +sensor-$(CONFIG_SENSOR_SOI_F35_SLAVE) += soi_f35_slave +sensor-$(CONFIG_SENSOR_SOI_H65) += soi_h65 +sensor-$(CONFIG_SENSOR_SONY_IMX290_2L) += sony_imx290_2L +sensor-$(CONFIG_SENSOR_SONY_IMX307) += sony_imx307 +sensor-$(CONFIG_SENSOR_SONY_IMX307_SLAVE) += sony_imx307_slave +sensor-$(CONFIG_SENSOR_SONY_IMX307_2L) += sony_imx307_2L +sensor-$(CONFIG_SENSOR_SONY_IMX307_SUBLVDS) += sony_imx307_sublvds +sensor-$(CONFIG_SENSOR_SONY_IMX327) += sony_imx327 +sensor-$(CONFIG_SENSOR_SONY_IMX327_SLAVE) += sony_imx327_slave +sensor-$(CONFIG_SENSOR_SONY_IMX327_2L) += sony_imx327_2L +sensor-$(CONFIG_SENSOR_SONY_IMX327_SUBLVDS) += sony_imx327_sublvds +sensor-$(CONFIG_SENSOR_SONY_IMX334) += sony_imx334 +sensor-$(CONFIG_SENSOR_SONY_IMX335) += sony_imx335 +sensor-$(CONFIG_SENSOR_SONY_IMX347) += sony_imx347 +sensor-$(CONFIG_SENSOR_SONY_IMX385) += sony_imx385 +sensor-$(CONFIG_SENSOR_TECHPOINT_TP2850) += techpoint_tp2850 +sensor-$(CONFIG_SENSOR_VIVO_MCS369) += vivo_mcs369 +sensor-$(CONFIG_SENSOR_VIVO_MCS369Q) += vivo_mcs369q +sensor-$(CONFIG_SENSOR_VIVO_MM308M2) += vivo_mm308m2 +else ifeq ($(CHIP_ARCH), $(filter $(CHIP_ARCH), CV180X CV181X CV182X)) +sensor-$(CONFIG_SENSOR_BRIGATES_BG0808) += brigates_bg0808 +sensor-$(CONFIG_SENSOR_GCORE_GC02M1) += gcore_gc02m1 +sensor-$(CONFIG_SENSOR_GCORE_GC1054) += gcore_gc1054 +sensor-$(CONFIG_SENSOR_GCORE_GC2053) += gcore_gc2053 +sensor-$(CONFIG_SENSOR_GCORE_GC2053_SLAVE) += gcore_gc2053_slave +sensor-$(CONFIG_SENSOR_GCORE_GC2053_1L) += gcore_gc2053_1L +sensor-$(CONFIG_SENSOR_GCORE_GC2093) += gcore_gc2093 +sensor-$(CONFIG_SENSOR_GCORE_GC2145) += gcore_gc2145 +sensor-$(CONFIG_SENSOR_GCORE_GC4023) += gcore_gc4023 +sensor-$(CONFIG_SENSOR_GCORE_GC4653) += gcore_gc4653 +sensor-$(CONFIG_SENSOR_NEXTCHIP_N5) += nextchip_n5 +sensor-$(CONFIG_SENSOR_NEXTCHIP_N6) += nextchip_n6 +sensor-$(CONFIG_SENSOR_OV_OS04A10) += ov_os04a10 +sensor-$(CONFIG_SENSOR_OV_OS04C10) += ov_os04c10 +sensor-$(CONFIG_SENSOR_OV_OS08A20) += ov_os08a20 +sensor-$(CONFIG_SENSOR_OV_OV4689) += ov_ov4689 +sensor-$(CONFIG_SENSOR_OV_OV6211) += ov_ov6211 +sensor-$(CONFIG_SENSOR_OV_OV7251) += ov_ov7251 +sensor-$(CONFIG_SENSOR_PIXELPLUS_PR2020) += pixelplus_pr2020 +sensor-$(CONFIG_SENSOR_PIXELPLUS_PR2100) += pixelplus_pr2100 +sensor-$(CONFIG_SENSOR_SMS_SC035GS) += sms_sc035gs +sensor-$(CONFIG_SENSOR_SMS_SC035GS_1L) += sms_sc035gs_1L +sensor-$(CONFIG_SENSOR_SMS_SC035HGS) += sms_sc035hgs +sensor-$(CONFIG_SENSOR_SMS_SC200AI) += sms_sc200ai +sensor-$(CONFIG_SENSOR_SMS_SC301IOT) += sms_sc301iot +sensor-$(CONFIG_SENSOR_SMS_SC401AI) += sms_sc401ai +sensor-$(CONFIG_SENSOR_SMS_SC500AI) += sms_sc500ai +sensor-$(CONFIG_SENSOR_SMS_SC501AI_2L) += sms_sc501ai_2L +sensor-$(CONFIG_SENSOR_SMS_SC531AI_2L) += sms_sc531ai_2L +sensor-$(CONFIG_SENSOR_SMS_SC3332) += sms_sc3332 +sensor-$(CONFIG_SENSOR_SMS_SC3335) += sms_sc3335 +sensor-$(CONFIG_SENSOR_SMS_SC3336) += sms_sc3336 +sensor-$(CONFIG_SENSOR_SMS_SC2335) += sms_sc2335 +sensor-$(CONFIG_SENSOR_SMS_SC2336) += sms_sc2336 +sensor-$(CONFIG_SENSOR_SMS_SC4336) += sms_sc4336 +sensor-$(CONFIG_SENSOR_SOI_F23) += soi_f23 +sensor-$(CONFIG_SENSOR_SOI_F35) += soi_f35 +sensor-$(CONFIG_SENSOR_SOI_F37P) += soi_f37p +sensor-$(CONFIG_SENSOR_SOI_K06) += soi_k06 +sensor-$(CONFIG_SENSOR_SOI_Q03) += soi_q03 +sensor-$(CONFIG_SENSOR_SONY_IMX307) += sony_imx307 +sensor-$(CONFIG_SENSOR_SONY_IMX307_SLAVE) += sony_imx307_slave +sensor-$(CONFIG_SENSOR_SONY_IMX307_2L) += sony_imx307_2L +sensor-$(CONFIG_SENSOR_SONY_IMX327) += sony_imx327 +sensor-$(CONFIG_SENSOR_SONY_IMX327_SLAVE) += sony_imx327_slave +sensor-$(CONFIG_SENSOR_SONY_IMX327_2L) += sony_imx327_2L +sensor-$(CONFIG_SENSOR_SONY_IMX327_FPGA) += sony_imx327_fpga +sensor-$(CONFIG_SENSOR_SONY_IMX327_SUBLVDS) += sony_imx327_sublvds +sensor-$(CONFIG_SENSOR_SONY_IMX335) += sony_imx335 +else +$(error not supported chip arch cv180x/cv181x/cv182x/cv183x) +endif diff --git a/middleware/v2/component/isp/sensor/cv180x/Makefile b/middleware/v2/component/isp/sensor/cv180x/Makefile new file mode 100644 index 000000000..92302dc00 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/Makefile @@ -0,0 +1,180 @@ +SHELL = /bin/bash + +ifeq ($(PARAM_FILE), ) +PARAM_FILE=../../../../../$(shell echo $(MW_VER))/Makefile.param +include $(PARAM_FILE) +endif +include ../../../../../$(shell echo $(MW_VER))/component/isp/sensor.mk + +define MAKE_SENSOR + pushd $(1) && \ + $(MAKE) all && \ + popd +endef + +.PHONY : prepare clean $(sensor-y) +all: prepare $(sensor-y) all_sensor + +prepare: + @echo "#################################################" + @echo "#" + @echo "# Compiling 'component libs' Configs as below..." + @echo "# SENSOR_LIST=$(sensor-y)" + @echo "#" + @echo "#################################################" + +brigates_bg0808: + $(call MAKE_SENSOR, ${@}) + +gcore_gc02m1: + $(call MAKE_SENSOR, ${@}) + +gcore_gc1054: + $(call MAKE_SENSOR, ${@}) + +gcore_gc2053: + $(call MAKE_SENSOR, ${@}) + +gcore_gc2053_slave: + $(call MAKE_SENSOR, ${@}) + +gcore_gc2053_1L: + $(call MAKE_SENSOR, ${@}) + +gcore_gc2093: + $(call MAKE_SENSOR, ${@}) + +gcore_gc2145: + $(call MAKE_SENSOR, ${@}) + +gcore_gc4023: + $(call MAKE_SENSOR, ${@}) + +gcore_gc4653: + $(call MAKE_SENSOR, ${@}) + +nextchip_n5: + $(call MAKE_SENSOR, ${@}) + +nextchip_n6: + $(call MAKE_SENSOR, ${@}) + +ov_os04a10: + $(call MAKE_SENSOR, ${@}) + +ov_os04c10: + $(call MAKE_SENSOR, ${@}) + +ov_os08a20: + $(call MAKE_SENSOR, ${@}) + +ov_ov4689: + $(call MAKE_SENSOR, ${@}) + +ov_ov6211: + $(call MAKE_SENSOR, ${@}) + +ov_ov7251: + $(call MAKE_SENSOR, ${@}) + +pixelplus_pr2020: + $(call MAKE_SENSOR, ${@}) + +pixelplus_pr2100: + $(call MAKE_SENSOR, ${@}) + +sms_sc035gs: + $(call MAKE_SENSOR, ${@}) + +sms_sc035gs_1L: + $(call MAKE_SENSOR, ${@}) + +sms_sc035hgs: + $(call MAKE_SENSOR, ${@}) + +sms_sc200ai: + $(call MAKE_SENSOR, ${@}) + +sms_sc301iot: + $(call MAKE_SENSOR, ${@}) + +sms_sc401ai: + $(call MAKE_SENSOR, ${@}) + +sms_sc500ai: + $(call MAKE_SENSOR, ${@}) + +sms_sc501ai_2L: + $(call MAKE_SENSOR, ${@}) + +sms_sc3332: + $(call MAKE_SENSOR, ${@}) + +sms_sc531ai_2L: + $(call MAKE_SENSOR, ${@}) + +sms_sc3335: + $(call MAKE_SENSOR, ${@}) + +sms_sc3336: + $(call MAKE_SENSOR, ${@}) + +sms_sc2335: + $(call MAKE_SENSOR, ${@}) + +sms_sc2336: + $(call MAKE_SENSOR, ${@}) + +sms_sc4336: + $(call MAKE_SENSOR, ${@}) + +soi_f23: + $(call MAKE_SENSOR, ${@}) + +soi_f35: + $(call MAKE_SENSOR, ${@}) + +soi_f37p: + $(call MAKE_SENSOR, ${@}) + +soi_q03: + $(call MAKE_SENSOR, ${@}) + +soi_k06: + $(call MAKE_SENSOR, ${@}) + +sony_imx307: + $(call MAKE_SENSOR, ${@}) + +sony_imx307_slave: + $(call MAKE_SENSOR, ${@}) + +sony_imx307_2L: + $(call MAKE_SENSOR, ${@}) + +sony_imx327: + $(call MAKE_SENSOR, ${@}) + +sony_imx327_slave: + $(call MAKE_SENSOR, ${@}) + +sony_imx327_2L: + $(call MAKE_SENSOR, ${@}) + +sony_imx327_fpga: + $(call MAKE_SENSOR, ${@}) + +sony_imx327_sublvds: + $(call MAKE_SENSOR, ${@}) + +sony_imx335: + $(call MAKE_SENSOR, ${@}) + +all_sensor: + @$(MAKE) -f Makefile_full || exit 1; + +clean: + @for x in `find ./ -maxdepth 2 -mindepth 2 -name "Makefile" `; \ + do cd `dirname $$x`; if [ $$? ]; then $(MAKE) clean; cd -; fi; done + @echo "#" + @$(MAKE) clean -f Makefile_full || exit 1; diff --git a/middleware/v2/component/isp/sensor/cv180x/Makefile_full b/middleware/v2/component/isp/sensor/cv180x/Makefile_full new file mode 100644 index 000000000..db3da3c28 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/Makefile_full @@ -0,0 +1,29 @@ +SHELL = /bin/bash + +ifeq ($(PARAM_FILE), ) +PARAM_FILE=../../../../../$(shell echo $(MW_VER))/Makefile.param +include $(PARAM_FILE) +endif +include ../../sensor.mk + +SRCS = $(shell find $(sensor-y) -name '*.c') +OBJS = $(SRCS:.c=.o) + +TARGET_A = $(MW_LIB)/libsns_full.a +TARGET_SO = $(MW_LIB)/libsns_full.so + +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS_PATH) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(TARGET_A) $(TARGET_SO) diff --git a/middleware/v2/component/isp/sensor/cv180x/brigates_bg0808/Makefile b/middleware/v2/component/isp/sensor/cv180x/brigates_bg0808/Makefile new file mode 100644 index 000000000..8bc92e246 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/brigates_bg0808/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_bg0808.a +TARGET_SO = $(MW_LIB)/libsns_bg0808.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/brigates_bg0808/bg0808_cmos.c b/middleware/v2/component/isp/sensor/cv180x/brigates_bg0808/bg0808_cmos.c new file mode 100644 index 000000000..d367eeab1 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/brigates_bg0808/bg0808_cmos.c @@ -0,0 +1,1181 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "bg0808_cmos_ex.h" +#include "bg0808_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define BG0808_ID 0x0808 +#define BG0808_I2C_ADDR 0x32 +#define BG0808_I2C_ADDR_IS_VALID(addr) ((addr) == BG0808_I2C_ADDR) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastBG0808[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define BG0808_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastBG0808[dev]) +#define BG0808_SENSOR_SET_CTX(dev, pstCtx) (g_pastBG0808[dev] = pstCtx) +#define BG0808_SENSOR_RESET_CTX(dev) (g_pastBG0808[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunBG0808_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16BG0808_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16BG0808_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeBg0808_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_u32SexpOld; + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****BG0808 Lines Range*****/ +#define BG0808_FULL_LINES_MAX (0xFFFF) + +/*****BG0808 Register Address*****/ +#define BG0808_EXP_H_ADDR (0x000c) +#define BG0808_EXP_L_ADDR (0x000d) +#define BG0808_SEXP_H_ADDR (0x0022) +#define BG0808_SEXP_L_ADDR (0x0023) + +#define BG0808_AGAIN_ADDR (0x00a2) +#define BG0808_SAGAIN_ADDR (0x00a4) +#define BG0808_CLAMP_MODE_ADDR (0x0073) + +#define BG0808_DGAIN_H_ADDR (0x00c0) +#define BG0808_DGAIN_L_ADDR (0x00c1) +#define BG0808_SDGAIN_H_ADDR (0x00c2) +#define BG0808_SDGAIN_L_ADDR (0x00c3) + +#define BG0808_VMAX_H_ADDR (0x0010) +#define BG0808_VMAX_L_ADDR (0x0011) +#define BG0808_SHADOW_ADDR (0x001d) + +#define AGAIN_MAX_IDX (64) +#define DGAIN_MAX_IDX (83) + +#define BG0808_RES_IS_1080P(w, h) ((w) == 1920 && (h) == 1080) + +#define BG0808_EXPACCURACY (1) +#define BG0808_SEXP_ADDSPEED_MAX (264) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const BG0808_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astBG0808_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = BG0808_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = BG0808_EXPACCURACY; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = pstAeSnsDft->u32MaxIntTime; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + break; + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 3; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astBG0808_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astBG0808_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astBG0808_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case BG0808_MODE_1920X1080P30: + case BG0808_MODE_1920X1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > BG0808_FULL_LINES_MAX) ? BG0808_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + pstSnsRegsInfo->astI2cData[WDR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 1; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + CVI_U32 SexpAddSpeed = 0; + + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 1 + * max : vts - 1 + * step : 1 + */ + u32MinTime = 1; + u32MaxTime = pstSnsState->au32FL[0] - 1; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_ADDR].u32Data = ((u32TmpIntTime & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_ADDR].u32Data = (u32TmpIntTime & 0x00FF); + } else { + /* + * Long exp + Short exp < VTS + * sexp[N+1] - sexp[N] <= 264 + */ + /* sexp */ + pstSnsState->au32WDRIntTime[0] = u32IntTime[0]; + /* lexp */ + pstSnsState->au32WDRIntTime[1] = u32IntTime[1]; + SexpAddSpeed = pstSnsState->au32WDRIntTime[0] > g_u32SexpOld ? + (pstSnsState->au32WDRIntTime[0] - g_u32SexpOld) : 0; + pstSnsState->au32WDRIntTime[0] = SexpAddSpeed >= BG0808_SEXP_ADDSPEED_MAX ? + BG0808_SEXP_ADDSPEED_MAX : pstSnsState->au32WDRIntTime[0]; + pstSnsRegsInfo->astI2cData[WDR_EXP_H_ADDR].u32Data = ((pstSnsState->au32WDRIntTime[1] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR_EXP_L_ADDR].u32Data = (pstSnsState->au32WDRIntTime[1] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_SEXP_H_ADDR].u32Data = ((pstSnsState->au32WDRIntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR_SEXP_L_ADDR].u32Data = (pstSnsState->au32WDRIntTime[0] & 0xFF); + + g_u32SexpOld = pstSnsState->au32WDRIntTime[0]; + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } + + return CVI_SUCCESS; +} + +typedef struct again_tbl_info_s { + CVI_U32 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} again_tbl_info_s; + +static CVI_U32 Again_table[AGAIN_MAX_IDX + 1] = { + 1024, 1036, 1050, 1063, 1077, 1092, 1107, 1122, 1137, 1153, + 1170, 1187, 1204, 1222, 1241, 1260, 1280, 1300, 1321, 1342, + 1365, 1388, 1412, 1437, 1462, 1489, 1517, 1545, 1575, 1606, + 1638, 1671, 1706, 1742, 1780, 1820, 1861, 1905, 1950, 1998, + 2048, 2100, 2155, 2214, 2275, 2340, 2409, 2482, 2560, 2642, + 2730, 2824, 2925, 3034, 3150, 3276, 3413, 3561, 3723, 3900, + 4096, 4311, 4551, 4818, 5120 +}; + +static struct again_tbl_info_s AgainInfo = { + .gainMax = 5120, + .idxBase = 0, + .regGainFineBase = 0x7F, + .regGainFineStep = 1, +}; + +typedef struct dgain_tbl_info_s { + CVI_U8 regH[DGAIN_MAX_IDX + 1]; + CVI_U8 regL[DGAIN_MAX_IDX + 1]; +} dgain_tbl_info_s; + +static CVI_U32 Dgain_table[DGAIN_MAX_IDX + 1] = { + 1024, 1084, 1144, 1204, 1264, 1324, 1384, 1444, 1504, 1564, + 1624, 1684, 1744, 1804, 1864, 2004, 2144, 2284, 2424, 2564, + 2704, 2844, 2984, 3124, 3264, 3404, 3544, 3684, 3824, 3964, + 4104, 4244, 4384, 4524, 4664, 4804, 5044, 5284, 5524, 5764, + 6004, 6244, 6484, 6724, 6964, 7204, 7444, 7684, 7924, 8164, + 8404, 8644, 8884, 9124, 9364, 9604, 9844, 10084, 10324, 10564, + 10804, 11044, 11284, 11524, 11764, 12004, 12244, 12484, 12724, 12964, + 13204, 13444, 13684, 13924, 14164, 14404, 14644, 14884, 15124, 15364, + 15604, 15844, 16084, 16324 +}; + +static struct dgain_tbl_info_s DgainInfo = { + .regH = { + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x3, + 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x5, + 0x5, 0x5, 0x5, 0x6, 0x6, 0x6, 0x6, 0x7, 0x7, 0x7, + 0x8, 0x8, 0x8, 0x8, 0x9, 0x9, 0x9, 0xA, 0xA, 0xB, + 0xB, 0xC, 0xC, 0xD, 0xD, 0xE, 0xE, 0xF, 0xF, 0xF, + 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, + 0x15, 0x15, 0x16, 0x16, 0x16, 0x17, 0x17, 0x18, 0x18, 0x19, + 0x19, 0x1A, 0x1A, 0x1B, 0x1B, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, + 0x1E, 0x1E, 0x1F, 0x1F + }, + .regL = { + 0x0, 0x1E, 0x3C, 0x5A, 0x78, 0x96, 0xB4, 0xD2, 0xF0, 0xE, + 0x2C, 0x4A, 0x68, 0x86, 0xA4, 0xEA, 0x30, 0x76, 0xBC, 0x2, + 0x48, 0x8E, 0xD4, 0x1A, 0x60, 0xA6, 0xEC, 0x32, 0x78, 0xBE, + 0x4, 0x4A, 0x90, 0xD6, 0x1C, 0x62, 0xDA, 0x52, 0xCA, 0x42, + 0xBA, 0x32, 0xAA, 0x22, 0x9A, 0x12, 0x8A, 0x2, 0x7A, 0xF2, + 0x6A, 0xE2, 0x5A, 0xD2, 0x4A, 0xC2, 0x3A, 0xB2, 0x2A, 0xA2, + 0x1A, 0x92, 0xA, 0x82, 0xFA, 0x72, 0xEA, 0x62, 0xDA, 0x52, + 0xCA, 0x42, 0xBA, 0x32, 0xAA, 0x22, 0x9A, 0x12, 0x8A, 0x2, + 0x7A, 0xF2, 0x6A, 0xE2 + }, +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[AGAIN_MAX_IDX]) { + *pu32AgainLin = Again_table[AGAIN_MAX_IDX]; + *pu32AgainDb = AGAIN_MAX_IDX; + return CVI_SUCCESS; + } + + for (i = 1; i < AGAIN_MAX_IDX + 1; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[DGAIN_MAX_IDX]) { + *pu32DgainLin = Dgain_table[DGAIN_MAX_IDX]; + *pu32DgainDb = DGAIN_MAX_IDX; + return CVI_SUCCESS; + } + + for (i = 1; i < DGAIN_MAX_IDX + 1; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again, regAgain; + CVI_U32 u32Dgain; + struct again_tbl_info_s *again_info; + + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + again_info = &AgainInfo; + regAgain = again_info->regGainFineBase - u32Again; + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_ADDR].u32Data = (regAgain & 0xFF); + if (regAgain <= 0x4f) + pstSnsRegsInfo->astI2cData[LINEAR_CLAMP_MODE].u32Data = 0x02; + else + pstSnsRegsInfo->astI2cData[LINEAR_CLAMP_MODE].u32Data = 0x00; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H_ADDR].u32Data = (DgainInfo.regH[u32Dgain] & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L_ADDR].u32Data = (DgainInfo.regL[u32Dgain] & 0xFF); + } else { + if (g_au16BG0808_GainMode[ViPipe] == SNS_GAIN_MODE_WDR_2F) { + //SEF Again + again_info = &AgainInfo; + regAgain = again_info->regGainFineBase - u32Again; + pstSnsRegsInfo->astI2cData[WDR_SAGAIN_ADDR].u32Data = (regAgain & 0xFF); + if (regAgain <= 0x4f) + pstSnsRegsInfo->astI2cData[WDR_CLAMP_MODE].u32Data = 0x02; + else + pstSnsRegsInfo->astI2cData[WDR_CLAMP_MODE].u32Data = 0x00; + //SEF Dgain + pstSnsRegsInfo->astI2cData[WDR_SDGAIN_H_ADDR].u32Data = (DgainInfo.regH[u32Dgain] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_SDGAIN_L_ADDR].u32Data = (DgainInfo.regL[u32Dgain] & 0xFF); + + //LEF Again + u32Again = pu32Again[1]; + again_info = &AgainInfo; + regAgain = again_info->regGainFineBase - u32Again; + pstSnsRegsInfo->astI2cData[WDR_AGAIN_ADDR].u32Data = (regAgain & 0xFF); + if (regAgain <= 0x4f) + pstSnsRegsInfo->astI2cData[WDR_CLAMP_MODE].u32Data = 0x02; + else + pstSnsRegsInfo->astI2cData[WDR_CLAMP_MODE].u32Data = 0x00; + //LEF Dgain + u32Dgain = pu32Dgain[1]; + pstSnsRegsInfo->astI2cData[WDR_DGAIN_H_ADDR].u32Data = (DgainInfo.regH[u32Dgain] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_DGAIN_L_ADDR].u32Data = (DgainInfo.regL[u32Dgain] & 0xFF); + } else if (g_au16BG0808_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + //SEF Again + again_info = &AgainInfo; + regAgain = again_info->regGainFineBase - u32Again; + pstSnsRegsInfo->astI2cData[WDR_SAGAIN_ADDR].u32Data = (regAgain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_AGAIN_ADDR].u32Data = (regAgain & 0xFF); + if (regAgain <= 0x4f) + pstSnsRegsInfo->astI2cData[WDR_CLAMP_MODE].u32Data = 0x02; + else + pstSnsRegsInfo->astI2cData[WDR_CLAMP_MODE].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[WDR_SDGAIN_H_ADDR].u32Data = (DgainInfo.regH[u32Dgain] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_SDGAIN_L_ADDR].u32Data = (DgainInfo.regL[u32Dgain] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_DGAIN_H_ADDR].u32Data = (DgainInfo.regH[u32Dgain] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_DGAIN_L_ADDR].u32Data = (DgainInfo.regL[u32Dgain] & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = 1; + /* + * Long exp + Short exp < VTS + */ + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 1 - g_astBG0808_mode[pstSnsState->u8ImgMode].u32IspResTime - + pstSnsState->au32WDRIntTime[0]) * 0x40) / DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 1 - g_astBG0808_mode[pstSnsState->u8ImgMode].u32IspResTime) + * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? u32ShortTimeMinLimit : u32IntTimeMaxTmp; + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio is too large!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + CVI_TRACE_SNS(CVI_DBG_DEBUG, "sexp[%d, %d], lexp[%d, %d], ratio:%d\n", + au32IntTimeMin[0], au32IntTimeMax[0], au32IntTimeMin[1], au32IntTimeMax[1], au32Ratio[0]); + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + //memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + //&g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const BG0808_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astBG0808_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = BG0808_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astBG0808_mode[pstSnsState->u8ImgMode].u32VtsDef; + CVI_TRACE_SNS(CVI_DBG_DEBUG, "linear mode\n"); + break; + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == BG0808_MODE_1920X1080P30) + pstSnsState->u8ImgMode = BG0808_MODE_1920X1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astBG0808_mode[pstSnsState->u8ImgMode].u32VtsDef; + CVI_TRACE_SNS(CVI_DBG_DEBUG, "2to1 line WDR 1080p mode(60fps->30fps)\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunBG0808_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = bg0808_i2c_addr; + pstI2c_data[i].u32AddrByteNum = bg0808_addr_byte; + pstI2c_data[i].u32DataByteNum = bg0808_data_byte; + } + + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = BG0808_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = BG0808_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = BG0808_AGAIN_ADDR; + pstI2c_data[LINEAR_CLAMP_MODE].u32RegAddr = BG0808_CLAMP_MODE_ADDR; + pstI2c_data[LINEAR_CLAMP_MODE].u32Data = 0x00; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = BG0808_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = BG0808_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = BG0808_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = BG0808_VMAX_L_ADDR; + pstI2c_data[LINEAR_SHADOW_ADDR].u32RegAddr = BG0808_SHADOW_ADDR; + pstI2c_data[LINEAR_SHADOW_ADDR].u32Data = 0x02; + break; + case WDR_MODE_2To1_LINE: + pstI2c_data[WDR_EXP_H_ADDR].u32RegAddr = BG0808_EXP_H_ADDR; + pstI2c_data[WDR_EXP_L_ADDR].u32RegAddr = BG0808_EXP_L_ADDR; + pstI2c_data[WDR_SEXP_H_ADDR].u32RegAddr = BG0808_SEXP_H_ADDR; + pstI2c_data[WDR_SEXP_L_ADDR].u32RegAddr = BG0808_SEXP_L_ADDR; + pstI2c_data[WDR_AGAIN_ADDR].u32RegAddr = BG0808_AGAIN_ADDR; + pstI2c_data[WDR_SAGAIN_ADDR].u32RegAddr = BG0808_SAGAIN_ADDR; + pstI2c_data[WDR_CLAMP_MODE].u32RegAddr = BG0808_CLAMP_MODE_ADDR; + pstI2c_data[WDR_CLAMP_MODE].u32Data = 0x00; + pstI2c_data[WDR_DGAIN_H_ADDR].u32RegAddr = BG0808_DGAIN_H_ADDR; + pstI2c_data[WDR_DGAIN_L_ADDR].u32RegAddr = BG0808_DGAIN_L_ADDR; + pstI2c_data[WDR_SDGAIN_H_ADDR].u32RegAddr = BG0808_SDGAIN_H_ADDR; + pstI2c_data[WDR_SDGAIN_L_ADDR].u32RegAddr = BG0808_SDGAIN_L_ADDR; + pstI2c_data[WDR_VMAX_H_ADDR].u32RegAddr = BG0808_VMAX_H_ADDR; + pstI2c_data[WDR_VMAX_L_ADDR].u32RegAddr = BG0808_VMAX_L_ADDR; + pstI2c_data[WDR_SHADOW_ADDR].u32RegAddr = BG0808_SHADOW_ADDR; + pstI2c_data[WDR_SHADOW_ADDR].u32Data = 0x02; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.need_update = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + } + } + pstCfg0->snsCfg.astI2cData[pstCfg0->snsCfg.u32RegNum - 1].u32Data = 0x02; + pstCfg0->snsCfg.astI2cData[pstCfg0->snsCfg.u32RegNum - 1].bUpdate = CVI_TRUE; + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (BG0808_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = BG0808_MODE_1920X1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (BG0808_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = BG0808_MODE_1920X1080P30_WDR; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeBg0808_MirrorFip[ViPipe] != eSnsMirrorFlip) { + bg0808_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeBg0808_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const BG0808_MODE_S *pstMode = CVI_NULL; + + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = BG0808_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astBG0808_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &bg0808_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astBG0808_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astBG0808_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstRxAttr->mclk.freq = CAMPLL_FREQ_27M; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &bg0808_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = bg0808_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = bg0808_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (BG0808_I2C_ADDR_IS_VALID(s32I2cAddr)) + bg0808_i2c_addr = s32I2cAddr; +} + +static CVI_S32 bg0808_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunBG0808_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + BG0808_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + BG0808_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + BG0808_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + BG0808_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = BG0808_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, BG0808_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, BG0808_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, BG0808_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16BG0808_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16BG0808_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsBG0808_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = bg0808_standby, + .pfnRestart = bg0808_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = bg0808_write_register, + .pfnReadReg = bg0808_read_register, + .pfnSetBusInfo = bg0808_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = bg0808_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/brigates_bg0808/bg0808_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/brigates_bg0808/bg0808_cmos_ex.h new file mode 100644 index 000000000..320272034 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/brigates_bg0808/bg0808_cmos_ex.h @@ -0,0 +1,99 @@ +#ifndef __BG0808_CMOS_EX_H_ +#define __BG0808_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum bg0808_linear_regs_e { + LINEAR_EXP_H_ADDR,//0x0c + LINEAR_EXP_L_ADDR,//0x0d + LINEAR_AGAIN_ADDR,//0x00a2 + LINEAR_CLAMP_MODE,//0x73 need change when again changed + LINEAR_DGAIN_H_ADDR,//0x00c0 + LINEAR_DGAIN_L_ADDR,//0x00c1 + LINEAR_VMAX_H_ADDR,//0x0010 + LINEAR_VMAX_L_ADDR,//0x0011 + LINEAR_SHADOW_ADDR,//0x001d + LINEAR_REGS_NUM +}; +enum bg0808_wdr_regs_e { + WDR_EXP_H_ADDR, + WDR_EXP_L_ADDR, + WDR_SEXP_H_ADDR,//0x22 + WDR_SEXP_L_ADDR,//0x23 + WDR_AGAIN_ADDR,//0x00a2 + WDR_SAGAIN_ADDR,//0x00a4 + WDR_CLAMP_MODE,//0x73 need change when again changed + WDR_DGAIN_H_ADDR, + WDR_DGAIN_L_ADDR, + WDR_SDGAIN_H_ADDR,//0x00c2 + WDR_SDGAIN_L_ADDR,//0x00c3 + WDR_VMAX_H_ADDR, + WDR_VMAX_L_ADDR, + WDR_SHADOW_ADDR, + WDR_REGS_NUM +}; + +typedef enum _BG0808_MODE_E { + BG0808_MODE_1920X1080P30 = 0, + BG0808_MODE_LINEAR_NUM, + BG0808_MODE_1920X1080P30_WDR = BG0808_MODE_LINEAR_NUM, + BG0808_MODE_NUM +} BG0808_MODE_E; + +typedef struct _BG0808_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + CVI_U32 u32IspResTime; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} BG0808_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastBG0808[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunBG0808_BusInfo[]; +extern CVI_U16 g_au16BG0808_GainMode[]; +extern CVI_U16 g_au16BG0808_L2SMode[]; +extern CVI_U8 bg0808_i2c_addr; +extern const CVI_U32 bg0808_addr_byte; +extern const CVI_U32 bg0808_data_byte; +extern void bg0808_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void bg0808_init(VI_PIPE ViPipe); +extern void bg0808_exit(VI_PIPE ViPipe); +extern void bg0808_standby(VI_PIPE ViPipe); +extern void bg0808_restart(VI_PIPE ViPipe); +extern int bg0808_write_register(VI_PIPE ViPipe, int addr, int data); +extern int bg0808_read_register(VI_PIPE ViPipe, int addr); +extern int bg0808_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __BG0808_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/brigates_bg0808/bg0808_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/brigates_bg0808/bg0808_cmos_param.h new file mode 100644 index 000000000..556578ce7 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/brigates_bg0808/bg0808_cmos_param.h @@ -0,0 +1,220 @@ +#ifndef __BG0808_CMOS_PARAM_H_ +#define __BG0808_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "bg0808_cmos_ex.h" + +static const BG0808_MODE_S g_astBG0808_mode[BG0808_MODE_NUM] = { + [BG0808_MODE_1920X1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1920, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.52, /* 1125(0x465) * 30 / 0xFFFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1124,//vts - 1 + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 5120, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16324, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [BG0808_MODE_1920X1080P30_WDR] = { + .name = "1080p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.52, /* 1125(0x465) * 30 / 0xFFFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp[0] = {//sexp + .u16Min = 1, + .u16Max = 1124,//vts - 1 + .u16Def = 400, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 1124,//vts - 1 + .u16Def = 400, + .u16Step = 1, + }, + .u32IspResTime = 34, /* ceil((u32Vts * f32MaxFps) / 1000); about 1ms*/ + .stAgain[0] = {//sagain + .u32Min = 1024, + .u32Max = 5120, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 5120, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = {//sagain + .u32Min = 1024, + .u32Max = 16324, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 16324, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + #if 0 + .stManual = {0, 0, 0, 0, 0, 0, 0, 0, 1024, 1024, 1024, 1024}, + .stAuto = { + {0, 0, 0, 0, 0, 0, 0, 0, /*8*/0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, /*8*/0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, /*8*/0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, /*8*/0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + /*8*/1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024}, + {1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + /*8*/1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024}, + {1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + /*8*/1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024}, + {1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + /*8*/1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024}, + }, + #endif + #if 1 //use test result as blc offset + .stManual = {28, 28, 28, 28, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1031, 1031, 1031, 1031 +#endif + }, + .stAuto = { + {28, 28, 28, 28, 28, 28, 28, 28, /*8*/28, 28, 28, 28, 28, 28, 28, 28}, + {28, 28, 28, 28, 28, 28, 28, 28, /*8*/28, 28, 28, 28, 28, 28, 28, 28}, + {28, 28, 28, 28, 28, 28, 28, 28, /*8*/28, 28, 28, 28, 28, 28, 28, 28}, + {28, 28, 28, 28, 28, 28, 28, 28, /*8*/28, 28, 28, 28, 28, 28, 28, 28}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, + /*8*/1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031}, + {1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, + /*8*/1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031}, + {1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, + /*8*/1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031}, + {1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, + /*8*/1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031}, +#endif + }, + #endif + }, +}; + +struct combo_dev_attr_s bg0808_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 0, 1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __BG0808_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/brigates_bg0808/bg0808_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/brigates_bg0808/bg0808_sensor_ctl.c new file mode 100644 index 000000000..00e23cd18 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/brigates_bg0808/bg0808_sensor_ctl.c @@ -0,0 +1,445 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "bg0808_cmos_ex.h" + +#define BG0808_CHIP_ID_HI_ADDR 0x0000 +#define BG0808_CHIP_ID_LO_ADDR 0x0001 +#define BG0808_CHIP_ID 0x0808 +static void bg0808_linear_1080P30_init(VI_PIPE ViPipe); +static void bg0808_wdr_1080P30_2to1_init(VI_PIPE ViPipe); +CVI_U8 bg0808_i2c_addr = 0x32; /* I2C Address of BG0808 */ +const CVI_U32 bg0808_addr_byte = 2; +const CVI_U32 bg0808_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int bg0808_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunBG0808_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, bg0808_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int bg0808_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +int bg0808_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (bg0808_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, bg0808_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, bg0808_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (bg0808_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int bg0808_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (bg0808_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (bg0808_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, bg0808_addr_byte + bg0808_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + + return CVI_SUCCESS; +} + +void bg0808_standby(VI_PIPE ViPipe) +{ + (void) ViPipe; + CVI_TRACE_SNS(CVI_DBG_NOTICE, "unsupport standby.\n"); +} + +void bg0808_restart(VI_PIPE ViPipe) +{ + (void) ViPipe; + CVI_TRACE_SNS(CVI_DBG_NOTICE, "unsupport restart.\n"); +} + +void bg0808_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastBG0808[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastBG0808[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + bg0808_write_register(ViPipe, + g_pastBG0808[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastBG0808[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void bg0808_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + bg0808_write_register(ViPipe, 0x0020, val); + bg0808_write_register(ViPipe, 0x001d, 0x02); +} + +int bg0808_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + delay_ms(4); + if (bg0808_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = bg0808_read_register(ViPipe, BG0808_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = bg0808_read_register(ViPipe, BG0808_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != BG0808_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void bg0808_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastBG0808[ViPipe]->enWDRMode; + u8ImgMode = g_pastBG0808[ViPipe]->u8ImgMode; + + if (g_fd[ViPipe] < 0) + bg0808_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == BG0808_MODE_1920X1080P30_WDR) { + bg0808_wdr_1080P30_2to1_init(ViPipe); + } else { + } + } else { + bg0808_linear_1080P30_init(ViPipe); + } + + g_pastBG0808[ViPipe]->bInit = CVI_TRUE; +} + +void bg0808_exit(VI_PIPE ViPipe) +{ + bg0808_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void bg0808_linear_1080P30_init(VI_PIPE ViPipe) +{ + delay_ms(20); + bg0808_write_register(ViPipe, 0x00b1, 0x55); + bg0808_write_register(ViPipe, 0x00cc, 0x07); + bg0808_write_register(ViPipe, 0x00e4, 0x14); + bg0808_write_register(ViPipe, 0x00fa, 0x7f); + bg0808_write_register(ViPipe, 0x0391, 0x84); + bg0808_write_register(ViPipe, 0x0390, 0x06); + bg0808_write_register(ViPipe, 0x0398, 0x15); + + bg0808_write_register(ViPipe, 0x03b2, 0x00);//hs trail, default 0x3c + bg0808_write_register(ViPipe, 0x03b3, 0x78); + + bg0808_write_register(ViPipe, 0x03c3, 0x10); + bg0808_write_register(ViPipe, 0x0392, 0x00); + bg0808_write_register(ViPipe, 0x0045, 0x01); + bg0808_write_register(ViPipe, 0x0046, 0x03); + bg0808_write_register(ViPipe, 0x0074, 0x00); + bg0808_write_register(ViPipe, 0x0075, 0x04); + bg0808_write_register(ViPipe, 0x00ae, 0x0a); + bg0808_write_register(ViPipe, 0x00d0, 0x02); + bg0808_write_register(ViPipe, 0x00b2, 0x05); + bg0808_write_register(ViPipe, 0x0120, 0x01); + bg0808_write_register(ViPipe, 0x01a5, 0x07); + bg0808_write_register(ViPipe, 0x007c, 0x04); + bg0808_write_register(ViPipe, 0x00a8, 0x0f); + bg0808_write_register(ViPipe, 0x0030, 0x30); + bg0808_write_register(ViPipe, 0x0032, 0x01); + bg0808_write_register(ViPipe, 0x0033, 0xed); + bg0808_write_register(ViPipe, 0x0034, 0x1e); + bg0808_write_register(ViPipe, 0x002c, 0x00); + bg0808_write_register(ViPipe, 0x002d, 0x2b); + bg0808_write_register(ViPipe, 0x002e, 0x02); + bg0808_write_register(ViPipe, 0x000e, 0x08); + bg0808_write_register(ViPipe, 0x000f, 0x98); + bg0808_write_register(ViPipe, 0x0010, 0x04); + bg0808_write_register(ViPipe, 0x0011, 0x65); + bg0808_write_register(ViPipe, 0x0070, 0x00); + bg0808_write_register(ViPipe, 0x0071, 0x01); + bg0808_write_register(ViPipe, 0x0069, 0x01); + bg0808_write_register(ViPipe, 0x004b, 0x02); + bg0808_write_register(ViPipe, 0x004c, 0x02); + bg0808_write_register(ViPipe, 0x0049, 0x00); + bg0808_write_register(ViPipe, 0x004a, 0x08); + bg0808_write_register(ViPipe, 0x004d, 0x0b); + bg0808_write_register(ViPipe, 0x004e, 0x01); + bg0808_write_register(ViPipe, 0x004f, 0x00); + bg0808_write_register(ViPipe, 0x0050, 0x2a); + bg0808_write_register(ViPipe, 0x0051, 0x00); + bg0808_write_register(ViPipe, 0x0052, 0x4a); + bg0808_write_register(ViPipe, 0x0055, 0x04); + bg0808_write_register(ViPipe, 0x0056, 0x00); + bg0808_write_register(ViPipe, 0x0057, 0x1e); + bg0808_write_register(ViPipe, 0x0084, 0x00); + bg0808_write_register(ViPipe, 0x0085, 0xb9); + bg0808_write_register(ViPipe, 0x0058, 0x02); + bg0808_write_register(ViPipe, 0x005a, 0x00); + bg0808_write_register(ViPipe, 0x005b, 0x4a); + bg0808_write_register(ViPipe, 0x005c, 0x00); + bg0808_write_register(ViPipe, 0x005d, 0x4a); + bg0808_write_register(ViPipe, 0x0086, 0x01); + bg0808_write_register(ViPipe, 0x0087, 0xda); + bg0808_write_register(ViPipe, 0x0088, 0x02); + bg0808_write_register(ViPipe, 0x006f, 0x02); + bg0808_write_register(ViPipe, 0x005e, 0x01); + bg0808_write_register(ViPipe, 0x0043, 0x02); + bg0808_write_register(ViPipe, 0x0044, 0x02); + bg0808_write_register(ViPipe, 0x0039, 0x00); + bg0808_write_register(ViPipe, 0x003a, 0xa0); + bg0808_write_register(ViPipe, 0x0037, 0x00); + bg0808_write_register(ViPipe, 0x0038, 0x80); + bg0808_write_register(ViPipe, 0x006d, 0x0d); + bg0808_write_register(ViPipe, 0x0064, 0x15); + bg0808_write_register(ViPipe, 0x00a1, 0x0c); + bg0808_write_register(ViPipe, 0x00aa, 0x0c); + bg0808_write_register(ViPipe, 0x00bc, 0x02); + bg0808_write_register(ViPipe, 0x0046, 0x00); + //blc + bg0808_write_register(ViPipe, 0x0130, 0x00);// blc, default 0x18 + bg0808_write_register(ViPipe, 0x0131, 0x18); + bg0808_write_register(ViPipe, 0x001d, 0x01); + + bg0808_default_reg_init(ViPipe); + delay_ms(20); + + printf("ViPipe:%d,===BG0808 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} +static void bg0808_wdr_1080P30_2to1_init(VI_PIPE ViPipe) +{ + delay_ms(20); + bg0808_write_register(ViPipe, 0x00b1, 0x55); + bg0808_write_register(ViPipe, 0x00cc, 0x07); + bg0808_write_register(ViPipe, 0x00e4, 0x14); + bg0808_write_register(ViPipe, 0x00fa, 0x7f); + bg0808_write_register(ViPipe, 0x0391, 0x84); + bg0808_write_register(ViPipe, 0x0390, 0x06); + bg0808_write_register(ViPipe, 0x03c3, 0x10); + bg0808_write_register(ViPipe, 0x0392, 0x00); + + bg0808_write_register(ViPipe, 0x03b2, 0x00);//hs trail, default 0x3c + bg0808_write_register(ViPipe, 0x03b3, 0x78); + + bg0808_write_register(ViPipe, 0x0045, 0x01); + bg0808_write_register(ViPipe, 0x0046, 0x03); + bg0808_write_register(ViPipe, 0x0074, 0x00); + bg0808_write_register(ViPipe, 0x0075, 0x04); + bg0808_write_register(ViPipe, 0x00ae, 0x0a); + bg0808_write_register(ViPipe, 0x00d0, 0x02); + bg0808_write_register(ViPipe, 0x00b2, 0x05); + bg0808_write_register(ViPipe, 0x0120, 0x01); + bg0808_write_register(ViPipe, 0x01a5, 0x07); + bg0808_write_register(ViPipe, 0x007c, 0x04); + bg0808_write_register(ViPipe, 0x00a8, 0x0f); + bg0808_write_register(ViPipe, 0x0032, 0x00); + bg0808_write_register(ViPipe, 0x0033, 0x35); + bg0808_write_register(ViPipe, 0x0034, 0x00); + bg0808_write_register(ViPipe, 0x002c, 0x00); + bg0808_write_register(ViPipe, 0x002d, 0x13); + bg0808_write_register(ViPipe, 0x002e, 0x00); + bg0808_write_register(ViPipe, 0x000e, 0x11); + bg0808_write_register(ViPipe, 0x000f, 0x30); + bg0808_write_register(ViPipe, 0x0010, 0x04); + bg0808_write_register(ViPipe, 0x0011, 0x65); + bg0808_write_register(ViPipe, 0x0070, 0x00); + bg0808_write_register(ViPipe, 0x0071, 0x01); + bg0808_write_register(ViPipe, 0x0069, 0x01); + bg0808_write_register(ViPipe, 0x004b, 0x04); + bg0808_write_register(ViPipe, 0x004c, 0x04); + bg0808_write_register(ViPipe, 0x0049, 0x00); + bg0808_write_register(ViPipe, 0x004a, 0x0f); + bg0808_write_register(ViPipe, 0x004d, 0x14); + bg0808_write_register(ViPipe, 0x004e, 0x01); + bg0808_write_register(ViPipe, 0x004f, 0x00); + bg0808_write_register(ViPipe, 0x0050, 0x53); + bg0808_write_register(ViPipe, 0x0051, 0x00); + bg0808_write_register(ViPipe, 0x0052, 0x93); + bg0808_write_register(ViPipe, 0x0055, 0x08); + bg0808_write_register(ViPipe, 0x0056, 0x00); + bg0808_write_register(ViPipe, 0x0057, 0x3b); + bg0808_write_register(ViPipe, 0x0084, 0x01); + bg0808_write_register(ViPipe, 0x0085, 0x72); + bg0808_write_register(ViPipe, 0x0058, 0x04); + bg0808_write_register(ViPipe, 0x005a, 0x00); + bg0808_write_register(ViPipe, 0x005b, 0x93); + bg0808_write_register(ViPipe, 0x005c, 0x00); + bg0808_write_register(ViPipe, 0x005d, 0x93); + bg0808_write_register(ViPipe, 0x0086, 0x03); + bg0808_write_register(ViPipe, 0x0087, 0x8e); + bg0808_write_register(ViPipe, 0x0088, 0x04); + bg0808_write_register(ViPipe, 0x006f, 0x04); + bg0808_write_register(ViPipe, 0x005e, 0x01); + bg0808_write_register(ViPipe, 0x0043, 0x04); + bg0808_write_register(ViPipe, 0x0044, 0x04); + bg0808_write_register(ViPipe, 0x0039, 0x01); + bg0808_write_register(ViPipe, 0x003a, 0x40); + bg0808_write_register(ViPipe, 0x0037, 0x01); + bg0808_write_register(ViPipe, 0x0038, 0x00); + bg0808_write_register(ViPipe, 0x006d, 0x0e); + bg0808_write_register(ViPipe, 0x0064, 0x16); + bg0808_write_register(ViPipe, 0x0021, 0x01); + bg0808_write_register(ViPipe, 0x0041, 0x01); + bg0808_write_register(ViPipe, 0x0042, 0x40); + bg0808_write_register(ViPipe, 0x003f, 0x01); + bg0808_write_register(ViPipe, 0x0040, 0x00); + bg0808_write_register(ViPipe, 0x0098, 0x00); + bg0808_write_register(ViPipe, 0x0099, 0x88); + bg0808_write_register(ViPipe, 0x009a, 0x01); + bg0808_write_register(ViPipe, 0x009b, 0x88); + bg0808_write_register(ViPipe, 0x009c, 0x01); + bg0808_write_register(ViPipe, 0x009d, 0x72); + bg0808_write_register(ViPipe, 0x009e, 0x03); + bg0808_write_register(ViPipe, 0x009f, 0x8e); + bg0808_write_register(ViPipe, 0x00a1, 0x0c); + bg0808_write_register(ViPipe, 0x00a3, 0x0c); + bg0808_write_register(ViPipe, 0x00aa, 0x0c); + bg0808_write_register(ViPipe, 0x00ab, 0x0c); + bg0808_write_register(ViPipe, 0x00bc, 0x02); + bg0808_write_register(ViPipe, 0x0046, 0x00); + //blc + bg0808_write_register(ViPipe, 0x0130, 0x00);// blc, default 0x18 + bg0808_write_register(ViPipe, 0x0131, 0x18); + bg0808_write_register(ViPipe, 0x001d, 0x01); + + bg0808_default_reg_init(ViPipe); + delay_ms(20); + + printf("ViPipe:%d,===BG0808 1080P 30fps 10bit WDR2TO1 Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc02m1/Makefile b/middleware/v2/component/isp/sensor/cv180x/gcore_gc02m1/Makefile new file mode 100644 index 000000000..33f4be44f --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc02m1/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc02m1.a +TARGET_SO = $(MW_LIB)/libsns_gc02m1.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc02m1/gc02m1_cmos.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc02m1/gc02m1_cmos.c new file mode 100644 index 000000000..3f2767e4b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc02m1/gc02m1_cmos.c @@ -0,0 +1,874 @@ +#include +#include +#include +#include +#include +#include +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" +#include "gc02m1_cmos_ex.h" +#include "gc02m1_cmos_param.h" +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#include "cvi_type.h" +#else +#include +#include +#include +#endif + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define GC02M1_ID 0x02e0 +#define GC02M1_I2C_ADDR_1 0x37 +#define GC02M1_I2C_ADDR_2 0x10 +#define GC02M1_I2C_ADDR_IS_VALID(addr) ((addr) == GC02M1_I2C_ADDR_1 || (addr) == GC02M1_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ***************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc02m1[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC02M1_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc02m1[dev]) +#define GC02M1_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc02m1[dev] = pstCtx) +#define GC02M1_SENSOR_RESET_CTX(dev) (g_pastGc02m1[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc02m1_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 3}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc02m1_MirrorFip[VI_MAX_PIPE_NUM] = {ISP_SNS_NORMAL}; + +CVI_U16 g_au16Gc02m1_GainMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ***************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Gc02m1 Lines Range*****/ +#define GC02M1_FULL_LINES_MAX (0x3fff) + +/*****Gc02m1 Register Address*****/ +#define GC02M1_PAGE_0_ADDR 0xfe +#define GC02M1_EXP_H_ADDR 0x03 //bit[13:8] +#define GC02M1_EXP_L_ADDR 0x04 + +#define GC02M1_AGAIN_ADDR 0xb6 //bit[4:0] + +#define GC02M1_VTS_H_ADDR 0x41 //bit[13:8] +#define GC02M1_VTS_L_ADDR 0x42 + +#define GC02M1_MIRROR_FLIP_ADDR 0x17 + +#define GC02M1_RES_IS_1200P(w, h) ((w) <= 1600 && (h) <= 1200) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC02M1_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astGc02m1_mode[GC02M1_MODE_1600X1200P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astGc02m1_mode[GC02M1_MODE_1600X1200P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 60880; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 1024; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? + g_au32InitExposure[ViPipe] : g_astGc02m1_mode[GC02M1_MODE_1600X1200P30].stExp[0].u16Def; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstAeSnsDft->u32MinIntTime = g_astGc02m1_mode[GC02M1_MODE_1600X1200P30].stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astGc02m1_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astGc02m1_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astGc02m1_mode[pstSnsState->u8ImgMode].f32MinFps; + + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + + u32VMAX = (u32VMAX > GC02M1_FULL_LINES_MAX) ? GC02M1_FULL_LINES_MAX : u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = ((u32IntTime[0] >> 8) & 0x3F); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_U32 regValTable[] = { + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, +}; + +static CVI_U32 gain_table[] = { + 16 * 64, + 16 * 96, + 16 * 127, + 16 * 157, + 16 * 197, + 16 * 226, + 16 * 259, + 16 * 287, + 16 * 318, + 16 * 356, + 16 * 391, + 16 * 419, + 16 * 450, + 16 * 480, + 16 * 513, + 16 * 646, +}; + + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + int total = ARRAY_SIZE(gain_table); + + if (*pu32AgainLin >= gain_table[total - 1]) { + *pu32AgainDb = total - 1; + *pu32AgainLin = gain_table[total - 1]; + return CVI_SUCCESS; + } + + for (i = 0; i < total; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainDb = i - 1; + break; + } + } + *pu32AgainLin = gain_table[i - 1]; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + UNUSED(ViPipe); + + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + /* only surpport linear mode */ + u32Again = pu32Again[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN].u32Data = regValTable[u32Again]; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + UNUSED(ViPipe); + UNUSED(u16ManRatioEnable); + UNUSED(au32Ratio); + UNUSED(au32IntTimeMax); + UNUSED(au32IntTimeMin); + UNUSED(pu32LFMaxIntTime); + + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode\n"); + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + UNUSED(ViPipe); + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + UNUSED(ViPipe); + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + CMOS_CHECK_POINTER(pstBlc); + UNUSED(ViPipe); + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC02M1_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astGc02m1_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + UNUSED(ViPipe); + UNUSED(u8Mode); + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunGc02m1_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = gc02m1_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc02m1_addr_byte; + pstI2c_data[i].u32DataByteNum = gc02m1_data_byte; + } + + pstI2c_data[LINEAR_PAGE_0].u32RegAddr = GC02M1_PAGE_0_ADDR; + pstI2c_data[LINEAR_PAGE_0].u32Data = 0; + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC02M1_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC02M1_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN].u32RegAddr = GC02M1_AGAIN_ADDR; + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC02M1_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC02M1_VTS_L_ADDR; + pstI2c_data[LINEAR_MIRROR_FLIP].u32RegAddr = GC02M1_MIRROR_FLIP_ADDR; + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + + CVI_U32 gainsUpdate = 0, shutterUpdate = 0, vtsUpdate = 0; + + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + if (i == LINEAR_AGAIN) + gainsUpdate = 1; + + if (i <= LINEAR_EXP_L && i >= LINEAR_EXP_H) + shutterUpdate = 1; + + if ((i >= LINEAR_VTS_H) && (i <= LINEAR_VTS_L)) + vtsUpdate = 1; + + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (gainsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN].bUpdate = CVI_TRUE; + } + if (shutterUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_L].bUpdate = CVI_TRUE; + } + if (vtsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_VTS_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_VTS_L].bUpdate = CVI_TRUE; + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC02M1_RES_IS_1200P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC02M1_MODE_1600X1200P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U8 value; + + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc02m1_MirrorFip[ViPipe] != eSnsMirrorFlip) { + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + value = 0; + break; + case ISP_SNS_MIRROR: + value = 0x01; + break; + case ISP_SNS_FLIP: + value = 0x02; + break; + case ISP_SNS_MIRROR_FLIP: + value = 0x03; + break; + default: + return; + } + + pstSnsRegsInfo->astI2cData[LINEAR_MIRROR_FLIP].u32Data = value; + + g_aeGc02m1_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC02M1_MODE_1600X1200P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astGc02m1_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astGc02m1_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astGc02m1_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc02m1_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astGc02m1_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astGc02m1_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc02m1_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc02m1_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc02m1_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (GC02M1_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc02m1_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc02m1_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc02m1_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC02M1_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC02M1_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC02M1_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC02M1_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC02M1_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC02M1_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC02M1_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC02M1_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Gc02m1_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc02m1_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc02m1_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc02m1_standby, + .pfnRestart = gc02m1_restart, + .pfnWriteReg = gc02m1_write_register, + .pfnReadReg = gc02m1_read_register, + .pfnSetBusInfo = gc02m1_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc02m1/gc02m1_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc02m1/gc02m1_cmos_ex.h new file mode 100644 index 000000000..62ca1b906 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc02m1/gc02m1_cmos_ex.h @@ -0,0 +1,85 @@ +#ifndef __GC02M1_CMOS_EX_H_ +#define __GC02M1_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum gc02m1_linear_regs_e { + LINEAR_PAGE_0, + LINEAR_EXP_H, + LINEAR_EXP_L, + LINEAR_AGAIN, + LINEAR_VTS_H, + LINEAR_VTS_L, + LINEAR_MIRROR_FLIP, + + LINEAR_REGS_NUM +}; + +typedef enum _GC02M1_MODE_E { + GC02M1_MODE_1600X1200P30 = 0, + GC02M1_MODE_LINEAR_NUM, + GC02M1_MODE_NUM +} GC02M1_MODE_E; + +typedef struct _GC02M1_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC02M1_STATE_S; + +typedef struct _GC02M1_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} GC02M1_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc02m1[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc02m1_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc02m1_MirrorFip[VI_MAX_PIPE_NUM]; +extern CVI_U8 gc02m1_i2c_addr; +extern const CVI_U32 gc02m1_addr_byte; +extern const CVI_U32 gc02m1_data_byte; +extern void gc02m1_init(VI_PIPE ViPipe); +extern void gc02m1_exit(VI_PIPE ViPipe); +extern void gc02m1_standby(VI_PIPE ViPipe); +extern void gc02m1_restart(VI_PIPE ViPipe); +extern int gc02m1_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc02m1_read_register(VI_PIPE ViPipe, int addr); +extern int gc02m1_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC02M1_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc02m1/gc02m1_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc02m1/gc02m1_cmos_param.h new file mode 100644 index 000000000..24c74f4d8 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc02m1/gc02m1_cmos_param.h @@ -0,0 +1,123 @@ +#ifndef __GC02M1_CMOS_PARAM_H_ +#define __GC02M1_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif + +#include "cvi_sns_ctrl.h" +#include "gc02m1_cmos_ex.h" + +static const GC02M1_MODE_S g_astGc02m1_mode[GC02M1_MODE_NUM] = { + [GC02M1_MODE_1600X1200P30] = { + .name = "1600X1200P30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1600, + .u32Height = 1200, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1600, + .u32Height = 1200, + }, + .stMaxSize = { + .u32Width = 1600, + .u32Height = 1200, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.32, /* 1268 * 30 / 0x3FFF */ + .u32HtsDef = 1774, + .u32VtsDef = 1268, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1268 - 8, + .u16Def = 100, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 16 * 646, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 1024, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256 }, + {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256 }, + {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256 }, + {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + 1092, 1092}, +#endif + }, + }, +}; + +struct combo_dev_attr_s gc02m1_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {0, 1, -1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC02M1_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc02m1/gc02m1_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc02m1/gc02m1_sensor_ctl.c new file mode 100644 index 000000000..2b41380f4 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc02m1/gc02m1_sensor_ctl.c @@ -0,0 +1,475 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc02m1_cmos_ex.h" +#define GC02M1_CHIP_ID_ADDR_H 0xf0 +#define GC02M1_CHIP_ID_ADDR_L 0xf1 +#define GC02M1_CHIP_ID 0x02e0 + +#define GC02M1_MIRROR_NORMAL 1 +#define GC02M1_MIRROR_H 0 +#define GC02M1_MIRROR_V 0 +#define GC02M1_MIRROR_HV 0 + +#if GC02M1_MIRROR_NORMAL +#define GC02M1_MIRROR 0x80 +#elif GC02M1_MIRROR_H +#define GC02M1_MIRROR 0x81 +#elif GC02M1_MIRROR_V +#define GC02M1_MIRROR 0x82 +#elif GC02M1_MIRROR_HV +#define GC02M1_MIRROR 0x83 +#else +#define GC02M1_MIRROR 0x80 +#endif + +static void gc02m1_linear_1200p30_init(VI_PIPE ViPipe); + +CVI_U8 gc02m1_i2c_addr = 0x37; +const CVI_U32 gc02m1_addr_byte = 1; +const CVI_U32 gc02m1_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc02m1_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc02m1_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc02m1_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc02m1_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc02m1_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (gc02m1_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc02m1_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, gc02m1_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc02m1_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_INFO, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int gc02m1_write_register(VI_PIPE ViPipe, int addr, int data) +{ + int idx = 0; + int ret; + char buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc02m1_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + if (gc02m1_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc02m1_addr_byte + gc02m1_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + + ret = read(g_fd[ViPipe], buf, gc02m1_addr_byte + gc02m1_data_byte); + syslog(LOG_INFO, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void gc02m1_standby(VI_PIPE ViPipe) +{ + int nVal; + + gc02m1_write_register(ViPipe, 0xfe, 0x00); + + nVal = gc02m1_read_register(ViPipe, 0x3e); + nVal &= ~(0x1 << 7); + nVal &= ~(0x1 << 4); + gc02m1_write_register(ViPipe, 0x3e, nVal); + gc02m1_write_register(ViPipe, 0xfc, 0x01); + + nVal = gc02m1_read_register(ViPipe, 0xf9); + nVal |= (0x1 << 0); + gc02m1_write_register(ViPipe, 0xf9, nVal); + + printf("gc02m1 standby\n"); +} + +void gc02m1_restart(VI_PIPE ViPipe) +{ + int nVal; + + nVal = gc02m1_read_register(ViPipe, 0xf9); + nVal &= ~(0x1 << 0); + gc02m1_write_register(ViPipe, 0xf9, nVal); + + usleep(1); + gc02m1_write_register(ViPipe, 0xfc, 0x8e); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + nVal = gc02m1_read_register(ViPipe, 0x3e); + nVal |= (0x1 << 7); + nVal |= (0x1 << 4); + gc02m1_write_register(ViPipe, 0x3e, nVal); + + printf("gc02m1 restart\n"); +} + +void gc02m1_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc02m1[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc02m1_write_register(ViPipe, + g_pastGc02m1[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc02m1[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +int gc02m1_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc02m1_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc02m1_read_register(ViPipe, GC02M1_CHIP_ID_ADDR_H); + nVal2 = gc02m1_read_register(ViPipe, GC02M1_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC02M1_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc02m1_init(VI_PIPE ViPipe) +{ + gc02m1_i2c_init(ViPipe); + + gc02m1_linear_1200p30_init(ViPipe); + + g_pastGc02m1[ViPipe]->bInit = CVI_TRUE; +} + +void gc02m1_exit(VI_PIPE ViPipe) +{ + gc02m1_i2c_exit(ViPipe); +} + +static void gc02m1_linear_1200p30_init(VI_PIPE ViPipe) +{ + usleep(10 * 1000); + + /*system*/ + gc02m1_write_register(ViPipe, 0xfc, 0x01); + gc02m1_write_register(ViPipe, 0xf4, 0x41); + gc02m1_write_register(ViPipe, 0xf5, 0xc0); + gc02m1_write_register(ViPipe, 0xf6, 0x44); + gc02m1_write_register(ViPipe, 0xf8, 0x32); + gc02m1_write_register(ViPipe, 0xf9, 0x82); + gc02m1_write_register(ViPipe, 0xfa, 0x00); + gc02m1_write_register(ViPipe, 0xfd, 0x80); + gc02m1_write_register(ViPipe, 0xfc, 0x81); + gc02m1_write_register(ViPipe, 0xfe, 0x03); + gc02m1_write_register(ViPipe, 0x01, 0x0b); + gc02m1_write_register(ViPipe, 0xf7, 0x01); + gc02m1_write_register(ViPipe, 0xfc, 0x80); + gc02m1_write_register(ViPipe, 0xfc, 0x80); + gc02m1_write_register(ViPipe, 0xfc, 0x80); + gc02m1_write_register(ViPipe, 0xfc, 0x8e); + /*CISCTL*/ + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0x87, 0x09); + gc02m1_write_register(ViPipe, 0xee, 0x72); + gc02m1_write_register(ViPipe, 0xfe, 0x01); + gc02m1_write_register(ViPipe, 0x8c, 0x90); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0x90, 0x00); + gc02m1_write_register(ViPipe, 0x03, 0x04); + gc02m1_write_register(ViPipe, 0x04, 0x7d); + gc02m1_write_register(ViPipe, 0x41, 0x04); + gc02m1_write_register(ViPipe, 0x42, 0xf4); + gc02m1_write_register(ViPipe, 0x05, 0x04); + gc02m1_write_register(ViPipe, 0x06, 0x48); + gc02m1_write_register(ViPipe, 0x07, 0x00); + gc02m1_write_register(ViPipe, 0x08, 0x18); + gc02m1_write_register(ViPipe, 0x9d, 0x18); + gc02m1_write_register(ViPipe, 0x09, 0x00); + gc02m1_write_register(ViPipe, 0x0a, 0x02); + gc02m1_write_register(ViPipe, 0x0d, 0x04); + gc02m1_write_register(ViPipe, 0x0e, 0xbc); + gc02m1_write_register(ViPipe, 0x17, GC02M1_MIRROR); + gc02m1_write_register(ViPipe, 0x19, 0x04); + gc02m1_write_register(ViPipe, 0x24, 0x00); + gc02m1_write_register(ViPipe, 0x56, 0x20); + gc02m1_write_register(ViPipe, 0x5b, 0x00); + gc02m1_write_register(ViPipe, 0x5e, 0x01); + /*analog Register width*/ + gc02m1_write_register(ViPipe, 0x21, 0x3c); + gc02m1_write_register(ViPipe, 0x44, 0x20); + gc02m1_write_register(ViPipe, 0xcc, 0x01); + /*analog mode*/ + gc02m1_write_register(ViPipe, 0x1a, 0x04); + gc02m1_write_register(ViPipe, 0x1f, 0x11); + gc02m1_write_register(ViPipe, 0x27, 0x30); + gc02m1_write_register(ViPipe, 0x2b, 0x00); + gc02m1_write_register(ViPipe, 0x33, 0x00); + gc02m1_write_register(ViPipe, 0x53, 0x90); + gc02m1_write_register(ViPipe, 0xe6, 0x50); + /*analog voltage*/ + gc02m1_write_register(ViPipe, 0x39, 0x07); + gc02m1_write_register(ViPipe, 0x43, 0x04); + gc02m1_write_register(ViPipe, 0x46, 0x2a); + gc02m1_write_register(ViPipe, 0x7c, 0xa0); + gc02m1_write_register(ViPipe, 0xd0, 0xbe); + gc02m1_write_register(ViPipe, 0xd1, 0x60); + gc02m1_write_register(ViPipe, 0xd2, 0x40); + gc02m1_write_register(ViPipe, 0xd3, 0xf3); + gc02m1_write_register(ViPipe, 0xde, 0x1d); + /*analog current*/ + gc02m1_write_register(ViPipe, 0xcd, 0x05); + gc02m1_write_register(ViPipe, 0xce, 0x6f); + /*CISCTL RESET*/ + gc02m1_write_register(ViPipe, 0xfc, 0x88); + gc02m1_write_register(ViPipe, 0xfe, 0x10); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0xfc, 0x8e); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0xfc, 0x88); + gc02m1_write_register(ViPipe, 0xfe, 0x10); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0xfc, 0x8e); + gc02m1_write_register(ViPipe, 0xfe, 0x04); + gc02m1_write_register(ViPipe, 0xe0, 0x01); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + /*ISP*/ + gc02m1_write_register(ViPipe, 0xfe, 0x01); + gc02m1_write_register(ViPipe, 0x53, 0x44); + gc02m1_write_register(ViPipe, 0x87, 0x53); + gc02m1_write_register(ViPipe, 0x89, 0x03); + /*Gain*/ + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0xb0, 0x74); + gc02m1_write_register(ViPipe, 0xb1, 0x04); + gc02m1_write_register(ViPipe, 0xb2, 0x00); + gc02m1_write_register(ViPipe, 0xb6, 0x00); + gc02m1_write_register(ViPipe, 0xfe, 0x04); + gc02m1_write_register(ViPipe, 0xd8, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x40); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x60); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0xc0); + gc02m1_write_register(ViPipe, 0xc0, 0x2a); + gc02m1_write_register(ViPipe, 0xc0, 0x80); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x40); + gc02m1_write_register(ViPipe, 0xc0, 0xa0); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x90); + gc02m1_write_register(ViPipe, 0xc0, 0x19); + gc02m1_write_register(ViPipe, 0xc0, 0xc0); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0xD0); + gc02m1_write_register(ViPipe, 0xc0, 0x2F); + gc02m1_write_register(ViPipe, 0xc0, 0xe0); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x90); + gc02m1_write_register(ViPipe, 0xc0, 0x39); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x01); + gc02m1_write_register(ViPipe, 0xc0, 0x20); + gc02m1_write_register(ViPipe, 0xc0, 0x04); + gc02m1_write_register(ViPipe, 0xc0, 0x20); + gc02m1_write_register(ViPipe, 0xc0, 0x01); + gc02m1_write_register(ViPipe, 0xc0, 0xe0); + gc02m1_write_register(ViPipe, 0xc0, 0x0f); + gc02m1_write_register(ViPipe, 0xc0, 0x40); + gc02m1_write_register(ViPipe, 0xc0, 0x01); + gc02m1_write_register(ViPipe, 0xc0, 0xe0); + gc02m1_write_register(ViPipe, 0xc0, 0x1a); + gc02m1_write_register(ViPipe, 0xc0, 0x60); + gc02m1_write_register(ViPipe, 0xc0, 0x01); + gc02m1_write_register(ViPipe, 0xc0, 0x20); + gc02m1_write_register(ViPipe, 0xc0, 0x25); + gc02m1_write_register(ViPipe, 0xc0, 0x80); + gc02m1_write_register(ViPipe, 0xc0, 0x01); + gc02m1_write_register(ViPipe, 0xc0, 0xa0); + gc02m1_write_register(ViPipe, 0xc0, 0x2c); + gc02m1_write_register(ViPipe, 0xc0, 0xa0); + gc02m1_write_register(ViPipe, 0xc0, 0x01); + gc02m1_write_register(ViPipe, 0xc0, 0xe0); + gc02m1_write_register(ViPipe, 0xc0, 0x32); + gc02m1_write_register(ViPipe, 0xc0, 0xc0); + gc02m1_write_register(ViPipe, 0xc0, 0x01); + gc02m1_write_register(ViPipe, 0xc0, 0x20); + gc02m1_write_register(ViPipe, 0xc0, 0x38); + gc02m1_write_register(ViPipe, 0xc0, 0xe0); + gc02m1_write_register(ViPipe, 0xc0, 0x01); + gc02m1_write_register(ViPipe, 0xc0, 0x60); + gc02m1_write_register(ViPipe, 0xc0, 0x3c); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x02); + gc02m1_write_register(ViPipe, 0xc0, 0xa0); + gc02m1_write_register(ViPipe, 0xc0, 0x40); + gc02m1_write_register(ViPipe, 0xc0, 0x80); + gc02m1_write_register(ViPipe, 0xc0, 0x02); + gc02m1_write_register(ViPipe, 0xc0, 0x18); + gc02m1_write_register(ViPipe, 0xc0, 0x5c); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0x9f, 0x10); + /*BLK*/ + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0x26, 0x20); + gc02m1_write_register(ViPipe, 0xfe, 0x01); + gc02m1_write_register(ViPipe, 0x40, 0x22); + gc02m1_write_register(ViPipe, 0x46, 0x7f); + gc02m1_write_register(ViPipe, 0x49, 0x0f); + gc02m1_write_register(ViPipe, 0x4a, 0xf0); + gc02m1_write_register(ViPipe, 0xfe, 0x04); + gc02m1_write_register(ViPipe, 0x14, 0x80); + gc02m1_write_register(ViPipe, 0x15, 0x80); + gc02m1_write_register(ViPipe, 0x16, 0x80); + gc02m1_write_register(ViPipe, 0x17, 0x80); + /*ant _blooming*/ + gc02m1_write_register(ViPipe, 0xfe, 0x01); + gc02m1_write_register(ViPipe, 0x41, 0x20); + gc02m1_write_register(ViPipe, 0x4c, 0x00); + gc02m1_write_register(ViPipe, 0x4d, 0x0c); + gc02m1_write_register(ViPipe, 0x44, 0x08); + gc02m1_write_register(ViPipe, 0x48, 0x03); + /*Window 1600X1200*/ + gc02m1_write_register(ViPipe, 0xfe, 0x01); + gc02m1_write_register(ViPipe, 0x90, 0x01); + gc02m1_write_register(ViPipe, 0x91, 0x00); + gc02m1_write_register(ViPipe, 0x92, 0x06); + gc02m1_write_register(ViPipe, 0x93, 0x00); + gc02m1_write_register(ViPipe, 0x94, 0x06); + gc02m1_write_register(ViPipe, 0x95, 0x04); + gc02m1_write_register(ViPipe, 0x96, 0xb0); + gc02m1_write_register(ViPipe, 0x97, 0x06); + gc02m1_write_register(ViPipe, 0x98, 0x40); + /*mipi*/ + gc02m1_write_register(ViPipe, 0xfe, 0x03); + gc02m1_write_register(ViPipe, 0x01, 0x23); + gc02m1_write_register(ViPipe, 0x03, 0xce); + gc02m1_write_register(ViPipe, 0x04, 0x48); + gc02m1_write_register(ViPipe, 0x15, 0x00); + gc02m1_write_register(ViPipe, 0x21, 0x10); + gc02m1_write_register(ViPipe, 0x22, 0x05); + gc02m1_write_register(ViPipe, 0x23, 0x20); + gc02m1_write_register(ViPipe, 0x25, 0x20); + gc02m1_write_register(ViPipe, 0x26, 0x08); + gc02m1_write_register(ViPipe, 0x29, 0x06); + gc02m1_write_register(ViPipe, 0x2a, 0x0a); + gc02m1_write_register(ViPipe, 0x2b, 0x08); + /*out*/ + gc02m1_write_register(ViPipe, 0xfe, 0x01); + gc02m1_write_register(ViPipe, 0x8c, 0x10); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0x3e, 0x90); + + gc02m1_default_reg_init(ViPipe); + usleep(10 * 1000); + + printf("ViPipe:%d,===GC02M1 1200P 30fps 10bit LINEAR Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc1054/Makefile b/middleware/v2/component/isp/sensor/cv180x/gcore_gc1054/Makefile new file mode 100644 index 000000000..eb95cf432 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc1054/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc1054.a +TARGET_SO = $(MW_LIB)/libsns_gc1054.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc1054/gc1054_cmos.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc1054/gc1054_cmos.c new file mode 100644 index 000000000..8acc1b486 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc1054/gc1054_cmos.c @@ -0,0 +1,900 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "gc1054_cmos_ex.h" +#include "gc1054_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define GC1054_ID 1054 + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc1054[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC1054_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc1054[dev]) +#define GC1054_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc1054[dev] = pstCtx) +#define GC1054_SENSOR_RESET_CTX(dev) (g_pastGc1054[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc1054_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +GC1054_STATE_S g_astGc1054_State[VI_MAX_PIPE_NUM] = { {0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc1054_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16Gc1054_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Gc1054_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Gc1054 Lines Range*****/ +#define GC1054_FULL_LINES_MAX (8931) // 0x1FFF(Max VB) + 724 + 16 + +/*****Gc1054 Register Address*****/ +#define GC1054_EXP_PAGE_ADDR 0xfe +#define GC1054_EXP_H_ADDR 0x03 +#define GC1054_EXP_L_ADDR 0x04 +#define GC1054_AGAIN_PAGE_ADDR 0xfe +#define GC1054_AGAIN_ADDR 0xb6 +#define GC1054_VB_PAGE_ADDR 0xfe +#define GC1054_VB_H_ADDR 0x07 +#define GC1054_VB_L_ADDR 0x08 +#define GC1054_FLIP_MIRROR_PAGE_ADDR 0xfe +#define GC1054_FLIP_MIRROR_ADDR 0x17 + +#define GC1054_RES_IS_720P(w, h) ((w) <= 1280 && (h) <= 720) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const GC1054_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc1054_mode; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC1054_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain.u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain.u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain.u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain.u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : + pstMode->stExp.u16Def; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp.u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp.u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = 0, u32VB = 0; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_stGc1054_mode.u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_stGc1054_mode.f32MaxFps; + f32MinFps = g_stGc1054_mode.f32MinFps; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > GC1054_FULL_LINES_MAX) ? GC1054_FULL_LINES_MAX : u32VMAX; + + u32VB = u32VMAX - 724 - 16; + pstSnsRegsInfo->astI2cData[LINEAR_VB_H].u32Data = ((u32VB & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VB_L].u32Data = (u32VB & 0xFF); + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_U32 gain_table[11] = { + 16*64, + 16*91, + 16*127, + 16*182, + 16*258, + 16*369, + 16*516, + 16*738, + 16*1032, + 16*1491, + 16*2084, +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[11 - 1]) { //max 32.5625x + *pu32AgainDb = 11 - 1; + *pu32AgainLin = gain_table[11 - 1]; + return CVI_SUCCESS; + } + + for (i = 1; i < 11; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainDb = i - 1; + break; + } + } + *pu32AgainLin = gain_table[i - 1]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN].u32Data = *pu32Again; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + UNUSED(ViPipe); + UNUSED(u16ManRatioEnable); + UNUSED(au32Ratio); + UNUSED(au32IntTimeMax); + UNUSED(au32IntTimeMin); + UNUSED(pu32LFMaxIntTime); + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + UNUSED(ViPipe); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + UNUSED(ViPipe); + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + CMOS_CHECK_POINTER(pstBlc); + UNUSED(ViPipe); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC1054_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc1054_mode; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->stImg, sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = GC1054_MODE_1280X720P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc1054_mode.u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunGc1054_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = gc1054_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc1054_addr_byte; + pstI2c_data[i].u32DataByteNum = gc1054_data_byte; + } + + pstI2c_data[LINEAR_EXP_PAGE].u32RegAddr = GC1054_EXP_PAGE_ADDR; + pstI2c_data[LINEAR_EXP_PAGE].u32Data = 0; + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC1054_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC1054_EXP_L_ADDR; + pstI2c_data[LINEAR_GAIN_PAGE].u32RegAddr = GC1054_AGAIN_PAGE_ADDR; + pstI2c_data[LINEAR_GAIN_PAGE].u32Data = 1; + pstI2c_data[LINEAR_AGAIN].u32RegAddr = GC1054_AGAIN_ADDR; + pstI2c_data[LINEAR_VB_PAGE].u32RegAddr = GC1054_VB_PAGE_ADDR; + pstI2c_data[LINEAR_VB_PAGE].u32Data = 0; + pstI2c_data[LINEAR_VB_H].u32RegAddr = GC1054_VB_H_ADDR; + pstI2c_data[LINEAR_VB_L].u32RegAddr = GC1054_VB_L_ADDR; + pstI2c_data[LINEAR_FLIP_MIRROR_PAGE].u32RegAddr = GC1054_FLIP_MIRROR_PAGE_ADDR; + pstI2c_data[LINEAR_FLIP_MIRROR_PAGE].u32Data = 0; + pstI2c_data[LINEAR_FLIP_MIRROR].u32RegAddr = GC1054_FLIP_MIRROR_ADDR; + pstI2c_data[LINEAR_FLIP_MIRROR].u32Data = 0xc0; + + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + + CVI_U32 gainsUpdate = 0, expUpdate = 0, vbUpdate = 0; + + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + + if (i == LINEAR_AGAIN) + gainsUpdate = 1; + + if ((i >= LINEAR_EXP_H) && (i <= LINEAR_EXP_L)) + expUpdate = 1; + + if ((i >= LINEAR_VB_H) && (i <= LINEAR_VB_L)) + vbUpdate = 1; + + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (gainsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_GAIN_PAGE].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN].bUpdate = CVI_TRUE; + } + if (expUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_PAGE].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_L].bUpdate = CVI_TRUE; + } + if (vbUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_VB_PAGE].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_VB_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_VB_L].bUpdate = CVI_TRUE; + } + if (pstI2c_data[LINEAR_FLIP_MIRROR].bUpdate == CVI_TRUE) { + pstI2c_data[LINEAR_FLIP_MIRROR_PAGE].bUpdate = CVI_TRUE; + } + + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + pstCfg0->ispCfg.u8DelayFrmNum = 1; + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = CVI_FALSE; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC1054_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC1054_MODE_1280X720P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 value = 0xC0; + CVI_U8 start_x = 3; + CVI_U8 start_y = 2; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_ISP_INFO_S *pstIspCfg0 = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + pstIspCfg0 = &pstSnsState->astSyncInfo[0].ispCfg; + + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc1054_MirrorFip[ViPipe] != eSnsMirrorFlip) { + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + value = 0xC0; + start_x = 3; + start_y = 2; + break; + case ISP_SNS_MIRROR: + value = 0xC1; + start_x = 4; + start_y = 2; + break; + case ISP_SNS_FLIP: + value = 0xC2; + start_x = 3; + start_y = 3; + break; + case ISP_SNS_MIRROR_FLIP: + value = 0xC3; + start_x = 4; + start_y = 3; + break; + default: + return; + } + + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u8DropFrmNum = 1; + pstIspCfg0->img_size[0].stWndRect.s32X = start_x; + pstIspCfg0->img_size[0].stWndRect.s32Y = start_y; + + g_aeGc1054_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC1054_MODE_1280X720P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc1054_mode.u32VtsDef; + pstSnsState->au32FL[0] = g_stGc1054_mode.u32VtsDef; + pstSnsState->au32FL[1] = g_stGc1054_mode.u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc1054_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_stGc1054_mode.stImg.stSnsSize.u32Width; + pstRxAttr->img_size.height = g_stGc1054_mode.stImg.stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc1054_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc1054_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc1054_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 gc1054_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc1054_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC1054_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC1054_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC1054_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC1054_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC1054_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC1054_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Gc1054_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Gc1054_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsGc1054_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc1054_standby, + .pfnRestart = gc1054_restart, + .pfnWriteReg = gc1054_write_register, + .pfnReadReg = gc1054_read_register, + .pfnSetBusInfo = gc1054_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc1054/gc1054_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc1054/gc1054_cmos_ex.h new file mode 100644 index 000000000..da266e899 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc1054/gc1054_cmos_ex.h @@ -0,0 +1,86 @@ +#ifndef __GC1054_CMOS_EX_H_ +#define __GC1054_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum gc1054_linear_regs_e { + LINEAR_EXP_PAGE = 0, //fe + LINEAR_EXP_H, //03 + LINEAR_EXP_L, //04 + LINEAR_GAIN_PAGE, //fe + LINEAR_AGAIN, //b6 + LINEAR_VB_PAGE, //fe + LINEAR_VB_H, //07 + LINEAR_VB_L, //08 + LINEAR_FLIP_MIRROR_PAGE, //fe + LINEAR_FLIP_MIRROR, //17 + LINEAR_REGS_NUM +}; + + +typedef enum _GC1054_MODE_E { + GC1054_MODE_1280X720P30 = 0, + GC1054_MODE_NUM +} GC1054_SLAVE_MODE_E; + +typedef struct _GC1054_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC1054_STATE_S; + +typedef struct _GC1054_MODE_S { + ISP_WDR_SIZE_S stImg; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp; + SNS_ATTR_LARGE_S stAgain; + SNS_ATTR_LARGE_S stDgain; + char name[64]; +} GC1054_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc1054[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc1054_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc1054_MirrorFip[VI_MAX_PIPE_NUM]; +extern const CVI_U8 gc1054_i2c_addr; +extern const CVI_U32 gc1054_addr_byte; +extern const CVI_U32 gc1054_data_byte; +extern void gc1054_init(VI_PIPE ViPipe); +extern void gc1054_exit(VI_PIPE ViPipe); +extern void gc1054_standby(VI_PIPE ViPipe); +extern void gc1054_restart(VI_PIPE ViPipe); +extern int gc1054_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc1054_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC1054_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc1054/gc1054_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc1054/gc1054_cmos_param.h new file mode 100644 index 000000000..1d49ef7a5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc1054/gc1054_cmos_param.h @@ -0,0 +1,223 @@ +#ifndef __GC1054_CMOS_PARAM_H_ +#define __GC1054_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc1054_cmos_ex.h" + +static const GC1054_MODE_S g_stGc1054_mode = { + .name = "1280X720P30", + .stImg = { + .stSnsSize = { + .u32Width = 1288, + .u32Height = 724, + }, + .stWndRect = { + .s32X = 3, + .s32Y = 2, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1288, + .u32Height = 724, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.63, /* 782 * 30 / 8931*/ + .u32HtsDef = 1726, + .u32VtsDef = 782, /* WIN_H + VB + 16 */ + .stExp = { + .u16Min = 1, + .u16Max = 782 - 1, /* VtsDef - 1*/ + .u16Def = 100, + .u16Step = 1, + }, + .stAgain = { + .u32Min = 1024, + .u32Max = 16 * 2084, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain = { + .u32Min = 1024, + .u32Max = 1024, + .u32Def = 1024, + .u32Step = 1, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.05999477580189704895, 0.13019448518753051758}, //B: slope, intercept + {0.06732148677110671997, -1.36387133598327636719}, //Gb: slope, intercept + {0.06651904433965682983, -1.10093510150909423828}, //Gr: slope, intercept + {0.06406146287918090820, 0.33316791057586669922}, //R: slope, intercept + }, + { //iso 200 + {0.06256803125143051147, 4.54908418655395507813}, //B: slope, intercept + {0.06911934912204742432, 2.79023528099060058594}, //Gb: slope, intercept + {0.06846688687801361084, 2.88726186752319335938}, //Gr: slope, intercept + {0.06652788817882537842, 4.40276956558227539063}, //R: slope, intercept + }, + { //iso 400 + {0.06841833144426345825, 11.72280883789062500000}, //B: slope, intercept + {0.07257881015539169312, 10.86985683441162109375}, //Gb: slope, intercept + {0.07174283266067504883, 11.20646286010742187500}, //Gr: slope, intercept + {0.07294593751430511475, 11.17350578308105468750}, //R: slope, intercept + }, + { //iso 800 + {0.07805790752172470093, 20.62956619262695312500}, //B: slope, intercept + {0.07694032043218612671, 22.20356750488281250000}, //Gb: slope, intercept + {0.07647507637739181519, 22.50957298278808593750}, //Gr: slope, intercept + {0.08402533829212188721, 19.11953735351562500000}, //R: slope, intercept + }, + { //iso 1600 + {0.09468275308609008789, 34.07563018798828125000}, //B: slope, intercept + {0.08710632473230361938, 39.15500259399414062500}, //Gb: slope, intercept + {0.08662072569131851196, 39.37175750732421875000}, //Gr: slope, intercept + {0.10222808271646499634, 31.34789276123046875000}, //R: slope, intercept + }, + { //iso 3200 + {0.12651191651821136475, 49.56183242797851562500}, //B: slope, intercept + {0.10816962271928787231, 59.42719650268554687500}, //Gb: slope, intercept + {0.10751257836818695068, 59.90552902221679687500}, //Gr: slope, intercept + {0.13802853226661682129, 45.09576034545898437500}, //R: slope, intercept + }, + { //iso 6400 + {0.17422541975975036621, 70.04063415527343750000}, //B: slope, intercept + {0.14234761893749237061, 85.51583862304687500000}, //Gb: slope, intercept + {0.14159946143627166748, 86.23278045654296875000}, //Gr: slope, intercept + {0.19450971484184265137, 62.65447235107421875000}, //R: slope, intercept + }, + { //iso 12800 + {0.24947367608547210693, 108.30633544921875000000}, //B: slope, intercept + {0.19751225411891937256, 130.88159179687500000000}, //Gb: slope, intercept + {0.19614629447460174561, 132.49082946777343750000}, //Gr: slope, intercept + {0.28106108307838439941, 97.15969085693359375000}, //R: slope, intercept + }, + { //iso 25600 + {0.35420843958854675293, 137.06745910644531250000}, //B: slope, intercept + {0.27778801321983337402, 168.72366333007812500000}, //Gb: slope, intercept + {0.27540388703346252441, 170.54939270019531250000}, //Gr: slope, intercept + {0.39949953556060791016, 123.29409790039062500000}, //R: slope, intercept + }, + { //iso 51200 + {0.45704349875450134277, 179.20147705078125000000}, //B: slope, intercept + {0.32142028212547302246, 246.71363830566406250000}, //Gb: slope, intercept + {0.31958609819412231445, 246.82630920410156250000}, //Gr: slope, intercept + {0.51058447360992431641, 161.86299133300781250000}, //R: slope, intercept + }, + { //iso 102400 + {0.61760461330413818359, 222.90534973144531250000}, //B: slope, intercept + {0.42568457126617431641, 319.29257202148437500000}, //Gb: slope, intercept + {0.41750904917716979980, 324.93432617187500000000}, //Gr: slope, intercept + {0.67956107854843139648, 203.78948974609375000000}, //R: slope, intercept + }, + { //iso 204800 + {0.63289469480514526367, 216.99952697753906250000}, //B: slope, intercept + {0.44890350103378295898, 306.80810546875000000000}, //Gb: slope, intercept + {0.44229975342750549316, 310.13763427734375000000}, //Gr: slope, intercept + {0.69596910476684570313, 196.70443725585937500000}, //R: slope, intercept + }, + { //iso 409600 + {0.71106964349746704102, 187.98352050781250000000}, //B: slope, intercept + {0.55859673023223876953, 246.22378540039062500000}, //Gb: slope, intercept + {0.55284017324447631836, 249.86463928222656250000}, //Gr: slope, intercept + {0.77318203449249267578, 168.85035705566406250000}, //R: slope, intercept + }, + { //iso 819200 + {0.70888006687164306641, 188.44216918945312500000}, //B: slope, intercept + {0.56110274791717529297, 245.46603393554687500000}, //Gb: slope, intercept + {0.55100852251052856445, 250.33049011230468750000}, //Gr: slope, intercept + {0.76897650957107543945, 169.31251525878906250000}, //R: slope, intercept + }, + { //iso 1638400 + {0.70520979166030883789, 188.93899536132812500000}, //B: slope, intercept + {0.56178557872772216797, 245.21235656738281250000}, //Gb: slope, intercept + {0.55338454246520996094, 249.57423400878906250000}, //Gr: slope, intercept + {0.77306479215621948242, 168.86497497558593750000}, //R: slope, intercept + }, + { //iso 3276800 + {0.71255809068679809570, 187.86839294433593750000}, //B: slope, intercept + {0.56056070327758789063, 245.57748413085937500000}, //Gb: slope, intercept + {0.55358195304870605469, 249.62020874023437500000}, //Gr: slope, intercept + {0.77431541681289672852, 168.74313354492187500000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {256, 256, 257, 257, 259, 259, 260, 267, 278, 298, 366, 383, 366, 373, 372, 372 }, + {256, 256, 257, 257, 258, 259, 261, 266, 274, 297, 379, 377, 372, 365, 373, 374 }, + {256, 256, 257, 257, 258, 259, 261, 266, 275, 296, 376, 388, 366, 374, 376, 372 }, + {256, 256, 257, 257, 258, 259, 260, 264, 274, 294, 362, 363, 365, 361, 353, 367 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1092, 1093, 1093, 1093, 1093, 1093, 1095, + 1099, 1104, 1125, 1130, 1125, 1127, 1126, 1126}, + {1092, 1092, 1093, 1093, 1093, 1093, 1094, 1095, + 1097, 1104, 1128, 1128, 1126, 1124, 1127, 1127}, + {1092, 1092, 1093, 1093, 1093, 1093, 1094, 1095, + 1098, 1104, 1128, 1131, 1125, 1127, 1128, 1126}, + {1092, 1092, 1093, 1093, 1093, 1093, 1093, 1095, + 1097, 1103, 1123, 1124, 1124, 1123, 1121, 1125}, +#endif + }, + }, +}; + +struct combo_dev_attr_s gc1054_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {3, 4, -1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 8, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 1, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC1054_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc1054/gc1054_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc1054/gc1054_sensor_ctl.c new file mode 100644 index 000000000..82822b860 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc1054/gc1054_sensor_ctl.c @@ -0,0 +1,313 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc1054_cmos_ex.h" + +static void gc1054_linear_720p30_init(VI_PIPE ViPipe); + +const CVI_U8 gc1054_i2c_addr = 0x21;//0x42 +const CVI_U32 gc1054_addr_byte = 1; +const CVI_U32 gc1054_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc1054_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc1054_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc1054_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc1054_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc1054_read_register(VI_PIPE ViPipe, int addr) +{ + /* TODO:*/ + UNUSED(ViPipe); + UNUSED(addr); + return CVI_SUCCESS; +} + + +int gc1054_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc1054_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (gc1054_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc1054_addr_byte + gc1054_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + //ret = read(g_fd[ViPipe], buf, gc1054_addr_byte + gc1054_data_byte); + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void gc1054_standby(VI_PIPE ViPipe) +{ + UNUSED(ViPipe); + printf("gc1054_standby\n"); +} + +void gc1054_restart(VI_PIPE ViPipe) +{ + UNUSED(ViPipe); + printf("gc1054_restart\n"); +} + +void gc1054_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc1054[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc1054_write_register(ViPipe, + g_pastGc1054[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc1054[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void gc1054_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode = g_pastGc1054[ViPipe]->enWDRMode; + + gc1054_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n"); + } else { + gc1054_linear_720p30_init(ViPipe); + } + g_pastGc1054[ViPipe]->bInit = CVI_TRUE; +} + +void gc1054_exit(VI_PIPE ViPipe) +{ + gc1054_i2c_exit(ViPipe); +} + +static void gc1054_linear_720p30_init(VI_PIPE ViPipe) +{ + /****system****/ + gc1054_write_register(ViPipe, 0xf2, 0x00); + gc1054_write_register(ViPipe, 0xf6, 0x00); + gc1054_write_register(ViPipe, 0xfc, 0x04); + gc1054_write_register(ViPipe, 0xf7, 0x01); + gc1054_write_register(ViPipe, 0xf8, 0x0b); + gc1054_write_register(ViPipe, 0xf9, 0x06); + gc1054_write_register(ViPipe, 0xfa, 0x80); + gc1054_write_register(ViPipe, 0xfc, 0x0e); + /****CISCTL & ANALOG****/ + gc1054_write_register(ViPipe, 0xfe, 0x00); + gc1054_write_register(ViPipe, 0x03, 0x02); + gc1054_write_register(ViPipe, 0x04, 0xa6); + gc1054_write_register(ViPipe, 0x05, 0x02); //HB + gc1054_write_register(ViPipe, 0x06, 0x07); + gc1054_write_register(ViPipe, 0x07, 0x00); //VB + gc1054_write_register(ViPipe, 0x08, 0x2a); + gc1054_write_register(ViPipe, 0x09, 0x00); + gc1054_write_register(ViPipe, 0x0a, 0x04); //row start + gc1054_write_register(ViPipe, 0x0b, 0x00); + gc1054_write_register(ViPipe, 0x0c, 0x00); //col start + gc1054_write_register(ViPipe, 0x0d, 0x02); + gc1054_write_register(ViPipe, 0x0e, 0xd8); //height 724 + gc1054_write_register(ViPipe, 0x0f, 0x05); + gc1054_write_register(ViPipe, 0x10, 0x10); //width 1288 + gc1054_write_register(ViPipe, 0x17, 0xc0); + gc1054_write_register(ViPipe, 0x18, 0x02); + gc1054_write_register(ViPipe, 0x19, 0x08); + gc1054_write_register(ViPipe, 0x1a, 0x18); + gc1054_write_register(ViPipe, 0x1d, 0x12); + gc1054_write_register(ViPipe, 0x1e, 0x50); + gc1054_write_register(ViPipe, 0x1f, 0x80); + gc1054_write_register(ViPipe, 0x21, 0x3a); + gc1054_write_register(ViPipe, 0x23, 0xe8); + gc1054_write_register(ViPipe, 0x25, 0x10); + gc1054_write_register(ViPipe, 0x28, 0x20); + gc1054_write_register(ViPipe, 0x34, 0x0a); //data low + gc1054_write_register(ViPipe, 0x3c, 0x10); + gc1054_write_register(ViPipe, 0x3d, 0x0e); + gc1054_write_register(ViPipe, 0xcc, 0x8f); + gc1054_write_register(ViPipe, 0xcd, 0x9a); + gc1054_write_register(ViPipe, 0xcf, 0x70); + gc1054_write_register(ViPipe, 0xd0, 0x9a); + gc1054_write_register(ViPipe, 0xd1, 0xc5); + gc1054_write_register(ViPipe, 0xd2, 0xed); //data high + gc1054_write_register(ViPipe, 0xd8, 0x3c); //dacin offset + gc1054_write_register(ViPipe, 0xd9, 0x7a); + gc1054_write_register(ViPipe, 0xda, 0x12); + gc1054_write_register(ViPipe, 0xdb, 0x50); + gc1054_write_register(ViPipe, 0xde, 0x0c); + gc1054_write_register(ViPipe, 0xe3, 0x60); + gc1054_write_register(ViPipe, 0xe4, 0x78); + gc1054_write_register(ViPipe, 0xfe, 0x01); + gc1054_write_register(ViPipe, 0xe3, 0x01); + gc1054_write_register(ViPipe, 0xe6, 0x16); //ramps offset + gc1054_write_register(ViPipe, 0xfe, 0x01); + gc1054_write_register(ViPipe, 0x80, 0x50); + gc1054_write_register(ViPipe, 0x88, 0x73); + gc1054_write_register(ViPipe, 0x89, 0x03); + gc1054_write_register(ViPipe, 0x90, 0x01); + gc1054_write_register(ViPipe, 0x92, 0x00); //crop win 2<=y<=4 + gc1054_write_register(ViPipe, 0x94, 0x00); //crop win 2<=x<=5 + gc1054_write_register(ViPipe, 0x95, 0x02); //crop win height + gc1054_write_register(ViPipe, 0x96, 0xd4); + gc1054_write_register(ViPipe, 0x97, 0x05); //crop win width + gc1054_write_register(ViPipe, 0x98, 0x08); + /*blk*/ + gc1054_write_register(ViPipe, 0xfe, 0x01); + gc1054_write_register(ViPipe, 0x40, 0x22); + gc1054_write_register(ViPipe, 0x43, 0x03); + gc1054_write_register(ViPipe, 0x4e, 0x3c); + gc1054_write_register(ViPipe, 0x4f, 0x00); + gc1054_write_register(ViPipe, 0x60, 0x00); + gc1054_write_register(ViPipe, 0x61, 0x80); + /*gain*/ + gc1054_write_register(ViPipe, 0xfe, 0x01); + gc1054_write_register(ViPipe, 0xb0, 0x48); + gc1054_write_register(ViPipe, 0xb1, 0x01); + gc1054_write_register(ViPipe, 0xb2, 0x00); + gc1054_write_register(ViPipe, 0xb6, 0x00); + gc1054_write_register(ViPipe, 0xfe, 0x02); + gc1054_write_register(ViPipe, 0x01, 0x00); + gc1054_write_register(ViPipe, 0x02, 0x01); + gc1054_write_register(ViPipe, 0x03, 0x02); + gc1054_write_register(ViPipe, 0x04, 0x03); + gc1054_write_register(ViPipe, 0x05, 0x04); + gc1054_write_register(ViPipe, 0x06, 0x05); + gc1054_write_register(ViPipe, 0x07, 0x06); + gc1054_write_register(ViPipe, 0x08, 0x0e); + gc1054_write_register(ViPipe, 0x09, 0x16); + gc1054_write_register(ViPipe, 0x0a, 0x1e); + gc1054_write_register(ViPipe, 0x0b, 0x36); + gc1054_write_register(ViPipe, 0x0c, 0x3e); + gc1054_write_register(ViPipe, 0x0d, 0x56); + gc1054_write_register(ViPipe, 0xfe, 0x02); + gc1054_write_register(ViPipe, 0xb0, 0x00); //col_gain[11:8] + gc1054_write_register(ViPipe, 0xb1, 0x00); + gc1054_write_register(ViPipe, 0xb2, 0x00); + gc1054_write_register(ViPipe, 0xb3, 0x11); + gc1054_write_register(ViPipe, 0xb4, 0x22); + gc1054_write_register(ViPipe, 0xb5, 0x54); + gc1054_write_register(ViPipe, 0xb6, 0xb8); + gc1054_write_register(ViPipe, 0xb7, 0x60); + gc1054_write_register(ViPipe, 0xb9, 0x00); //col_gain[12] + gc1054_write_register(ViPipe, 0xba, 0xc0); + gc1054_write_register(ViPipe, 0xc0, 0x20); //col_gain[7:0] + gc1054_write_register(ViPipe, 0xc1, 0x2d); + gc1054_write_register(ViPipe, 0xc2, 0x40); + gc1054_write_register(ViPipe, 0xc3, 0x5b); + gc1054_write_register(ViPipe, 0xc4, 0x80); + gc1054_write_register(ViPipe, 0xc5, 0xb5); + gc1054_write_register(ViPipe, 0xc6, 0x00); + gc1054_write_register(ViPipe, 0xc7, 0x6a); + gc1054_write_register(ViPipe, 0xc8, 0x00); + gc1054_write_register(ViPipe, 0xc9, 0xd4); + gc1054_write_register(ViPipe, 0xca, 0x00); + gc1054_write_register(ViPipe, 0xcb, 0xa8); + gc1054_write_register(ViPipe, 0xcc, 0x00); + gc1054_write_register(ViPipe, 0xcd, 0x50); + gc1054_write_register(ViPipe, 0xce, 0x00); + gc1054_write_register(ViPipe, 0xcf, 0xa1); + /****DARKSUN****/ + gc1054_write_register(ViPipe, 0xfe, 0x02); + gc1054_write_register(ViPipe, 0x54, 0xf7); + gc1054_write_register(ViPipe, 0x55, 0xf0); + gc1054_write_register(ViPipe, 0x56, 0x00); + gc1054_write_register(ViPipe, 0x57, 0x00); + gc1054_write_register(ViPipe, 0x58, 0x00); + gc1054_write_register(ViPipe, 0x5a, 0x04); + /****DD****/ + gc1054_write_register(ViPipe, 0xfe, 0x04); + gc1054_write_register(ViPipe, 0x40, 0x40); //blc 0x40-10bit + gc1054_write_register(ViPipe, 0x81, 0x8a); + /****DVP & MIPI****/ + gc1054_write_register(ViPipe, 0xfe, 0x03); + gc1054_write_register(ViPipe, 0x01, 0x03); + gc1054_write_register(ViPipe, 0x02, 0x11); + gc1054_write_register(ViPipe, 0x03, 0x90); + gc1054_write_register(ViPipe, 0x10, 0x90); + gc1054_write_register(ViPipe, 0x11, 0x2b); + gc1054_write_register(ViPipe, 0x12, 0x4a); //lwc 1280*5/4 + gc1054_write_register(ViPipe, 0x13, 0x06); + gc1054_write_register(ViPipe, 0x15, 0x06); + gc1054_write_register(ViPipe, 0x21, 0x02); + gc1054_write_register(ViPipe, 0x22, 0x02); + gc1054_write_register(ViPipe, 0x23, 0x08); + gc1054_write_register(ViPipe, 0x24, 0x02); + gc1054_write_register(ViPipe, 0x25, 0x10); + gc1054_write_register(ViPipe, 0x26, 0x04); + gc1054_write_register(ViPipe, 0x29, 0x02); + gc1054_write_register(ViPipe, 0x2a, 0x02); + gc1054_write_register(ViPipe, 0x2b, 0x08); + gc1054_write_register(ViPipe, 0x42, 0x08); + gc1054_write_register(ViPipe, 0x43, 0x05); + gc1054_write_register(ViPipe, 0xfe, 0x00); + + gc1054_default_reg_init(ViPipe); + delay_ms(40); + printf("ViPipe:%d,===GC1054 720P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053/Makefile b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053/Makefile new file mode 100644 index 000000000..8566f11ff --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc2053.a +TARGET_SO = $(MW_LIB)/libsns_gc2053.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053/gc2053_cmos.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053/gc2053_cmos.c new file mode 100644 index 000000000..2b33e50d0 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053/gc2053_cmos.c @@ -0,0 +1,883 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "gc2053_cmos_ex.h" +#include "gc2053_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define GC2053_ID 2053 +#define GC2053_I2C_ADDR_1 0x3f +#define GC2053_I2C_ADDR_2 0x37 +#define GC2053_I2C_ADDR_IS_VALID(addr) ((addr) == GC2053_I2C_ADDR_1 || (addr) == GC2053_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc2053[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC2053_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc2053[dev]) +#define GC2053_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc2053[dev] = pstCtx) +#define GC2053_SENSOR_RESET_CTX(dev) (g_pastGc2053[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc2053_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +GC2053_STATE_S g_astGc2053_State[VI_MAX_PIPE_NUM] = { {0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2053_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16Gc2053_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Gc2053_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Gc2053 Lines Range*****/ +#define GC2053_FULL_LINES_MAX (0x3fff) + +/*****Gc2053 Register Address*****/ +#define GC2053_EXP_H_ADDR 0x03 +#define GC2053_EXP_L_ADDR 0x04 +#define GC2053_AGAIN_H_ADDR 0xb4 +#define GC2053_AGAIN_L_ADDR 0xb3 +#define GC2053_COL_AGAIN_H_ADDR 0xb8 +#define GC2053_COL_AGAIN_L_ADDR 0xb9 +#define GC2053_DGAIN_H_ADDR 0xb1 +#define GC2053_DGAIN_L_ADDR 0xb2 +#define GC2053_VTS_H_ADDR 0x41 //(frame length) +#define GC2053_VTS_L_ADDR 0x42 + +#define GC2053_RES_IS_1080P(w, h) ((w) == 1920 && (h) == 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const GC2053_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc2053_mode; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC2053_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 3985*16; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 10240; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : + pstMode->stExp.u16Def; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp.u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp.u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = 0; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_stGc2053_mode.u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_stGc2053_mode.f32MaxFps; + f32MinFps = g_stGc2053_mode.f32MinFps; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > GC2053_FULL_LINES_MAX) ? GC2053_FULL_LINES_MAX : u32VMAX; + + pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF); + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_U32 regValTable[25][4] = { + {0x00, 0x00, 0x01, 0x00}, + {0x00, 0x10, 0x01, 0x0c}, + {0x00, 0x20, 0x01, 0x1b}, + {0x00, 0x30, 0x01, 0x2c}, + {0x00, 0x40, 0x01, 0x3f}, + {0x00, 0x50, 0x02, 0x16}, + {0x00, 0x60, 0x02, 0x35}, + {0x00, 0x70, 0x03, 0x16}, + {0x00, 0x80, 0x04, 0x02}, + {0x00, 0x90, 0x04, 0x31}, + {0x00, 0xa0, 0x05, 0x32}, + {0x00, 0xb0, 0x06, 0x35}, + {0x00, 0xc0, 0x08, 0x04}, + {0x00, 0x5a, 0x09, 0x19}, + {0x00, 0x83, 0x0b, 0x0f}, + {0x00, 0x93, 0x0d, 0x12}, + {0x00, 0x84, 0x10, 0x00}, + {0x00, 0x94, 0x12, 0x3a}, + {0x01, 0x2c, 0x1a, 0x02}, + {0x01, 0x3c, 0x1b, 0x20}, + {0x00, 0x8c, 0x20, 0x0f}, + {0x00, 0x9c, 0x26, 0x07}, + {0x02, 0x64, 0x36, 0x21}, + {0x02, 0x74, 0x37, 0x3a}, + {0x00, 0xc6, 0x3d, 0x02}, +}; + +static CVI_U32 gain_table[25] = { + 64*16, 76*16, 90*16, 108*16, 127*16, 148*16, 180*16, 216*16, 255*16, 300*16, + 361*16, 422*16, 504*16, 593*16, 722*16, 850*16, 1008*16, 1182*16, 1408*16, 1689*16, + 2021*16, 2391*16, 2850*16, 3369*16, 3985*16,/* 4805*16, 5768*16, 6806*16, 7723*16,*/ +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i, total; + CVI_U32 pregain; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + total = sizeof(gain_table) / sizeof(CVI_U32); + + if (*pu32AgainLin >= gain_table[total - 1]) { + *pu32AgainLin = *pu32AgainDb = gain_table[total - 1]; + return CVI_SUCCESS; + } + + for (i = 1; i < total; i++) { + if (*pu32AgainLin < gain_table[i]) + break; + } + i--; + // find the pregain + pregain = *pu32AgainLin * 64 / gain_table[i]; + // set the Db as the AE algo gain, we need this to do gain update + *pu32AgainDb = *pu32AgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32AgainLin = pregain * gain_table[i] / 64; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 pregain; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + // find the pregain + pregain = *pu32DgainLin * 64 / 1024; + // set the Db as the AE algo gain, we need this to do gain update + *pu32DgainDb = *pu32DgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32DgainLin = pregain * 16; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + int i, total; + + total = sizeof(gain_table) / sizeof(CVI_U32); + + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* only surpport linear mode */ + u32Again = pu32Again[0]; + /* To kepp the linearity. we assume AE algo adjusts the dgain only when the again reachs the maximum value */ + if (u32Again < (3985*16)) { + for (i = 1; i < total; i++) { + if (*pu32Again < gain_table[i]) + break; + } + i--; + // find the pregain + u32Dgain = u32Again * 64 / gain_table[i]; + u32Again = i; + } else { + u32Again = total - 1; + // find the pregain + u32Dgain = pu32Dgain[0] * 64 / 1024; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][0]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][1]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][2]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][3]; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 6); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + UNUSED(ViPipe); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + UNUSED(ViPipe); + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + CMOS_CHECK_POINTER(pstBlc); + UNUSED(ViPipe); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC2053_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc2053_mode; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->stImg, sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = GC2053_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc2053_mode.u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunGc2053_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = gc2053_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc2053_addr_byte; + pstI2c_data[i].u32DataByteNum = gc2053_data_byte; + } + + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC2053_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC2053_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC2053_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC2053_AGAIN_L_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC2053_COL_AGAIN_H_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC2053_COL_AGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC2053_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC2053_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC2053_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC2053_VTS_L_ADDR; + + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + + CVI_U32 gainsUpdate = 0; + + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + + if ((i >= LINEAR_AGAIN_H) && (i <= LINEAR_DGAIN_L)) + gainsUpdate = 1; + + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (gainsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L].bUpdate = CVI_TRUE; + } + + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC2053_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC2053_MODE_1920X1080P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc2053_MirrorFip[ViPipe] != eSnsMirrorFlip) { + gc2053_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeGc2053_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC2053_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc2053_mode.u32VtsDef; + pstSnsState->au32FL[0] = g_stGc2053_mode.u32VtsDef; + pstSnsState->au32FL[1] = g_stGc2053_mode.u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc2053_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_stGc2053_mode.stImg.stSnsSize.u32Width; + pstRxAttr->img_size.height = g_stGc2053_mode.stImg.stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc2053_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc2053_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc2053_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (GC2053_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc2053_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc2053_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc2053_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2053_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC2053_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2053_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC2053_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC2053_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC2053_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC2053_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC2053_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Gc2053_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Gc2053_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc2053_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc2053_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc2053_standby, + .pfnRestart = gc2053_restart, + .pfnWriteReg = gc2053_write_register, + .pfnReadReg = gc2053_read_register, + .pfnSetBusInfo = gc2053_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053/gc2053_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053/gc2053_cmos_ex.h new file mode 100644 index 000000000..05f2bb670 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053/gc2053_cmos_ex.h @@ -0,0 +1,88 @@ +#ifndef __GC2053_CMOS_EX_H_ +#define __GC2053_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum gc2053_linear_regs_e { + LINEAR_EXP_H = 0,//03 + LINEAR_EXP_L, //04 + LINEAR_AGAIN_H, //b4 + LINEAR_AGAIN_L, //b3 + LINEAR_COL_AGAIN_H, //b8 + LINEAR_COL_AGAIN_L, //b9 + LINEAR_DGAIN_H, //b1 + LINEAR_DGAIN_L, //b2 + LINEAR_VTS_H, //0x41 (frame length) + LINEAR_VTS_L,//0x42 + LINEAR_REGS_NUM +}; + + +typedef enum _GC2053_MODE_E { + GC2053_MODE_1920X1080P30 = 0, + GC2053_MODE_NUM +} GC2053_SLAVE_MODE_E; + +typedef struct _GC2053_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC2053_STATE_S; + +typedef struct _GC2053_MODE_S { + ISP_WDR_SIZE_S stImg; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp; + SNS_ATTR_LARGE_S stAgain; + SNS_ATTR_LARGE_S stDgain; + char name[64]; +} GC2053_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc2053[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc2053_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2053_MirrorFip[VI_MAX_PIPE_NUM]; +extern CVI_U8 gc2053_i2c_addr; +extern const CVI_U32 gc2053_addr_byte; +extern const CVI_U32 gc2053_data_byte; +extern void gc2053_init(VI_PIPE ViPipe); +extern void gc2053_exit(VI_PIPE ViPipe); +extern void gc2053_standby(VI_PIPE ViPipe); +extern void gc2053_restart(VI_PIPE ViPipe); +extern int gc2053_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc2053_read_register(VI_PIPE ViPipe, int addr); +extern void gc2053_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int gc2053_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2053_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053/gc2053_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053/gc2053_cmos_param.h new file mode 100644 index 000000000..d2824cf5b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053/gc2053_cmos_param.h @@ -0,0 +1,219 @@ +#ifndef __GC2053_CMOS_PARAM_H_ +#define __GC2053_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2053_cmos_ex.h" + +static const GC2053_MODE_S g_stGc2053_mode = { + .name = "1920X1080P30", + .stImg = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.07, /* 1125 * 30 / 0x3FFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp = { + .u16Min = 1, + .u16Max = 0x3fff, + .u16Def = 0x2000, + .u16Step = 1, + }, + .stAgain = { + .u32Min = 64, + .u32Max = 62977, + .u32Def = 64, + .u32Step = 1, + }, + .stDgain = { + .u32Min = 64*16, + .u32Max = 7073*16, + .u32Def = 581*16, + .u32Step = 10*16, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.05999477580189704895, 0.13019448518753051758}, //B: slope, intercept + {0.06732148677110671997, -1.36387133598327636719}, //Gb: slope, intercept + {0.06651904433965682983, -1.10093510150909423828}, //Gr: slope, intercept + {0.06406146287918090820, 0.33316791057586669922}, //R: slope, intercept + }, + { //iso 200 + {0.06256803125143051147, 4.54908418655395507813}, //B: slope, intercept + {0.06911934912204742432, 2.79023528099060058594}, //Gb: slope, intercept + {0.06846688687801361084, 2.88726186752319335938}, //Gr: slope, intercept + {0.06652788817882537842, 4.40276956558227539063}, //R: slope, intercept + }, + { //iso 400 + {0.06841833144426345825, 11.72280883789062500000}, //B: slope, intercept + {0.07257881015539169312, 10.86985683441162109375}, //Gb: slope, intercept + {0.07174283266067504883, 11.20646286010742187500}, //Gr: slope, intercept + {0.07294593751430511475, 11.17350578308105468750}, //R: slope, intercept + }, + { //iso 800 + {0.07805790752172470093, 20.62956619262695312500}, //B: slope, intercept + {0.07694032043218612671, 22.20356750488281250000}, //Gb: slope, intercept + {0.07647507637739181519, 22.50957298278808593750}, //Gr: slope, intercept + {0.08402533829212188721, 19.11953735351562500000}, //R: slope, intercept + }, + { //iso 1600 + {0.09468275308609008789, 34.07563018798828125000}, //B: slope, intercept + {0.08710632473230361938, 39.15500259399414062500}, //Gb: slope, intercept + {0.08662072569131851196, 39.37175750732421875000}, //Gr: slope, intercept + {0.10222808271646499634, 31.34789276123046875000}, //R: slope, intercept + }, + { //iso 3200 + {0.12651191651821136475, 49.56183242797851562500}, //B: slope, intercept + {0.10816962271928787231, 59.42719650268554687500}, //Gb: slope, intercept + {0.10751257836818695068, 59.90552902221679687500}, //Gr: slope, intercept + {0.13802853226661682129, 45.09576034545898437500}, //R: slope, intercept + }, + { //iso 6400 + {0.17422541975975036621, 70.04063415527343750000}, //B: slope, intercept + {0.14234761893749237061, 85.51583862304687500000}, //Gb: slope, intercept + {0.14159946143627166748, 86.23278045654296875000}, //Gr: slope, intercept + {0.19450971484184265137, 62.65447235107421875000}, //R: slope, intercept + }, + { //iso 12800 + {0.24947367608547210693, 108.30633544921875000000}, //B: slope, intercept + {0.19751225411891937256, 130.88159179687500000000}, //Gb: slope, intercept + {0.19614629447460174561, 132.49082946777343750000}, //Gr: slope, intercept + {0.28106108307838439941, 97.15969085693359375000}, //R: slope, intercept + }, + { //iso 25600 + {0.35420843958854675293, 137.06745910644531250000}, //B: slope, intercept + {0.27778801321983337402, 168.72366333007812500000}, //Gb: slope, intercept + {0.27540388703346252441, 170.54939270019531250000}, //Gr: slope, intercept + {0.39949953556060791016, 123.29409790039062500000}, //R: slope, intercept + }, + { //iso 51200 + {0.45704349875450134277, 179.20147705078125000000}, //B: slope, intercept + {0.32142028212547302246, 246.71363830566406250000}, //Gb: slope, intercept + {0.31958609819412231445, 246.82630920410156250000}, //Gr: slope, intercept + {0.51058447360992431641, 161.86299133300781250000}, //R: slope, intercept + }, + { //iso 102400 + {0.61760461330413818359, 222.90534973144531250000}, //B: slope, intercept + {0.42568457126617431641, 319.29257202148437500000}, //Gb: slope, intercept + {0.41750904917716979980, 324.93432617187500000000}, //Gr: slope, intercept + {0.67956107854843139648, 203.78948974609375000000}, //R: slope, intercept + }, + { //iso 204800 + {0.63289469480514526367, 216.99952697753906250000}, //B: slope, intercept + {0.44890350103378295898, 306.80810546875000000000}, //Gb: slope, intercept + {0.44229975342750549316, 310.13763427734375000000}, //Gr: slope, intercept + {0.69596910476684570313, 196.70443725585937500000}, //R: slope, intercept + }, + { //iso 409600 + {0.71106964349746704102, 187.98352050781250000000}, //B: slope, intercept + {0.55859673023223876953, 246.22378540039062500000}, //Gb: slope, intercept + {0.55284017324447631836, 249.86463928222656250000}, //Gr: slope, intercept + {0.77318203449249267578, 168.85035705566406250000}, //R: slope, intercept + }, + { //iso 819200 + {0.70888006687164306641, 188.44216918945312500000}, //B: slope, intercept + {0.56110274791717529297, 245.46603393554687500000}, //Gb: slope, intercept + {0.55100852251052856445, 250.33049011230468750000}, //Gr: slope, intercept + {0.76897650957107543945, 169.31251525878906250000}, //R: slope, intercept + }, + { //iso 1638400 + {0.70520979166030883789, 188.93899536132812500000}, //B: slope, intercept + {0.56178557872772216797, 245.21235656738281250000}, //Gb: slope, intercept + {0.55338454246520996094, 249.57423400878906250000}, //Gr: slope, intercept + {0.77306479215621948242, 168.86497497558593750000}, //R: slope, intercept + }, + { //iso 3276800 + {0.71255809068679809570, 187.86839294433593750000}, //B: slope, intercept + {0.56056070327758789063, 245.57748413085937500000}, //Gb: slope, intercept + {0.55358195304870605469, 249.62020874023437500000}, //Gr: slope, intercept + {0.77431541681289672852, 168.74313354492187500000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {257, 257, 257, 257, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {257, 257, 257, 257, 259, 259, 260, 267, 278, 298, 366, 383, 366, 373, 372, 372 }, + {257, 257, 257, 257, 258, 259, 261, 266, 274, 297, 379, 377, 372, 365, 373, 374 }, + {257, 257, 257, 257, 258, 259, 261, 266, 275, 296, 376, 388, 366, 374, 376, 372 }, + {257, 257, 257, 257, 258, 259, 260, 264, 274, 294, 362, 363, 365, 361, 353, 367 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1095, + 1099, 1104, 1125, 1130, 1125, 1127, 1126, 1126}, + {1093, 1093, 1093, 1093, 1093, 1093, 1094, 1095, + 1097, 1104, 1128, 1128, 1126, 1124, 1127, 1127}, + {1093, 1093, 1093, 1093, 1093, 1093, 1094, 1095, + 1098, 1104, 1128, 1131, 1125, 1127, 1128, 1126}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1095, + 1097, 1103, 1123, 1124, 1124, 1123, 1121, 1125}, +#endif + }, + }, +}; + +struct combo_dev_attr_s gc2053_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {1, 3, 2, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2053_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053/gc2053_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053/gc2053_sensor_ctl.c new file mode 100644 index 000000000..007ac86bf --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053/gc2053_sensor_ctl.c @@ -0,0 +1,395 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2053_cmos_ex.h" + +#define GC2053_CHIP_ID_ADDR_H 0xf0 +#define GC2053_CHIP_ID_ADDR_L 0xf1 +#define GC2053_CHIP_ID 0x2053 + +static void gc2053_linear_1080p30_init(VI_PIPE ViPipe); + +CVI_U8 gc2053_i2c_addr = 0x37;//0x6e +const CVI_U32 gc2053_addr_byte = 1; +const CVI_U32 gc2053_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc2053_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc2053_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc2053_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc2053_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc2053_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (gc2053_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc2053_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, gc2053_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc2053_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int gc2053_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc2053_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (gc2053_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc2053_addr_byte + gc2053_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + //syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void gc2053_standby(VI_PIPE ViPipe) +{ + gc2053_write_register(ViPipe, 0x3e, 0x00); + gc2053_write_register(ViPipe, 0xf7, 0x00); + gc2053_write_register(ViPipe, 0xfc, 0x01); + gc2053_write_register(ViPipe, 0xf9, 0x83); + + printf("gc2053_standby\n"); +} + +void gc2053_restart(VI_PIPE ViPipe) +{ + gc2053_write_register(ViPipe, 0xf9, 0x82); + delay_ms(2); + gc2053_write_register(ViPipe, 0xf7, 0x01); + gc2053_write_register(ViPipe, 0xfc, 0x8e); + gc2053_write_register(ViPipe, 0x3e, 0x91); + + printf("gc2053_restart\n"); +} + +void gc2053_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc2053[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc2053_write_register(ViPipe, + g_pastGc2053[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc2053[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} +void gc2053_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 value = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + value = 0x01; + break; + case ISP_SNS_FLIP: + value = 0x02; + break; + case ISP_SNS_MIRROR_FLIP: + value = 0x03; + break; + default: + return; + } + gc2053_write_register(ViPipe, 0xfe, 0x00); + gc2053_write_register(ViPipe, 0x17, value); +} + +int gc2053_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc2053_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc2053_read_register(ViPipe, GC2053_CHIP_ID_ADDR_H); + nVal2 = gc2053_read_register(ViPipe, GC2053_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC2053_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc2053_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode = g_pastGc2053[ViPipe]->enWDRMode; + + gc2053_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n"); + } else { + gc2053_linear_1080p30_init(ViPipe); + } + g_pastGc2053[ViPipe]->bInit = CVI_TRUE; +} + +void gc2053_exit(VI_PIPE ViPipe) +{ + gc2053_i2c_exit(ViPipe); +} + +static void gc2053_linear_1080p30_init(VI_PIPE ViPipe) +{ + /****system****/ + gc2053_write_register(ViPipe, 0xfe, 0x80); + gc2053_write_register(ViPipe, 0xfe, 0x80); + gc2053_write_register(ViPipe, 0xfe, 0x80); + gc2053_write_register(ViPipe, 0xfe, 0x00); + gc2053_write_register(ViPipe, 0xf2, 0x00); + gc2053_write_register(ViPipe, 0xf3, 0x00); + gc2053_write_register(ViPipe, 0xf4, 0x36); + gc2053_write_register(ViPipe, 0xf5, 0xc0); + gc2053_write_register(ViPipe, 0xf6, 0x44); + gc2053_write_register(ViPipe, 0xf7, 0x01); + gc2053_write_register(ViPipe, 0xf8, 0x2c); + gc2053_write_register(ViPipe, 0xf9, 0x42); + gc2053_write_register(ViPipe, 0xfc, 0x8e); + /****CISCTL & ANALOG****/ + gc2053_write_register(ViPipe, 0xfe, 0x00); + gc2053_write_register(ViPipe, 0x87, 0x18); + gc2053_write_register(ViPipe, 0xee, 0x30); + gc2053_write_register(ViPipe, 0xd0, 0xb7); + gc2053_write_register(ViPipe, 0x03, 0x04); + gc2053_write_register(ViPipe, 0x04, 0x60); + gc2053_write_register(ViPipe, 0x05, 0x04); + gc2053_write_register(ViPipe, 0x06, 0x4c); + gc2053_write_register(ViPipe, 0x07, 0x00); + gc2053_write_register(ViPipe, 0x08, 0x11); + gc2053_write_register(ViPipe, 0x09, 0x00); + gc2053_write_register(ViPipe, 0x0a, 0x02); + gc2053_write_register(ViPipe, 0x0b, 0x00); + gc2053_write_register(ViPipe, 0x0c, 0x02); + gc2053_write_register(ViPipe, 0x0d, 0x04); + gc2053_write_register(ViPipe, 0x0e, 0x40); + gc2053_write_register(ViPipe, 0x12, 0xe2); + gc2053_write_register(ViPipe, 0x13, 0x16); + gc2053_write_register(ViPipe, 0x19, 0x0a); + gc2053_write_register(ViPipe, 0x21, 0x1c); + gc2053_write_register(ViPipe, 0x28, 0x0a); + gc2053_write_register(ViPipe, 0x29, 0x24); + gc2053_write_register(ViPipe, 0x2b, 0x04); + gc2053_write_register(ViPipe, 0x32, 0xf8); + gc2053_write_register(ViPipe, 0x37, 0x03); + gc2053_write_register(ViPipe, 0x39, 0x15); + gc2053_write_register(ViPipe, 0x41, 0x04); + gc2053_write_register(ViPipe, 0x42, 0x65); + gc2053_write_register(ViPipe, 0x43, 0x07); + gc2053_write_register(ViPipe, 0x44, 0x40); + gc2053_write_register(ViPipe, 0x46, 0x0b); + gc2053_write_register(ViPipe, 0x4b, 0x20); + gc2053_write_register(ViPipe, 0x4e, 0x08); + gc2053_write_register(ViPipe, 0x55, 0x20); + gc2053_write_register(ViPipe, 0x66, 0x05); + gc2053_write_register(ViPipe, 0x67, 0x05); + gc2053_write_register(ViPipe, 0x77, 0x01); + gc2053_write_register(ViPipe, 0x78, 0x00); + gc2053_write_register(ViPipe, 0x7c, 0x93); + gc2053_write_register(ViPipe, 0x8c, 0x12); + gc2053_write_register(ViPipe, 0x8d, 0x92); + gc2053_write_register(ViPipe, 0x90, 0x00); + gc2053_write_register(ViPipe, 0x9d, 0x10); + gc2053_write_register(ViPipe, 0xce, 0x7c); + gc2053_write_register(ViPipe, 0xd2, 0x41); + gc2053_write_register(ViPipe, 0xd3, 0xdc); + gc2053_write_register(ViPipe, 0xe6, 0x50); + /*gain*/ + gc2053_write_register(ViPipe, 0xb6, 0xc0); + gc2053_write_register(ViPipe, 0xb0, 0x70); + gc2053_write_register(ViPipe, 0xb1, 0x01); + gc2053_write_register(ViPipe, 0xb2, 0x00); + gc2053_write_register(ViPipe, 0xb3, 0x00); + gc2053_write_register(ViPipe, 0xb4, 0x00); + gc2053_write_register(ViPipe, 0xb8, 0x01); + gc2053_write_register(ViPipe, 0xb9, 0x00); + /*blk*/ + gc2053_write_register(ViPipe, 0x26, 0x30); + gc2053_write_register(ViPipe, 0xfe, 0x01); + gc2053_write_register(ViPipe, 0x40, 0x23); + gc2053_write_register(ViPipe, 0x55, 0x07); + gc2053_write_register(ViPipe, 0x60, 0x40); + gc2053_write_register(ViPipe, 0xfe, 0x04); + gc2053_write_register(ViPipe, 0x14, 0x78); + gc2053_write_register(ViPipe, 0x15, 0x78); + gc2053_write_register(ViPipe, 0x16, 0x78); + gc2053_write_register(ViPipe, 0x17, 0x78); + /*window*/ + gc2053_write_register(ViPipe, 0xfe, 0x01); + gc2053_write_register(ViPipe, 0x91, 0x00); + gc2053_write_register(ViPipe, 0x92, 0x00); + gc2053_write_register(ViPipe, 0x93, 0x00); + gc2053_write_register(ViPipe, 0x94, 0x03); + gc2053_write_register(ViPipe, 0x95, 0x04); + gc2053_write_register(ViPipe, 0x96, 0x38); + gc2053_write_register(ViPipe, 0x97, 0x07); + gc2053_write_register(ViPipe, 0x98, 0x80); + /*ISP*/ + gc2053_write_register(ViPipe, 0xfe, 0x01); + gc2053_write_register(ViPipe, 0x01, 0x05); + gc2053_write_register(ViPipe, 0x02, 0x89); + gc2053_write_register(ViPipe, 0x04, 0x01); + gc2053_write_register(ViPipe, 0x07, 0xa6); + gc2053_write_register(ViPipe, 0x08, 0xa9); + gc2053_write_register(ViPipe, 0x09, 0xa8); + gc2053_write_register(ViPipe, 0x0a, 0xa7); + gc2053_write_register(ViPipe, 0x0b, 0xff); + gc2053_write_register(ViPipe, 0x0c, 0xff); + gc2053_write_register(ViPipe, 0x0f, 0x00); + gc2053_write_register(ViPipe, 0x50, 0x1c); + gc2053_write_register(ViPipe, 0x89, 0x03); + gc2053_write_register(ViPipe, 0xfe, 0x04); + gc2053_write_register(ViPipe, 0x28, 0x86); + gc2053_write_register(ViPipe, 0x29, 0x86); + gc2053_write_register(ViPipe, 0x2a, 0x86); + gc2053_write_register(ViPipe, 0x2b, 0x68); + gc2053_write_register(ViPipe, 0x2c, 0x68); + gc2053_write_register(ViPipe, 0x2d, 0x68); + gc2053_write_register(ViPipe, 0x2e, 0x68); + gc2053_write_register(ViPipe, 0x2f, 0x68); + gc2053_write_register(ViPipe, 0x30, 0x4f); + gc2053_write_register(ViPipe, 0x31, 0x68); + gc2053_write_register(ViPipe, 0x32, 0x67); + gc2053_write_register(ViPipe, 0x33, 0x66); + gc2053_write_register(ViPipe, 0x34, 0x66); + gc2053_write_register(ViPipe, 0x35, 0x66); + gc2053_write_register(ViPipe, 0x36, 0x66); + gc2053_write_register(ViPipe, 0x37, 0x66); + gc2053_write_register(ViPipe, 0x38, 0x62); + gc2053_write_register(ViPipe, 0x39, 0x62); + gc2053_write_register(ViPipe, 0x3a, 0x62); + gc2053_write_register(ViPipe, 0x3b, 0x62); + gc2053_write_register(ViPipe, 0x3c, 0x62); + gc2053_write_register(ViPipe, 0x3d, 0x62); + gc2053_write_register(ViPipe, 0x3e, 0x62); + gc2053_write_register(ViPipe, 0x3f, 0x62); + /****DVP & MIPI****/ + gc2053_write_register(ViPipe, 0xfe, 0x01); + gc2053_write_register(ViPipe, 0x9a, 0x06); + gc2053_write_register(ViPipe, 0xfe, 0x00); + gc2053_write_register(ViPipe, 0x7b, 0x2a); + gc2053_write_register(ViPipe, 0x23, 0x2d); + gc2053_write_register(ViPipe, 0xfe, 0x03); + gc2053_write_register(ViPipe, 0x01, 0x27); + gc2053_write_register(ViPipe, 0x02, 0x56); + gc2053_write_register(ViPipe, 0x03, 0x8e); + gc2053_write_register(ViPipe, 0x12, 0x80); + gc2053_write_register(ViPipe, 0x13, 0x07); + gc2053_write_register(ViPipe, 0x15, 0x12); + gc2053_write_register(ViPipe, 0xfe, 0x00); + gc2053_write_register(ViPipe, 0x3e, 0x91); + + gc2053_default_reg_init(ViPipe); + printf("ViPipe:%d,===GC2053 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_1L/Makefile b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_1L/Makefile new file mode 100644 index 000000000..64bd2a954 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_1L/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc2053_1l.a +TARGET_SO = $(MW_LIB)/libsns_gc2053_1l.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_1L/gc2053_1l_cmos.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_1L/gc2053_1l_cmos.c new file mode 100644 index 000000000..265a2a4ea --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_1L/gc2053_1l_cmos.c @@ -0,0 +1,969 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "gc2053_1l_cmos_ex.h" +#include "gc2053_1l_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define GC2053_1L_ID 2053 +#define GC2053_1L_I2C_ADDR_1 0x3f +#define GC2053_1L_I2C_ADDR_2 0x37 +#define GC2053_1L_I2C_ADDR_IS_VALID(addr) ((addr) == GC2053_1L_I2C_ADDR_1 || (addr) == GC2053_1L_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc2053_1l[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC2053_1L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc2053_1l[dev]) +#define GC2053_1L_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc2053_1l[dev] = pstCtx) +#define GC2053_1L_SENSOR_RESET_CTX(dev) (g_pastGc2053_1l[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc2053_1l_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +GC2053_1L_STATE_S g_astGc2053_1l_State[VI_MAX_PIPE_NUM] = { {0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2053_1l_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16Gc2053_1l_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Gc2053_1l_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Gc2053_1l Lines Range*****/ +#define GC2053_1L_FULL_LINES_MAX (0x3fff) + +/*****Gc2053_1l Register Address*****/ +#define GC2053_1L_EXP_H_ADDR 0x03 +#define GC2053_1L_EXP_L_ADDR 0x04 +#define GC2053_1L_AGAIN_H_ADDR 0xb4 +#define GC2053_1L_AGAIN_L_ADDR 0xb3 +#define GC2053_1L_COL_AGAIN_H_ADDR 0xb8 +#define GC2053_1L_COL_AGAIN_L_ADDR 0xb9 +#define GC2053_1L_DGAIN_H_ADDR 0xb1 +#define GC2053_1L_DGAIN_L_ADDR 0xb2 +#define GC2053_1L_VTS_H_ADDR 0x41 //(frame length) +#define GC2053_1L_VTS_L_ADDR 0x42 + +#define GC2053_1L_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const GC2053_1L_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc2053_1l_mode; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC2053_1L_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 3985*16; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 10240; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : + pstMode->stExp.u16Def; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp.u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp.u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = 0; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_stGc2053_1l_mode.u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_stGc2053_1l_mode.f32MaxFps; + f32MinFps = g_stGc2053_1l_mode.f32MinFps; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > GC2053_1L_FULL_LINES_MAX) ? GC2053_1L_FULL_LINES_MAX : u32VMAX; + + pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF); + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_U32 regValTable[25][4] = { + {0x00, 0x00, 0x01, 0x00}, + {0x00, 0x10, 0x01, 0x0c}, + {0x00, 0x20, 0x01, 0x1b}, + {0x00, 0x30, 0x01, 0x2c}, + {0x00, 0x40, 0x01, 0x3f}, + {0x00, 0x50, 0x02, 0x16}, + {0x00, 0x60, 0x02, 0x35}, + {0x00, 0x70, 0x03, 0x16}, + {0x00, 0x80, 0x04, 0x02}, + {0x00, 0x90, 0x04, 0x31}, + {0x00, 0xa0, 0x05, 0x32}, + {0x00, 0xb0, 0x06, 0x35}, + {0x00, 0xc0, 0x08, 0x04}, + {0x00, 0x5a, 0x09, 0x19}, + {0x00, 0x83, 0x0b, 0x0f}, + {0x00, 0x93, 0x0d, 0x12}, + {0x00, 0x84, 0x10, 0x00}, + {0x00, 0x94, 0x12, 0x3a}, + {0x01, 0x2c, 0x1a, 0x02}, + {0x01, 0x3c, 0x1b, 0x20}, + {0x00, 0x8c, 0x20, 0x0f}, + {0x00, 0x9c, 0x26, 0x07}, + {0x02, 0x64, 0x36, 0x21}, + {0x02, 0x74, 0x37, 0x3a}, + {0x00, 0xc6, 0x3d, 0x02}, + /* + {0x00, 0xdc, 0x3f, 0x3f}, + {0x02, 0x85, 0x3f, 0x3f}, + {0x02, 0x95, 0x3f, 0x3f}, + {0x00, 0xce, 0x3f, 0x3f}, + */ +}; + +static CVI_U32 gain_table[25] = { + 64*16, 76*16, 90*16, 108*16, 127*16, 148*16, 180*16, 216*16, 255*16, 300*16, + 361*16, 422*16, 504*16, 593*16, 722*16, 850*16, 1008*16, 1182*16, 1408*16, 1689*16, + 2021*16, 2391*16, 2850*16, 3369*16, 3985*16,/* 4805*16, 5768*16, 6806*16, 7723*16,*/ +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i, total; + CVI_U32 pregain; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + total = sizeof(gain_table) / sizeof(CVI_U32); + + if (*pu32AgainLin >= gain_table[total - 1]) { + *pu32AgainLin = *pu32AgainDb = gain_table[total - 1]; + return CVI_SUCCESS; + } + + for (i = 1; i < total; i++) { + if (*pu32AgainLin < gain_table[i]) + break; + } + i--; + // find the pregain + pregain = *pu32AgainLin * 64 / gain_table[i]; + // set the Db as the AE algo gain, we need this to do gain update + *pu32AgainDb = *pu32AgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32AgainLin = pregain * gain_table[i] / 64; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 pregain; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + // find the pregain + pregain = *pu32DgainLin * 64 / 1024; + // set the Db as the AE algo gain, we need this to do gain update + *pu32DgainDb = *pu32DgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32DgainLin = pregain * 16; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + int i, total; + + total = sizeof(gain_table) / sizeof(CVI_U32); + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* only surpport linear mode */ + u32Again = pu32Again[0]; + /* To kepp the linearity. we assume AE algo adjusts the dgain only when the again reachs the maximum value */ + if (u32Again < (3985*16)) { + for (i = 1; i < total; i++) { + if (*pu32Again < gain_table[i]) + break; + } + i--; + // find the pregain + u32Dgain = u32Again * 64 / gain_table[i]; + u32Again = i; + } else { + u32Again = total - 1; + // find the pregain + u32Dgain = pu32Dgain[0] * 64 / 1024; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][0]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][1]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][2]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][3]; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 6); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + UNUSED(ViPipe); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 8 : 8; + /* + * Long exp + Short exp < VTS - 4 + * max l2s distance = FL - boundary - active_h - 4 + * max sexp = max l2s distance - (L2S offset + 1) * 2 + */ + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 4) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + + u32IntTimeMaxTmp = (g_astGc2053_1l_State[ViPipe].u32Sexp_MAX < u32IntTimeMaxTmp) ? + g_astGc2053_1l_State[ViPipe].u32Sexp_MAX : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + syslog(LOG_DEBUG, "Max inttime0 = %u\n", u32IntTimeMaxTmp); + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio is too large!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + UNUSED(ViPipe); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + UNUSED(ViPipe); + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + CMOS_CHECK_POINTER(pstBlc); + UNUSED(ViPipe); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC2053_1L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc2053_1l_mode; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->stImg, sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = GC2053_1L_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc2053_1l_mode.u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunGc2053_1l_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = gc2053_1l_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc2053_1l_addr_byte; + pstI2c_data[i].u32DataByteNum = gc2053_1l_data_byte; + } + + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC2053_1L_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC2053_1L_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC2053_1L_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC2053_1L_AGAIN_L_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC2053_1L_COL_AGAIN_H_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC2053_1L_COL_AGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC2053_1L_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC2053_1L_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC2053_1L_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC2053_1L_VTS_L_ADDR; + + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + + CVI_U32 gainsUpdate = 0; + + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + + if ((i >= LINEAR_AGAIN_H) && (i <= LINEAR_DGAIN_L)) + gainsUpdate = 1; + + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (gainsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L].bUpdate = CVI_TRUE; + } + + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC2053_1L_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC2053_1L_MODE_1920X1080P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc2053_1l_MirrorFip[ViPipe] != eSnsMirrorFlip) { + gc2053_1l_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeGc2053_1l_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC2053_1L_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc2053_1l_mode.u32VtsDef; + pstSnsState->au32FL[0] = g_stGc2053_1l_mode.u32VtsDef; + pstSnsState->au32FL[1] = g_stGc2053_1l_mode.u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc2053_1l_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_stGc2053_1l_mode.stImg.stSnsSize.u32Width; + pstRxAttr->img_size.height = g_stGc2053_1l_mode.stImg.stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc2053_1l_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc2053_1l_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc2053_1l_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (GC2053_1L_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc2053_1l_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc2053_1l_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc2053_1l_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC2053_1L_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC2053_1L_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC2053_1L_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC2053_1L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC2053_1L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC2053_1L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Gc2053_1l_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Gc2053_1l_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc2053_1l_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc2053_1l_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc2053_1l_standby, + .pfnRestart = gc2053_1l_restart, + .pfnWriteReg = gc2053_1l_write_register, + .pfnReadReg = gc2053_1l_read_register, + .pfnSetBusInfo = gc2053_1l_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_1L/gc2053_1l_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_1L/gc2053_1l_cmos_ex.h new file mode 100644 index 000000000..bbabb3598 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_1L/gc2053_1l_cmos_ex.h @@ -0,0 +1,88 @@ +#ifndef __GC2053_1L_CMOS_EX_H_ +#define __GC2053_1L_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum gc2053_1l_linear_regs_e { + LINEAR_EXP_H = 0,//03 + LINEAR_EXP_L, //04 + LINEAR_AGAIN_H, //b4 + LINEAR_AGAIN_L, //b3 + LINEAR_COL_AGAIN_H, //b8 + LINEAR_COL_AGAIN_L, //b9 + LINEAR_DGAIN_H, //b1 + LINEAR_DGAIN_L, //b2 + LINEAR_VTS_H, //0x41 (frame length) + LINEAR_VTS_L,//0x42 + LINEAR_REGS_NUM +}; + + +typedef enum _GC2053_1L_MODE_E { + GC2053_1L_MODE_1920X1080P30 = 0, + GC2053_1L_MODE_NUM +} GC2053_1L_SLAVE_MODE_E; + +typedef struct _GC2053_1L_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC2053_1L_STATE_S; + +typedef struct _GC2053_1L_MODE_S { + ISP_WDR_SIZE_S stImg; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp; + SNS_ATTR_LARGE_S stAgain; + SNS_ATTR_LARGE_S stDgain; + char name[64]; +} GC2053_1L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc2053_1l[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc2053_1l_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2053_1l_MirrorFip[VI_MAX_PIPE_NUM]; +extern CVI_U8 gc2053_1l_i2c_addr; +extern const CVI_U32 gc2053_1l_addr_byte; +extern const CVI_U32 gc2053_1l_data_byte; +extern void gc2053_1l_init(VI_PIPE ViPipe); +extern void gc2053_1l_exit(VI_PIPE ViPipe); +extern void gc2053_1l_standby(VI_PIPE ViPipe); +extern void gc2053_1l_restart(VI_PIPE ViPipe); +extern int gc2053_1l_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc2053_1l_read_register(VI_PIPE ViPipe, int addr); +extern void gc2053_1l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int gc2053_1l_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2053_1L_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_1L/gc2053_1l_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_1L/gc2053_1l_cmos_param.h new file mode 100644 index 000000000..9eece0767 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_1L/gc2053_1l_cmos_param.h @@ -0,0 +1,223 @@ +#ifndef __GC2053_1L_CMOS_PARAM_H_ +#define __GC2053_1L_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2053_1l_cmos_ex.h" + +static const GC2053_1L_MODE_S g_stGc2053_1l_mode = { + .name = "1920X1080P30", + .stImg = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.07, /* 1125 * 30 / 0x3FFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp = { + .u16Min = 1, + .u16Max = 0x3fff, + .u16Def = 0x2000, + .u16Step = 1, + }, + .stAgain = { + .u32Min = 64, + .u32Max = 62977, + .u32Def = 64, + .u32Step = 1, + }, + .stDgain = { + .u32Min = 64*16, + .u32Max = 7073*16, + .u32Def = 581*16, + .u32Step = 10*16, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.05999477580189704895, 0.13019448518753051758}, //B: slope, intercept + {0.06732148677110671997, -1.36387133598327636719}, //Gb: slope, intercept + {0.06651904433965682983, -1.10093510150909423828}, //Gr: slope, intercept + {0.06406146287918090820, 0.33316791057586669922}, //R: slope, intercept + }, + { //iso 200 + {0.06256803125143051147, 4.54908418655395507813}, //B: slope, intercept + {0.06911934912204742432, 2.79023528099060058594}, //Gb: slope, intercept + {0.06846688687801361084, 2.88726186752319335938}, //Gr: slope, intercept + {0.06652788817882537842, 4.40276956558227539063}, //R: slope, intercept + }, + { //iso 400 + {0.06841833144426345825, 11.72280883789062500000}, //B: slope, intercept + {0.07257881015539169312, 10.86985683441162109375}, //Gb: slope, intercept + {0.07174283266067504883, 11.20646286010742187500}, //Gr: slope, intercept + {0.07294593751430511475, 11.17350578308105468750}, //R: slope, intercept + }, + { //iso 800 + {0.07805790752172470093, 20.62956619262695312500}, //B: slope, intercept + {0.07694032043218612671, 22.20356750488281250000}, //Gb: slope, intercept + {0.07647507637739181519, 22.50957298278808593750}, //Gr: slope, intercept + {0.08402533829212188721, 19.11953735351562500000}, //R: slope, intercept + }, + { //iso 1600 + {0.09468275308609008789, 34.07563018798828125000}, //B: slope, intercept + {0.08710632473230361938, 39.15500259399414062500}, //Gb: slope, intercept + {0.08662072569131851196, 39.37175750732421875000}, //Gr: slope, intercept + {0.10222808271646499634, 31.34789276123046875000}, //R: slope, intercept + }, + { //iso 3200 + {0.12651191651821136475, 49.56183242797851562500}, //B: slope, intercept + {0.10816962271928787231, 59.42719650268554687500}, //Gb: slope, intercept + {0.10751257836818695068, 59.90552902221679687500}, //Gr: slope, intercept + {0.13802853226661682129, 45.09576034545898437500}, //R: slope, intercept + }, + { //iso 6400 + {0.17422541975975036621, 70.04063415527343750000}, //B: slope, intercept + {0.14234761893749237061, 85.51583862304687500000}, //Gb: slope, intercept + {0.14159946143627166748, 86.23278045654296875000}, //Gr: slope, intercept + {0.19450971484184265137, 62.65447235107421875000}, //R: slope, intercept + }, + { //iso 12800 + {0.24947367608547210693, 108.30633544921875000000}, //B: slope, intercept + {0.19751225411891937256, 130.88159179687500000000}, //Gb: slope, intercept + {0.19614629447460174561, 132.49082946777343750000}, //Gr: slope, intercept + {0.28106108307838439941, 97.15969085693359375000}, //R: slope, intercept + }, + { //iso 25600 + {0.35420843958854675293, 137.06745910644531250000}, //B: slope, intercept + {0.27778801321983337402, 168.72366333007812500000}, //Gb: slope, intercept + {0.27540388703346252441, 170.54939270019531250000}, //Gr: slope, intercept + {0.39949953556060791016, 123.29409790039062500000}, //R: slope, intercept + }, + { //iso 51200 + {0.45704349875450134277, 179.20147705078125000000}, //B: slope, intercept + {0.32142028212547302246, 246.71363830566406250000}, //Gb: slope, intercept + {0.31958609819412231445, 246.82630920410156250000}, //Gr: slope, intercept + {0.51058447360992431641, 161.86299133300781250000}, //R: slope, intercept + }, + { //iso 102400 + {0.61760461330413818359, 222.90534973144531250000}, //B: slope, intercept + {0.42568457126617431641, 319.29257202148437500000}, //Gb: slope, intercept + {0.41750904917716979980, 324.93432617187500000000}, //Gr: slope, intercept + {0.67956107854843139648, 203.78948974609375000000}, //R: slope, intercept + }, + { //iso 204800 + {0.63289469480514526367, 216.99952697753906250000}, //B: slope, intercept + {0.44890350103378295898, 306.80810546875000000000}, //Gb: slope, intercept + {0.44229975342750549316, 310.13763427734375000000}, //Gr: slope, intercept + {0.69596910476684570313, 196.70443725585937500000}, //R: slope, intercept + }, + { //iso 409600 + {0.71106964349746704102, 187.98352050781250000000}, //B: slope, intercept + {0.55859673023223876953, 246.22378540039062500000}, //Gb: slope, intercept + {0.55284017324447631836, 249.86463928222656250000}, //Gr: slope, intercept + {0.77318203449249267578, 168.85035705566406250000}, //R: slope, intercept + }, + { //iso 819200 + {0.70888006687164306641, 188.44216918945312500000}, //B: slope, intercept + {0.56110274791717529297, 245.46603393554687500000}, //Gb: slope, intercept + {0.55100852251052856445, 250.33049011230468750000}, //Gr: slope, intercept + {0.76897650957107543945, 169.31251525878906250000}, //R: slope, intercept + }, + { //iso 1638400 + {0.70520979166030883789, 188.93899536132812500000}, //B: slope, intercept + {0.56178557872772216797, 245.21235656738281250000}, //Gb: slope, intercept + {0.55338454246520996094, 249.57423400878906250000}, //Gr: slope, intercept + {0.77306479215621948242, 168.86497497558593750000}, //R: slope, intercept + }, + { //iso 3276800 + {0.71255809068679809570, 187.86839294433593750000}, //B: slope, intercept + {0.56056070327758789063, 245.57748413085937500000}, //Gb: slope, intercept + {0.55358195304870605469, 249.62020874023437500000}, //Gr: slope, intercept + {0.77431541681289672852, 168.74313354492187500000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {257, 257, 257, 257, 0, 0, 0 +#ifdef ARCH_CV182X + , 0, 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {257, 257, 257, 257, 259, 259, 260, 267, 278, 298, 366, 383, 366, 373, 372, 372 }, + {257, 257, 257, 257, 258, 259, 261, 266, 274, 297, 379, 377, 372, 365, 373, 374 }, + {257, 257, 257, 257, 258, 259, 261, 266, 275, 296, 376, 388, 366, 374, 376, 372 }, + {257, 257, 257, 257, 258, 259, 260, 264, 274, 294, 362, 363, 365, 361, 353, 367 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1095, + 1099, 1104, 1125, 1130, 1125, 1127, 1126, 1126}, + {1093, 1093, 1093, 1093, 1093, 1093, 1094, 1095, + 1097, 1104, 1128, 1128, 1126, 1124, 1127, 1127}, + {1093, 1093, 1093, 1093, 1093, 1093, 1094, 1095, + 1098, 1104, 1128, 1131, 1125, 1127, 1128, 1126}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1095, + 1097, 1103, 1123, 1124, 1124, 1123, 1121, 1125}, +#endif + }, + }, +}; + +struct combo_dev_attr_s gc2053_1l_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {3, 4, -1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 31, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 1, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2053_1L_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_1L/gc2053_1l_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_1L/gc2053_1l_sensor_ctl.c new file mode 100644 index 000000000..328bb8320 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_1L/gc2053_1l_sensor_ctl.c @@ -0,0 +1,398 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2053_1l_cmos_ex.h" + +#define GC2053_1L_CHIP_ID_ADDR_H 0xf0 +#define GC2053_1L_CHIP_ID_ADDR_L 0xf1 +#define GC2053_1L_CHIP_ID 0x2053 + +static void gc2053_1l_linear_1080p30_init(VI_PIPE ViPipe); + +CVI_U8 gc2053_1l_i2c_addr = 0x3f;//0x7e +const CVI_U32 gc2053_1l_addr_byte = 1; +const CVI_U32 gc2053_1l_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc2053_1l_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc2053_1l_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc2053_1l_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc2053_1l_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc2053_1l_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (gc2053_1l_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc2053_1l_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, gc2053_1l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc2053_1l_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int gc2053_1l_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc2053_1l_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (gc2053_1l_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc2053_1l_addr_byte + gc2053_1l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + ret = read(g_fd[ViPipe], buf, gc2053_1l_addr_byte + gc2053_1l_data_byte); + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void gc2053_1l_standby(VI_PIPE ViPipe) +{ + gc2053_1l_write_register(ViPipe, 0x3e, 0x00); + gc2053_1l_write_register(ViPipe, 0xf7, 0x00); + gc2053_1l_write_register(ViPipe, 0xfc, 0x01); + gc2053_1l_write_register(ViPipe, 0xf9, 0x83); + + printf("gc2053_1l_standby\n"); +} + +void gc2053_1l_restart(VI_PIPE ViPipe) +{ + gc2053_1l_write_register(ViPipe, 0xf9, 0x82); + delay_ms(2); + gc2053_1l_write_register(ViPipe, 0xf7, 0x01); + gc2053_1l_write_register(ViPipe, 0xfc, 0x8e); + gc2053_1l_write_register(ViPipe, 0x3e, 0x90); + + printf("gc2053_1l_restart\n"); +} + +void gc2053_1l_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc2053_1l[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc2053_1l_write_register(ViPipe, + g_pastGc2053_1l[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc2053_1l[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} +void gc2053_1l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 value = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + value = 0x01; + break; + case ISP_SNS_FLIP: + value = 0x02; + break; + case ISP_SNS_MIRROR_FLIP: + value = 0x03; + break; + default: + return; + } + gc2053_1l_write_register(ViPipe, 0xfe, 0x00); + gc2053_1l_write_register(ViPipe, 0x17, value); +} + +int gc2053_1l_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc2053_1l_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc2053_1l_read_register(ViPipe, GC2053_1L_CHIP_ID_ADDR_H); + nVal2 = gc2053_1l_read_register(ViPipe, GC2053_1L_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC2053_1L_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc2053_1l_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode = g_pastGc2053_1l[ViPipe]->enWDRMode; + + gc2053_1l_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n"); + } else { + gc2053_1l_linear_1080p30_init(ViPipe); + } + g_pastGc2053_1l[ViPipe]->bInit = CVI_TRUE; +} + +void gc2053_1l_exit(VI_PIPE ViPipe) +{ + gc2053_1l_i2c_exit(ViPipe); +} + +static void gc2053_1l_linear_1080p30_init(VI_PIPE ViPipe) +{ + /****system****/ + gc2053_1l_write_register(ViPipe, 0xfe, 0x80); + gc2053_1l_write_register(ViPipe, 0xfe, 0x80); + gc2053_1l_write_register(ViPipe, 0xfe, 0x80); + gc2053_1l_write_register(ViPipe, 0xfe, 0x00); + gc2053_1l_write_register(ViPipe, 0xf2, 0x00); + gc2053_1l_write_register(ViPipe, 0xf3, 0x00); + gc2053_1l_write_register(ViPipe, 0xf4, 0x36); + gc2053_1l_write_register(ViPipe, 0xf5, 0xc0); + gc2053_1l_write_register(ViPipe, 0xf6, 0x82); + gc2053_1l_write_register(ViPipe, 0xf7, 0x01); + gc2053_1l_write_register(ViPipe, 0xf8, 0x20); + gc2053_1l_write_register(ViPipe, 0xf9, 0x82); + gc2053_1l_write_register(ViPipe, 0xfc, 0x8e); + /****CISCTL & ANALOG****/ + gc2053_1l_write_register(ViPipe, 0xfe, 0x00); + gc2053_1l_write_register(ViPipe, 0x87, 0x18); + gc2053_1l_write_register(ViPipe, 0xee, 0x30); + gc2053_1l_write_register(ViPipe, 0xd0, 0xb7); + gc2053_1l_write_register(ViPipe, 0x03, 0x04); + gc2053_1l_write_register(ViPipe, 0x04, 0x10); + gc2053_1l_write_register(ViPipe, 0x05, 0x05);//05 + gc2053_1l_write_register(ViPipe, 0x06, 0x00);//60//[11:0]hb + gc2053_1l_write_register(ViPipe, 0x07, 0x00); + gc2053_1l_write_register(ViPipe, 0x08, 0x19); + gc2053_1l_write_register(ViPipe, 0x09, 0x00); + gc2053_1l_write_register(ViPipe, 0x0a, 0x02); //cisctl row start + gc2053_1l_write_register(ViPipe, 0x0b, 0x00); + gc2053_1l_write_register(ViPipe, 0x0c, 0x02); //cisctl col start + gc2053_1l_write_register(ViPipe, 0x0d, 0x04); + gc2053_1l_write_register(ViPipe, 0x0e, 0x40); + gc2053_1l_write_register(ViPipe, 0x12, 0xe2); + gc2053_1l_write_register(ViPipe, 0x13, 0x16); + gc2053_1l_write_register(ViPipe, 0x19, 0x0a); + gc2053_1l_write_register(ViPipe, 0x21, 0x1c); + gc2053_1l_write_register(ViPipe, 0x28, 0x0a); + gc2053_1l_write_register(ViPipe, 0x29, 0x24); + gc2053_1l_write_register(ViPipe, 0x2b, 0x04); + gc2053_1l_write_register(ViPipe, 0x32, 0xf8); + gc2053_1l_write_register(ViPipe, 0x37, 0x03); + gc2053_1l_write_register(ViPipe, 0x39, 0x15); + gc2053_1l_write_register(ViPipe, 0x41, 0x04); + gc2053_1l_write_register(ViPipe, 0x42, 0x65); + gc2053_1l_write_register(ViPipe, 0x43, 0x07); + gc2053_1l_write_register(ViPipe, 0x44, 0x40); + gc2053_1l_write_register(ViPipe, 0x46, 0x0b); + gc2053_1l_write_register(ViPipe, 0x4b, 0x20); + gc2053_1l_write_register(ViPipe, 0x4e, 0x08); + gc2053_1l_write_register(ViPipe, 0x55, 0x20); + gc2053_1l_write_register(ViPipe, 0x66, 0x05); + gc2053_1l_write_register(ViPipe, 0x67, 0x05); + gc2053_1l_write_register(ViPipe, 0x77, 0x01); + gc2053_1l_write_register(ViPipe, 0x78, 0x00); + gc2053_1l_write_register(ViPipe, 0x7c, 0x93); + gc2053_1l_write_register(ViPipe, 0x8c, 0x12); + gc2053_1l_write_register(ViPipe, 0x8d, 0x92); + gc2053_1l_write_register(ViPipe, 0x90, 0x00); + gc2053_1l_write_register(ViPipe, 0x9d, 0x10); + gc2053_1l_write_register(ViPipe, 0xce, 0x7c); + gc2053_1l_write_register(ViPipe, 0xd2, 0x41); + gc2053_1l_write_register(ViPipe, 0xd3, 0xdc); + gc2053_1l_write_register(ViPipe, 0xda, 0x05); + gc2053_1l_write_register(ViPipe, 0xdb, 0x00); + gc2053_1l_write_register(ViPipe, 0xe6, 0x50); + /*gain*/ + gc2053_1l_write_register(ViPipe, 0xb6, 0xc0); + gc2053_1l_write_register(ViPipe, 0xb0, 0x70); + gc2053_1l_write_register(ViPipe, 0xb1, 0x01); + gc2053_1l_write_register(ViPipe, 0xb2, 0x00); + gc2053_1l_write_register(ViPipe, 0xb3, 0x00); + gc2053_1l_write_register(ViPipe, 0xb4, 0x00); + gc2053_1l_write_register(ViPipe, 0xb8, 0x01); + gc2053_1l_write_register(ViPipe, 0xb9, 0x00); + /*blk*/ + gc2053_1l_write_register(ViPipe, 0x26, 0x30); + gc2053_1l_write_register(ViPipe, 0xfe, 0x01); + gc2053_1l_write_register(ViPipe, 0x40, 0x23); + gc2053_1l_write_register(ViPipe, 0x55, 0x07); + gc2053_1l_write_register(ViPipe, 0x60, 0x40); //[7:0]WB_offset + gc2053_1l_write_register(ViPipe, 0xfe, 0x04); + gc2053_1l_write_register(ViPipe, 0x14, 0x78); + gc2053_1l_write_register(ViPipe, 0x15, 0x78); + gc2053_1l_write_register(ViPipe, 0x16, 0x78); + gc2053_1l_write_register(ViPipe, 0x17, 0x78); + /*window*/ + gc2053_1l_write_register(ViPipe, 0xfe, 0x01); + gc2053_1l_write_register(ViPipe, 0x92, 0x00); //win y1 + gc2053_1l_write_register(ViPipe, 0x94, 0x03); //win x1 + gc2053_1l_write_register(ViPipe, 0x95, 0x04); + gc2053_1l_write_register(ViPipe, 0x96, 0x38); //[10:0]out_height + gc2053_1l_write_register(ViPipe, 0x97, 0x07); + gc2053_1l_write_register(ViPipe, 0x98, 0x80); //[11:0]out_width + /*ISP*/ + gc2053_1l_write_register(ViPipe, 0xfe, 0x01); + gc2053_1l_write_register(ViPipe, 0x01, 0x05); + gc2053_1l_write_register(ViPipe, 0x02, 0x89); + gc2053_1l_write_register(ViPipe, 0x04, 0x01); //[0]DD_en + gc2053_1l_write_register(ViPipe, 0x07, 0xa6); + gc2053_1l_write_register(ViPipe, 0x08, 0xa9); + gc2053_1l_write_register(ViPipe, 0x09, 0xa8); + gc2053_1l_write_register(ViPipe, 0x0a, 0xa7); + gc2053_1l_write_register(ViPipe, 0x0b, 0xff); + gc2053_1l_write_register(ViPipe, 0x0c, 0xff); + gc2053_1l_write_register(ViPipe, 0x0f, 0x00); + gc2053_1l_write_register(ViPipe, 0x50, 0x1c); + gc2053_1l_write_register(ViPipe, 0x89, 0x03); + gc2053_1l_write_register(ViPipe, 0xfe, 0x04); + gc2053_1l_write_register(ViPipe, 0x28, 0x86);//84 + gc2053_1l_write_register(ViPipe, 0x29, 0x86);//84 + gc2053_1l_write_register(ViPipe, 0x2a, 0x86);//84 + gc2053_1l_write_register(ViPipe, 0x2b, 0x68);//84 + gc2053_1l_write_register(ViPipe, 0x2c, 0x68);//84 + gc2053_1l_write_register(ViPipe, 0x2d, 0x68);//84 + gc2053_1l_write_register(ViPipe, 0x2e, 0x68);//83 + gc2053_1l_write_register(ViPipe, 0x2f, 0x68);//82 + gc2053_1l_write_register(ViPipe, 0x30, 0x4f);//82 + gc2053_1l_write_register(ViPipe, 0x31, 0x68);//82 + gc2053_1l_write_register(ViPipe, 0x32, 0x67);//82 + gc2053_1l_write_register(ViPipe, 0x33, 0x66);//82 + gc2053_1l_write_register(ViPipe, 0x34, 0x66);//82 + gc2053_1l_write_register(ViPipe, 0x35, 0x66);//82 + gc2053_1l_write_register(ViPipe, 0x36, 0x66);//64 + gc2053_1l_write_register(ViPipe, 0x37, 0x66);//68 + gc2053_1l_write_register(ViPipe, 0x38, 0x62); + gc2053_1l_write_register(ViPipe, 0x39, 0x62); + gc2053_1l_write_register(ViPipe, 0x3a, 0x62); + gc2053_1l_write_register(ViPipe, 0x3b, 0x62); + gc2053_1l_write_register(ViPipe, 0x3c, 0x62); + gc2053_1l_write_register(ViPipe, 0x3d, 0x62); + gc2053_1l_write_register(ViPipe, 0x3e, 0x62); + gc2053_1l_write_register(ViPipe, 0x3f, 0x62); + /****DVP & MIPI****/ + gc2053_1l_write_register(ViPipe, 0xfe, 0x01); + gc2053_1l_write_register(ViPipe, 0x9a, 0x06); + gc2053_1l_write_register(ViPipe, 0xfe, 0x00); + gc2053_1l_write_register(ViPipe, 0x7b, 0x2a); + gc2053_1l_write_register(ViPipe, 0x23, 0x2d); + gc2053_1l_write_register(ViPipe, 0xfe, 0x03); + gc2053_1l_write_register(ViPipe, 0x01, 0x27); + gc2053_1l_write_register(ViPipe, 0x02, 0x56); + gc2053_1l_write_register(ViPipe, 0x03, 0xb6); + gc2053_1l_write_register(ViPipe, 0x12, 0x80); + gc2053_1l_write_register(ViPipe, 0x13, 0x07); + gc2053_1l_write_register(ViPipe, 0x15, 0x12); + gc2053_1l_write_register(ViPipe, 0x29, 0x16);// hs_prepare + gc2053_1l_write_register(ViPipe, 0x36, 0x03);// clk lp drv + gc2053_1l_write_register(ViPipe, 0x37, 0x0f);// clk lp drv + gc2053_1l_write_register(ViPipe, 0xfe, 0x00); + gc2053_1l_write_register(ViPipe, 0x3e, 0x90); + + gc2053_1l_default_reg_init(ViPipe); + printf("ViPipe:%d,===GC2053_1L 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_slave/Makefile b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_slave/Makefile new file mode 100644 index 000000000..d64869402 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_slave/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc2053_slave.a +TARGET_SO = $(MW_LIB)/libsns_gc2053_slave.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_slave/gc2053_slave_cmos.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_slave/gc2053_slave_cmos.c new file mode 100644 index 000000000..a93bc4c7e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_slave/gc2053_slave_cmos.c @@ -0,0 +1,883 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "gc2053_slave_cmos_ex.h" +#include "gc2053_slave_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define GC2053_SLAVE_ID 2053 +#define GC2053_SLAVE_I2C_ADDR_1 0x3f +#define GC2053_SLAVE_I2C_ADDR_2 0x37 +#define GC2053_SLAVE_I2C_ADDR_IS_VALID(addr) ((addr) == GC2053_SLAVE_I2C_ADDR_1 || (addr) == GC2053_SLAVE_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc2053_Slave[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC2053_SLAVE_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc2053_Slave[dev]) +#define GC2053_SLAVE_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc2053_Slave[dev] = pstCtx) +#define GC2053_SLAVE_SENSOR_RESET_CTX(dev) (g_pastGc2053_Slave[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc2053_Slave_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 3}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +GC2053_SLAVE_STATE_S g_astGc2053_Slave_State[VI_MAX_PIPE_NUM] = { {0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2053_Slave_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16Gc2053_Slave_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Gc2053_Slave_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Gc2053_Slave Lines Range*****/ +#define GC2053_SLAVE_FULL_LINES_MAX (0x3fff) + +/*****Gc2053_Slave Register Address*****/ +#define GC2053_SLAVE_EXP_H_ADDR 0x03 +#define GC2053_SLAVE_EXP_L_ADDR 0x04 +#define GC2053_SLAVE_AGAIN_H_ADDR 0xb4 +#define GC2053_SLAVE_AGAIN_L_ADDR 0xb3 +#define GC2053_SLAVE_COL_AGAIN_H_ADDR 0xb8 +#define GC2053_SLAVE_COL_AGAIN_L_ADDR 0xb9 +#define GC2053_SLAVE_DGAIN_H_ADDR 0xb1 +#define GC2053_SLAVE_DGAIN_L_ADDR 0xb2 +#define GC2053_SLAVE_VTS_H_ADDR 0x41 //(frame length) +#define GC2053_SLAVE_VTS_L_ADDR 0x42 + +#define GC2053_SLAVE_RES_IS_1080P(w, h) ((w) == 1920 && (h) == 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const GC2053_SLAVE_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc2053_Slave_mode; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC2053_SLAVE_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 3985*16; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 10240; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : + pstMode->stExp.u16Def; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp.u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp.u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = 0; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_stGc2053_Slave_mode.u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_stGc2053_Slave_mode.f32MaxFps; + f32MinFps = g_stGc2053_Slave_mode.f32MinFps; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > GC2053_SLAVE_FULL_LINES_MAX) ? GC2053_SLAVE_FULL_LINES_MAX : u32VMAX; + + pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF); + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_U32 regValTable[25][4] = { + {0x00, 0x00, 0x01, 0x00}, + {0x00, 0x10, 0x01, 0x0c}, + {0x00, 0x20, 0x01, 0x1b}, + {0x00, 0x30, 0x01, 0x2c}, + {0x00, 0x40, 0x01, 0x3f}, + {0x00, 0x50, 0x02, 0x16}, + {0x00, 0x60, 0x02, 0x35}, + {0x00, 0x70, 0x03, 0x16}, + {0x00, 0x80, 0x04, 0x02}, + {0x00, 0x90, 0x04, 0x31}, + {0x00, 0xa0, 0x05, 0x32}, + {0x00, 0xb0, 0x06, 0x35}, + {0x00, 0xc0, 0x08, 0x04}, + {0x00, 0x5a, 0x09, 0x19}, + {0x00, 0x83, 0x0b, 0x0f}, + {0x00, 0x93, 0x0d, 0x12}, + {0x00, 0x84, 0x10, 0x00}, + {0x00, 0x94, 0x12, 0x3a}, + {0x01, 0x2c, 0x1a, 0x02}, + {0x01, 0x3c, 0x1b, 0x20}, + {0x00, 0x8c, 0x20, 0x0f}, + {0x00, 0x9c, 0x26, 0x07}, + {0x02, 0x64, 0x36, 0x21}, + {0x02, 0x74, 0x37, 0x3a}, + {0x00, 0xc6, 0x3d, 0x02}, +}; + +static CVI_U32 gain_table[25] = { + 64*16, 76*16, 90*16, 108*16, 127*16, 148*16, 180*16, 216*16, 255*16, 300*16, + 361*16, 422*16, 504*16, 593*16, 722*16, 850*16, 1008*16, 1182*16, 1408*16, 1689*16, + 2021*16, 2391*16, 2850*16, 3369*16, 3985*16,/* 4805*16, 5768*16, 6806*16, 7723*16,*/ +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i, total; + CVI_U32 pregain; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + total = sizeof(gain_table) / sizeof(CVI_U32); + + if (*pu32AgainLin >= gain_table[total - 1]) { + *pu32AgainLin = *pu32AgainDb = gain_table[total - 1]; + return CVI_SUCCESS; + } + + for (i = 1; i < total; i++) { + if (*pu32AgainLin < gain_table[i]) + break; + } + i--; + // find the pregain + pregain = *pu32AgainLin * 64 / gain_table[i]; + // set the Db as the AE algo gain, we need this to do gain update + *pu32AgainDb = *pu32AgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32AgainLin = pregain * gain_table[i] / 64; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 pregain; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + // find the pregain + pregain = *pu32DgainLin * 64 / 1024; + // set the Db as the AE algo gain, we need this to do gain update + *pu32DgainDb = *pu32DgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32DgainLin = pregain * 16; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + int i, total; + + total = sizeof(gain_table) / sizeof(CVI_U32); + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* only surpport linear mode */ + u32Again = pu32Again[0]; + /* To kepp the linearity. we assume AE algo adjusts the dgain only when the again reachs the maximum value */ + if (u32Again < (3985*16)) { + for (i = 1; i < total; i++) { + if (*pu32Again < gain_table[i]) + break; + } + i--; + // find the pregain + u32Dgain = u32Again * 64 / gain_table[i]; + u32Again = i; + } else { + u32Again = total - 1; + // find the pregain + u32Dgain = pu32Dgain[0] * 64 / 1024; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][0]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][1]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][2]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][3]; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 6); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + UNUSED(ViPipe); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + UNUSED(ViPipe); + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + CMOS_CHECK_POINTER(pstBlc); + UNUSED(ViPipe); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC2053_SLAVE_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc2053_Slave_mode; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->stImg, sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = GC2053_SLAVE_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc2053_Slave_mode.u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunGc2053_Slave_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = gc2053_slave_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc2053_slave_addr_byte; + pstI2c_data[i].u32DataByteNum = gc2053_slave_data_byte; + } + + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC2053_SLAVE_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC2053_SLAVE_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC2053_SLAVE_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC2053_SLAVE_AGAIN_L_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC2053_SLAVE_COL_AGAIN_H_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC2053_SLAVE_COL_AGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC2053_SLAVE_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC2053_SLAVE_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC2053_SLAVE_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC2053_SLAVE_VTS_L_ADDR; + + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + + CVI_U32 gainsUpdate = 0; + + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + + if ((i >= LINEAR_AGAIN_H) && (i <= LINEAR_DGAIN_L)) + gainsUpdate = 1; + + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (gainsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L].bUpdate = CVI_TRUE; + } + + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC2053_SLAVE_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC2053_SLAVE_MODE_1920X1080P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc2053_Slave_MirrorFip[ViPipe] != eSnsMirrorFlip) { + gc2053_slave_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeGc2053_Slave_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC2053_SLAVE_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc2053_Slave_mode.u32VtsDef; + pstSnsState->au32FL[0] = g_stGc2053_Slave_mode.u32VtsDef; + pstSnsState->au32FL[1] = g_stGc2053_Slave_mode.u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc2053_slave_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_stGc2053_Slave_mode.stImg.stSnsSize.u32Width; + pstRxAttr->img_size.height = g_stGc2053_Slave_mode.stImg.stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc2053_slave_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc2053_slave_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc2053_slave_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (GC2053_SLAVE_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc2053_slave_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc2053_slave_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc2053_Slave_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC2053_SLAVE_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC2053_SLAVE_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC2053_SLAVE_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC2053_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC2053_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC2053_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Gc2053_Slave_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Gc2053_Slave_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc2053_slave_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc2053_Slave_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc2053_slave_standby, + .pfnRestart = gc2053_slave_restart, + .pfnWriteReg = gc2053_slave_write_register, + .pfnReadReg = gc2053_slave_read_register, + .pfnSetBusInfo = gc2053_slave_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_slave/gc2053_slave_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_slave/gc2053_slave_cmos_ex.h new file mode 100644 index 000000000..60b1f7e56 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_slave/gc2053_slave_cmos_ex.h @@ -0,0 +1,88 @@ +#ifndef __GC2053_SLAVE_CMOS_EX_H_ +#define __GC2053_SLAVE_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum gc2053_slave_linear_regs_e { + LINEAR_EXP_H = 0,//03 + LINEAR_EXP_L, //04 + LINEAR_AGAIN_H, //b4 + LINEAR_AGAIN_L, //b3 + LINEAR_COL_AGAIN_H, //b8 + LINEAR_COL_AGAIN_L, //b9 + LINEAR_DGAIN_H, //b1 + LINEAR_DGAIN_L, //b2 + LINEAR_VTS_H, //0x41 (frame length) + LINEAR_VTS_L,//0x42 + LINEAR_REGS_NUM +}; + + +typedef enum _GC2053_SLAVE_MODE_E { + GC2053_SLAVE_MODE_1920X1080P30 = 0, + GC2053_SLAVE_MODE_NUM +} GC2053_SLAVE_MODE_E; + +typedef struct _GC2053_SLAVE_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC2053_SLAVE_STATE_S; + +typedef struct _GC2053_SLAVE_MODE_S { + ISP_WDR_SIZE_S stImg; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp; + SNS_ATTR_LARGE_S stAgain; + SNS_ATTR_LARGE_S stDgain; + char name[64]; +} GC2053_SLAVE_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc2053_Slave[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc2053_Slave_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2053_Slave_MirrorFip[VI_MAX_PIPE_NUM]; +extern CVI_U8 gc2053_slave_i2c_addr; +extern const CVI_U32 gc2053_slave_addr_byte; +extern const CVI_U32 gc2053_slave_data_byte; +extern void gc2053_slave_init(VI_PIPE ViPipe); +extern void gc2053_slave_exit(VI_PIPE ViPipe); +extern void gc2053_slave_standby(VI_PIPE ViPipe); +extern void gc2053_slave_restart(VI_PIPE ViPipe); +extern int gc2053_slave_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc2053_slave_read_register(VI_PIPE ViPipe, int addr); +extern void gc2053_slave_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int gc2053_slave_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2053_SLAVE_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_slave/gc2053_slave_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_slave/gc2053_slave_cmos_param.h new file mode 100644 index 000000000..983eac40e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_slave/gc2053_slave_cmos_param.h @@ -0,0 +1,219 @@ +#ifndef __GC2053_CMOS_PARAM_H_ +#define __GC2053_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2053_slave_cmos_ex.h" + +static const GC2053_SLAVE_MODE_S g_stGc2053_Slave_mode = { + .name = "1920X1080P30", + .stImg = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.07, /* 1125 * 30 / 0x3FFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp = { + .u16Min = 1, + .u16Max = 0x3fff, + .u16Def = 0x2000, + .u16Step = 1, + }, + .stAgain = { + .u32Min = 64, + .u32Max = 62977, + .u32Def = 64, + .u32Step = 1, + }, + .stDgain = { + .u32Min = 64*16, + .u32Max = 7073*16, + .u32Def = 581*16, + .u32Step = 10*16, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.05999477580189704895, 0.13019448518753051758}, //B: slope, intercept + {0.06732148677110671997, -1.36387133598327636719}, //Gb: slope, intercept + {0.06651904433965682983, -1.10093510150909423828}, //Gr: slope, intercept + {0.06406146287918090820, 0.33316791057586669922}, //R: slope, intercept + }, + { //iso 200 + {0.06256803125143051147, 4.54908418655395507813}, //B: slope, intercept + {0.06911934912204742432, 2.79023528099060058594}, //Gb: slope, intercept + {0.06846688687801361084, 2.88726186752319335938}, //Gr: slope, intercept + {0.06652788817882537842, 4.40276956558227539063}, //R: slope, intercept + }, + { //iso 400 + {0.06841833144426345825, 11.72280883789062500000}, //B: slope, intercept + {0.07257881015539169312, 10.86985683441162109375}, //Gb: slope, intercept + {0.07174283266067504883, 11.20646286010742187500}, //Gr: slope, intercept + {0.07294593751430511475, 11.17350578308105468750}, //R: slope, intercept + }, + { //iso 800 + {0.07805790752172470093, 20.62956619262695312500}, //B: slope, intercept + {0.07694032043218612671, 22.20356750488281250000}, //Gb: slope, intercept + {0.07647507637739181519, 22.50957298278808593750}, //Gr: slope, intercept + {0.08402533829212188721, 19.11953735351562500000}, //R: slope, intercept + }, + { //iso 1600 + {0.09468275308609008789, 34.07563018798828125000}, //B: slope, intercept + {0.08710632473230361938, 39.15500259399414062500}, //Gb: slope, intercept + {0.08662072569131851196, 39.37175750732421875000}, //Gr: slope, intercept + {0.10222808271646499634, 31.34789276123046875000}, //R: slope, intercept + }, + { //iso 3200 + {0.12651191651821136475, 49.56183242797851562500}, //B: slope, intercept + {0.10816962271928787231, 59.42719650268554687500}, //Gb: slope, intercept + {0.10751257836818695068, 59.90552902221679687500}, //Gr: slope, intercept + {0.13802853226661682129, 45.09576034545898437500}, //R: slope, intercept + }, + { //iso 6400 + {0.17422541975975036621, 70.04063415527343750000}, //B: slope, intercept + {0.14234761893749237061, 85.51583862304687500000}, //Gb: slope, intercept + {0.14159946143627166748, 86.23278045654296875000}, //Gr: slope, intercept + {0.19450971484184265137, 62.65447235107421875000}, //R: slope, intercept + }, + { //iso 12800 + {0.24947367608547210693, 108.30633544921875000000}, //B: slope, intercept + {0.19751225411891937256, 130.88159179687500000000}, //Gb: slope, intercept + {0.19614629447460174561, 132.49082946777343750000}, //Gr: slope, intercept + {0.28106108307838439941, 97.15969085693359375000}, //R: slope, intercept + }, + { //iso 25600 + {0.35420843958854675293, 137.06745910644531250000}, //B: slope, intercept + {0.27778801321983337402, 168.72366333007812500000}, //Gb: slope, intercept + {0.27540388703346252441, 170.54939270019531250000}, //Gr: slope, intercept + {0.39949953556060791016, 123.29409790039062500000}, //R: slope, intercept + }, + { //iso 51200 + {0.45704349875450134277, 179.20147705078125000000}, //B: slope, intercept + {0.32142028212547302246, 246.71363830566406250000}, //Gb: slope, intercept + {0.31958609819412231445, 246.82630920410156250000}, //Gr: slope, intercept + {0.51058447360992431641, 161.86299133300781250000}, //R: slope, intercept + }, + { //iso 102400 + {0.61760461330413818359, 222.90534973144531250000}, //B: slope, intercept + {0.42568457126617431641, 319.29257202148437500000}, //Gb: slope, intercept + {0.41750904917716979980, 324.93432617187500000000}, //Gr: slope, intercept + {0.67956107854843139648, 203.78948974609375000000}, //R: slope, intercept + }, + { //iso 204800 + {0.63289469480514526367, 216.99952697753906250000}, //B: slope, intercept + {0.44890350103378295898, 306.80810546875000000000}, //Gb: slope, intercept + {0.44229975342750549316, 310.13763427734375000000}, //Gr: slope, intercept + {0.69596910476684570313, 196.70443725585937500000}, //R: slope, intercept + }, + { //iso 409600 + {0.71106964349746704102, 187.98352050781250000000}, //B: slope, intercept + {0.55859673023223876953, 246.22378540039062500000}, //Gb: slope, intercept + {0.55284017324447631836, 249.86463928222656250000}, //Gr: slope, intercept + {0.77318203449249267578, 168.85035705566406250000}, //R: slope, intercept + }, + { //iso 819200 + {0.70888006687164306641, 188.44216918945312500000}, //B: slope, intercept + {0.56110274791717529297, 245.46603393554687500000}, //Gb: slope, intercept + {0.55100852251052856445, 250.33049011230468750000}, //Gr: slope, intercept + {0.76897650957107543945, 169.31251525878906250000}, //R: slope, intercept + }, + { //iso 1638400 + {0.70520979166030883789, 188.93899536132812500000}, //B: slope, intercept + {0.56178557872772216797, 245.21235656738281250000}, //Gb: slope, intercept + {0.55338454246520996094, 249.57423400878906250000}, //Gr: slope, intercept + {0.77306479215621948242, 168.86497497558593750000}, //R: slope, intercept + }, + { //iso 3276800 + {0.71255809068679809570, 187.86839294433593750000}, //B: slope, intercept + {0.56056070327758789063, 245.57748413085937500000}, //Gb: slope, intercept + {0.55358195304870605469, 249.62020874023437500000}, //Gr: slope, intercept + {0.77431541681289672852, 168.74313354492187500000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {257, 257, 257, 257, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {257, 257, 257, 257, 259, 259, 260, 267, 278, 298, 366, 383, 366, 373, 372, 372 }, + {257, 257, 257, 257, 258, 259, 261, 266, 274, 297, 379, 377, 372, 365, 373, 374 }, + {257, 257, 257, 257, 258, 259, 261, 266, 275, 296, 376, 388, 366, 374, 376, 372 }, + {257, 257, 257, 257, 258, 259, 260, 264, 274, 294, 362, 363, 365, 361, 353, 367 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1095, + 1099, 1104, 1125, 1130, 1125, 1127, 1126, 1126}, + {1093, 1093, 1093, 1093, 1093, 1093, 1094, 1095, + 1097, 1104, 1128, 1128, 1126, 1124, 1127, 1127}, + {1093, 1093, 1093, 1093, 1093, 1093, 1094, 1095, + 1098, 1104, 1128, 1131, 1125, 1127, 1128, 1126}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1095, + 1097, 1103, 1123, 1124, 1124, 1123, 1121, 1125}, +#endif + }, + }, +}; + +struct combo_dev_attr_s gc2053_slave_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {0, 4, 2, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 1, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2053_SLAVE_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_slave/gc2053_slave_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_slave/gc2053_slave_sensor_ctl.c new file mode 100644 index 000000000..520515021 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2053_slave/gc2053_slave_sensor_ctl.c @@ -0,0 +1,395 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2053_slave_cmos_ex.h" + +#define GC2053_SLAVE_CHIP_ID_ADDR_H 0xf0 +#define GC2053_SLAVE_CHIP_ID_ADDR_L 0xf1 +#define GC2053_SLAVE_CHIP_ID 0x2053 + +static void gc2053_slave_linear_1080p30_init(VI_PIPE ViPipe); + +CVI_U8 gc2053_slave_i2c_addr = 0x37;//0x6e +const CVI_U32 gc2053_slave_addr_byte = 1; +const CVI_U32 gc2053_slave_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc2053_slave_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc2053_Slave_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc2053_slave_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc2053_slave_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc2053_slave_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (gc2053_slave_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc2053_slave_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, gc2053_slave_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc2053_slave_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int gc2053_slave_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc2053_slave_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (gc2053_slave_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc2053_slave_addr_byte + gc2053_slave_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + //syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void gc2053_slave_standby(VI_PIPE ViPipe) +{ + gc2053_slave_write_register(ViPipe, 0x3e, 0x00); + gc2053_slave_write_register(ViPipe, 0xf7, 0x00); + gc2053_slave_write_register(ViPipe, 0xfc, 0x01); + gc2053_slave_write_register(ViPipe, 0xf9, 0x83); + + printf("gc2053_standby\n"); +} + +void gc2053_slave_restart(VI_PIPE ViPipe) +{ + gc2053_slave_write_register(ViPipe, 0xf9, 0x82); + delay_ms(2); + gc2053_slave_write_register(ViPipe, 0xf7, 0x01); + gc2053_slave_write_register(ViPipe, 0xfc, 0x8e); + gc2053_slave_write_register(ViPipe, 0x3e, 0x91); + + printf("gc2053_restart\n"); +} + +void gc2053_slave_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc2053_Slave[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc2053_slave_write_register(ViPipe, + g_pastGc2053_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc2053_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} +void gc2053_slave_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 value = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + value = 0x01; + break; + case ISP_SNS_FLIP: + value = 0x02; + break; + case ISP_SNS_MIRROR_FLIP: + value = 0x03; + break; + default: + return; + } + gc2053_slave_write_register(ViPipe, 0xfe, 0x00); + gc2053_slave_write_register(ViPipe, 0x17, value); +} + +int gc2053_slave_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc2053_slave_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc2053_slave_read_register(ViPipe, GC2053_SLAVE_CHIP_ID_ADDR_H); + nVal2 = gc2053_slave_read_register(ViPipe, GC2053_SLAVE_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC2053_SLAVE_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc2053_slave_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode = g_pastGc2053_Slave[ViPipe]->enWDRMode; + + gc2053_slave_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n"); + } else { + gc2053_slave_linear_1080p30_init(ViPipe); + } + g_pastGc2053_Slave[ViPipe]->bInit = CVI_TRUE; +} + +void gc2053_slave_exit(VI_PIPE ViPipe) +{ + gc2053_slave_i2c_exit(ViPipe); +} + +static void gc2053_slave_linear_1080p30_init(VI_PIPE ViPipe) +{ + /****system****/ + gc2053_slave_write_register(ViPipe, 0xfe, 0x80); + gc2053_slave_write_register(ViPipe, 0xfe, 0x80); + gc2053_slave_write_register(ViPipe, 0xfe, 0x80); + gc2053_slave_write_register(ViPipe, 0xfe, 0x00); + gc2053_slave_write_register(ViPipe, 0xf2, 0x00); + gc2053_slave_write_register(ViPipe, 0xf3, 0x00); + gc2053_slave_write_register(ViPipe, 0xf4, 0x36); + gc2053_slave_write_register(ViPipe, 0xf5, 0xc0); + gc2053_slave_write_register(ViPipe, 0xf6, 0x44); + gc2053_slave_write_register(ViPipe, 0xf7, 0x01); + gc2053_slave_write_register(ViPipe, 0xf8, 0x2c); + gc2053_slave_write_register(ViPipe, 0xf9, 0x42); + gc2053_slave_write_register(ViPipe, 0xfc, 0x8e); + /****CISCTL & ANALOG****/ + gc2053_slave_write_register(ViPipe, 0xfe, 0x00); + gc2053_slave_write_register(ViPipe, 0x87, 0x18); + gc2053_slave_write_register(ViPipe, 0xee, 0x30); + gc2053_slave_write_register(ViPipe, 0xd0, 0xb7); + gc2053_slave_write_register(ViPipe, 0x03, 0x04); + gc2053_slave_write_register(ViPipe, 0x04, 0x60); + gc2053_slave_write_register(ViPipe, 0x05, 0x04); + gc2053_slave_write_register(ViPipe, 0x06, 0x4c); + gc2053_slave_write_register(ViPipe, 0x07, 0x00); + gc2053_slave_write_register(ViPipe, 0x08, 0x11); + gc2053_slave_write_register(ViPipe, 0x09, 0x00); + gc2053_slave_write_register(ViPipe, 0x0a, 0x02); + gc2053_slave_write_register(ViPipe, 0x0b, 0x00); + gc2053_slave_write_register(ViPipe, 0x0c, 0x02); + gc2053_slave_write_register(ViPipe, 0x0d, 0x04); + gc2053_slave_write_register(ViPipe, 0x0e, 0x40); + gc2053_slave_write_register(ViPipe, 0x12, 0xe2); + gc2053_slave_write_register(ViPipe, 0x13, 0x16); + gc2053_slave_write_register(ViPipe, 0x19, 0x0a); + gc2053_slave_write_register(ViPipe, 0x21, 0x1c); + gc2053_slave_write_register(ViPipe, 0x28, 0x0a); + gc2053_slave_write_register(ViPipe, 0x29, 0x24); + gc2053_slave_write_register(ViPipe, 0x2b, 0x04); + gc2053_slave_write_register(ViPipe, 0x32, 0xf8); + gc2053_slave_write_register(ViPipe, 0x37, 0x03); + gc2053_slave_write_register(ViPipe, 0x39, 0x15); + gc2053_slave_write_register(ViPipe, 0x41, 0x04); + gc2053_slave_write_register(ViPipe, 0x42, 0x65); + gc2053_slave_write_register(ViPipe, 0x43, 0x07); + gc2053_slave_write_register(ViPipe, 0x44, 0x40); + gc2053_slave_write_register(ViPipe, 0x46, 0x0b); + gc2053_slave_write_register(ViPipe, 0x4b, 0x20); + gc2053_slave_write_register(ViPipe, 0x4e, 0x08); + gc2053_slave_write_register(ViPipe, 0x55, 0x20); + gc2053_slave_write_register(ViPipe, 0x66, 0x05); + gc2053_slave_write_register(ViPipe, 0x67, 0x05); + gc2053_slave_write_register(ViPipe, 0x77, 0x01); + gc2053_slave_write_register(ViPipe, 0x78, 0x00); + gc2053_slave_write_register(ViPipe, 0x7c, 0x93); + gc2053_slave_write_register(ViPipe, 0x8c, 0x12); + gc2053_slave_write_register(ViPipe, 0x8d, 0x92); + gc2053_slave_write_register(ViPipe, 0x90, 0x00); + gc2053_slave_write_register(ViPipe, 0x9d, 0x10); + gc2053_slave_write_register(ViPipe, 0xce, 0x7c); + gc2053_slave_write_register(ViPipe, 0xd2, 0x41); + gc2053_slave_write_register(ViPipe, 0xd3, 0xdc); + gc2053_slave_write_register(ViPipe, 0xe6, 0x50); + /*gain*/ + gc2053_slave_write_register(ViPipe, 0xb6, 0xc0); + gc2053_slave_write_register(ViPipe, 0xb0, 0x70); + gc2053_slave_write_register(ViPipe, 0xb1, 0x01); + gc2053_slave_write_register(ViPipe, 0xb2, 0x00); + gc2053_slave_write_register(ViPipe, 0xb3, 0x00); + gc2053_slave_write_register(ViPipe, 0xb4, 0x00); + gc2053_slave_write_register(ViPipe, 0xb8, 0x01); + gc2053_slave_write_register(ViPipe, 0xb9, 0x00); + /*blk*/ + gc2053_slave_write_register(ViPipe, 0x26, 0x30); + gc2053_slave_write_register(ViPipe, 0xfe, 0x01); + gc2053_slave_write_register(ViPipe, 0x40, 0x23); + gc2053_slave_write_register(ViPipe, 0x55, 0x07); + gc2053_slave_write_register(ViPipe, 0x60, 0x40); + gc2053_slave_write_register(ViPipe, 0xfe, 0x04); + gc2053_slave_write_register(ViPipe, 0x14, 0x78); + gc2053_slave_write_register(ViPipe, 0x15, 0x78); + gc2053_slave_write_register(ViPipe, 0x16, 0x78); + gc2053_slave_write_register(ViPipe, 0x17, 0x78); + /*window*/ + gc2053_slave_write_register(ViPipe, 0xfe, 0x01); + gc2053_slave_write_register(ViPipe, 0x91, 0x00); + gc2053_slave_write_register(ViPipe, 0x92, 0x00); + gc2053_slave_write_register(ViPipe, 0x93, 0x00); + gc2053_slave_write_register(ViPipe, 0x94, 0x03); + gc2053_slave_write_register(ViPipe, 0x95, 0x04); + gc2053_slave_write_register(ViPipe, 0x96, 0x38); + gc2053_slave_write_register(ViPipe, 0x97, 0x07); + gc2053_slave_write_register(ViPipe, 0x98, 0x80); + /*ISP*/ + gc2053_slave_write_register(ViPipe, 0xfe, 0x01); + gc2053_slave_write_register(ViPipe, 0x01, 0x05); + gc2053_slave_write_register(ViPipe, 0x02, 0x89); + gc2053_slave_write_register(ViPipe, 0x04, 0x01); + gc2053_slave_write_register(ViPipe, 0x07, 0xa6); + gc2053_slave_write_register(ViPipe, 0x08, 0xa9); + gc2053_slave_write_register(ViPipe, 0x09, 0xa8); + gc2053_slave_write_register(ViPipe, 0x0a, 0xa7); + gc2053_slave_write_register(ViPipe, 0x0b, 0xff); + gc2053_slave_write_register(ViPipe, 0x0c, 0xff); + gc2053_slave_write_register(ViPipe, 0x0f, 0x00); + gc2053_slave_write_register(ViPipe, 0x50, 0x1c); + gc2053_slave_write_register(ViPipe, 0x89, 0x03); + gc2053_slave_write_register(ViPipe, 0xfe, 0x04); + gc2053_slave_write_register(ViPipe, 0x28, 0x86); + gc2053_slave_write_register(ViPipe, 0x29, 0x86); + gc2053_slave_write_register(ViPipe, 0x2a, 0x86); + gc2053_slave_write_register(ViPipe, 0x2b, 0x68); + gc2053_slave_write_register(ViPipe, 0x2c, 0x68); + gc2053_slave_write_register(ViPipe, 0x2d, 0x68); + gc2053_slave_write_register(ViPipe, 0x2e, 0x68); + gc2053_slave_write_register(ViPipe, 0x2f, 0x68); + gc2053_slave_write_register(ViPipe, 0x30, 0x4f); + gc2053_slave_write_register(ViPipe, 0x31, 0x68); + gc2053_slave_write_register(ViPipe, 0x32, 0x67); + gc2053_slave_write_register(ViPipe, 0x33, 0x66); + gc2053_slave_write_register(ViPipe, 0x34, 0x66); + gc2053_slave_write_register(ViPipe, 0x35, 0x66); + gc2053_slave_write_register(ViPipe, 0x36, 0x66); + gc2053_slave_write_register(ViPipe, 0x37, 0x66); + gc2053_slave_write_register(ViPipe, 0x38, 0x62); + gc2053_slave_write_register(ViPipe, 0x39, 0x62); + gc2053_slave_write_register(ViPipe, 0x3a, 0x62); + gc2053_slave_write_register(ViPipe, 0x3b, 0x62); + gc2053_slave_write_register(ViPipe, 0x3c, 0x62); + gc2053_slave_write_register(ViPipe, 0x3d, 0x62); + gc2053_slave_write_register(ViPipe, 0x3e, 0x62); + gc2053_slave_write_register(ViPipe, 0x3f, 0x62); + /****DVP & MIPI****/ + gc2053_slave_write_register(ViPipe, 0xfe, 0x01); + gc2053_slave_write_register(ViPipe, 0x9a, 0x06); + gc2053_slave_write_register(ViPipe, 0xfe, 0x00); + gc2053_slave_write_register(ViPipe, 0x7b, 0x2a); + gc2053_slave_write_register(ViPipe, 0x23, 0x2d); + gc2053_slave_write_register(ViPipe, 0xfe, 0x03); + gc2053_slave_write_register(ViPipe, 0x01, 0x27); + gc2053_slave_write_register(ViPipe, 0x02, 0x56); + gc2053_slave_write_register(ViPipe, 0x03, 0x8e); + gc2053_slave_write_register(ViPipe, 0x12, 0x80); + gc2053_slave_write_register(ViPipe, 0x13, 0x07); + gc2053_slave_write_register(ViPipe, 0x15, 0x12); + gc2053_slave_write_register(ViPipe, 0xfe, 0x00); + gc2053_slave_write_register(ViPipe, 0x3e, 0x91); + + gc2053_slave_default_reg_init(ViPipe); + printf("ViPipe:%d,===GC2053 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2093/Makefile b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2093/Makefile new file mode 100644 index 000000000..a6b89d54e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2093/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc2093.a +TARGET_SO = $(MW_LIB)/libsns_gc2093.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2093/gc2093_cmos.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2093/gc2093_cmos.c new file mode 100644 index 000000000..14b24233b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2093/gc2093_cmos.c @@ -0,0 +1,1193 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "gc2093_cmos_ex.h" +#include "gc2093_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define GC2093_ID 2093 +/**************************************************************************** + * global variables * + ***************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc2093[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC2093_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc2093[dev]) +#define GC2093_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc2093[dev] = pstCtx) +#define GC2093_SENSOR_RESET_CTX(dev) (g_pastGc2093[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc2093_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2093_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16Gc2093_GainMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ***************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Gc2093 Lines Range*****/ +#define GC2093_FULL_LINES_MAX (0x3fff) + +/*****Gc2093 Register Address*****/ +#define GC2093_EXP_H_ADDR 0x0003 +#define GC2093_EXP_L_ADDR 0x0004 +#define GC2093_SEXP_H_ADDR 0x0001 +#define GC2093_SEXP_L_ADDR 0x0002 + +#define GC2093_AGAIN_H_ADDR 0x00b4 +#define GC2093_AGAIN_L_ADDR 0x00b3 +#define GC2093_COL_AGAIN_H_ADDR 0x00b8 +#define GC2093_COL_AGAIN_L_ADDR 0x00b9 +#define GC2093_AGAIN_MAG1 0x0155 +#define GC2093_AGAIN_HOLD 0x031d +#define GC2093_AGAIN_MAG2 0x00c2 +#define GC2093_AGAIN_MAG3 0x00cf +#define GC2093_AGAIN_MAG4 0x00d9 + +#define GC2093_DGAIN_H_ADDR 0x00b1 +#define GC2093_DGAIN_L_ADDR 0x00b2 +#define GC2093_VTS_H_ADDR 0x0041 //(frame length) +#define GC2093_VTS_L_ADDR 0x0042 + +#define GC2093_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC2093_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astGc2093_mode[GC2093_MODE_1920X1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astGc2093_mode[GC2093_MODE_1920X1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 74976; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 10240; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? + g_au32InitExposure[ViPipe] : g_astGc2093_mode[GC2093_MODE_1920X1080P30].stExp[0].u16Def; + + pstAeSnsDft->u32MaxIntTime = g_astGc2093_mode[GC2093_MODE_1920X1080P30].stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = g_astGc2093_mode[GC2093_MODE_1920X1080P30].stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astGc2093_mode[GC2093_MODE_1920X1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astGc2093_mode[GC2093_MODE_1920X1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 3; + pstAeSnsDft->u32MinIntTime = 1; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 74976; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 10240; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astGc2093_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astGc2093_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astGc2093_mode[pstSnsState->u8ImgMode].f32MinFps; + + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + + u32VMAX = (u32VMAX > GC2093_FULL_LINES_MAX) ? GC2093_FULL_LINES_MAX : u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF); + } else { + pstSnsRegsInfo->astI2cData[WDR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR_VTS_L].u32Data = (u32VMAX & 0xFF); + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + CVI_U16 u16Sexp, u16Lexp; + CVI_U32 u32MaxRangeLExp, u32MaxRangeSExp; + + /* + *exp_shortau32FL[0] - 1088 - 20 - 1 - 8; + pstSnsState->au32WDRIntTime[0] = (u32ShortIntTime <= u32MaxRangeSExp) ? + u32ShortIntTime : u32MaxRangeSExp; + if (!pstSnsState->au32WDRIntTime[0]) + pstSnsState->au32WDRIntTime[0] = 1; + u16Sexp = (CVI_U16)pstSnsState->au32WDRIntTime[0]; + + u32MaxRangeLExp = pstSnsState->au32FL[0] - u16Sexp; + pstSnsState->au32WDRIntTime[1] = (u32LongIntTime <= u32MaxRangeLExp) ? + u32LongIntTime : u32MaxRangeLExp; + if (!pstSnsState->au32WDRIntTime[1]) + pstSnsState->au32WDRIntTime[1] = 1; + u16Lexp = (CVI_U16)pstSnsState->au32WDRIntTime[1]; + + pstSnsRegsInfo->astI2cData[WDR_LEXP_H].u32Data = ((u16Lexp >> 8) & 0x3F); + pstSnsRegsInfo->astI2cData[WDR_LEXP_L].u32Data = (u16Lexp & 0xFF); + + pstSnsRegsInfo->astI2cData[WDR_SEXP_H].u32Data = ((u16Sexp >> 8) & 0x3F); + pstSnsRegsInfo->astI2cData[WDR_SEXP_L].u32Data = (u16Sexp & 0xFF); + + //Fixed blooming problem that would occur in highlighted environments + //sync solution from gc simon + if (u16Sexp < 0x4) + gc2093_write_register(ViPipe, 0x0032, 0xfd); + else + gc2093_write_register(ViPipe, 0x0032, 0xf8); + } else { + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = ((u32IntTime[0] >> 8) & 0x3F); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF); + } + + return CVI_SUCCESS; +} + +static CVI_U32 regValTable[25][7] = { + //0xb3 0xb8 0xb9 0x155 0xc2 0xcf 0xd9 + {0x00, 0x01, 0x00, 0x08, 0x10, 0x08, 0x0a}, + {0x10, 0x01, 0x0c, 0x08, 0x10, 0x08, 0x0a}, + {0x20, 0x01, 0x1b, 0x08, 0x11, 0x08, 0x0c}, + {0x30, 0x01, 0x2c, 0x08, 0x12, 0x08, 0x0e}, + {0x40, 0x01, 0x3f, 0x08, 0x14, 0x08, 0x12}, + {0x50, 0x02, 0x16, 0x08, 0x15, 0x08, 0x14}, + {0x60, 0x02, 0x35, 0x08, 0x17, 0x08, 0x18}, + {0x70, 0x03, 0x16, 0x08, 0x18, 0x08, 0x1a}, + {0x80, 0x04, 0x02, 0x08, 0x1a, 0x08, 0x1e}, + {0x90, 0x04, 0x31, 0x08, 0x1b, 0x08, 0x20}, + {0xa0, 0x05, 0x32, 0x08, 0x1d, 0x08, 0x24}, + {0xb0, 0x06, 0x35, 0x08, 0x1e, 0x08, 0x26}, + {0xc0, 0x08, 0x04, 0x08, 0x20, 0x08, 0x2a}, + {0x5a, 0x09, 0x19, 0x08, 0x1e, 0x08, 0x2a}, + {0x83, 0x0b, 0x0f, 0x08, 0x1f, 0x08, 0x2a}, + {0x93, 0x0d, 0x12, 0x08, 0x21, 0x08, 0x2e}, + {0x84, 0x10, 0x00, 0x0b, 0x22, 0x08, 0x30}, + {0x94, 0x12, 0x3a, 0x0b, 0x24, 0x08, 0x34}, + {0x5d, 0x1a, 0x02, 0x0b, 0x26, 0x08, 0x34}, + {0x9b, 0x1b, 0x20, 0x0b, 0x26, 0x08, 0x34}, + {0x8c, 0x20, 0x0f, 0x0b, 0x26, 0x08, 0x34}, + {0x9c, 0x26, 0x07, 0x12, 0x26, 0x08, 0x34}, + {0xB6, 0x36, 0x21, 0x12, 0x26, 0x08, 0x34}, + {0xad, 0x37, 0x3a, 0x12, 0x26, 0x08, 0x34}, + {0xbd, 0x3d, 0x02, 0x12, 0x26, 0x08, 0x34}, +}; + +static CVI_U32 regValTable_WDR[25][7] = { + //0xb3 0xb8 0xb9 0x155 0xc2 0xcf 0xd9 + {0x00, 0x01, 0x00, 0x08, 0x10, 0x08, 0x0a}, + {0x10, 0x01, 0x0c, 0x08, 0x10, 0x08, 0x0a}, + {0x20, 0x01, 0x1b, 0x08, 0x11, 0x08, 0x0c}, + {0x30, 0x01, 0x2c, 0x08, 0x12, 0x08, 0x0e}, + {0x40, 0x01, 0x3f, 0x08, 0x14, 0x08, 0x12}, + {0x50, 0x02, 0x16, 0x08, 0x15, 0x08, 0x14}, + {0x60, 0x02, 0x35, 0x08, 0x17, 0x08, 0x18}, + {0x70, 0x03, 0x16, 0x08, 0x18, 0x08, 0x1a}, + {0x80, 0x04, 0x02, 0x08, 0x1a, 0x08, 0x1e}, + {0x90, 0x04, 0x31, 0x08, 0x1b, 0x08, 0x20}, + {0xa0, 0x05, 0x32, 0x08, 0x1d, 0x08, 0x24}, + {0xb0, 0x06, 0x35, 0x08, 0x1e, 0x08, 0x26}, + {0xc0, 0x08, 0x04, 0x08, 0x20, 0x08, 0x2a}, + {0x5a, 0x09, 0x19, 0x08, 0x1e, 0x08, 0x2a}, + {0x83, 0x0b, 0x0f, 0x08, 0x1f, 0x08, 0x2a}, + {0x93, 0x0d, 0x12, 0x08, 0x21, 0x08, 0x2e}, + {0x84, 0x10, 0x00, 0x0b, 0x22, 0x08, 0x30}, + {0x94, 0x12, 0x3a, 0x0b, 0x24, 0x08, 0x34}, + {0x5d, 0x1a, 0x02, 0x0b, 0x26, 0x08, 0x34}, + {0x9b, 0x1b, 0x20, 0x0b, 0x26, 0x08, 0x34}, + {0x8c, 0x20, 0x0f, 0x0b, 0x26, 0x08, 0x34}, + {0x9c, 0x26, 0x07, 0x12, 0x26, 0x08, 0x34}, + {0xB6, 0x36, 0x21, 0x12, 0x26, 0x08, 0x34}, + {0xad, 0x37, 0x3a, 0x12, 0x26, 0x08, 0x34}, + {0xbd, 0x3d, 0x02, 0x12, 0x26, 0x08, 0x34}, +}; + +static CVI_U32 gain_table[25] = { + 1024, 1216, 1456, 1712, 2000, 2352, 2832, 3376, 3968, 4752, 5696, 6800, 8064, + 9584, 11344, 13376, 15648, 18448, 26352, 26416, 30960, 36672, 51824, 63344, 74976, +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i, total; + CVI_U32 pregain; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + UNUSED(ViPipe); + total = sizeof(gain_table) / sizeof(CVI_U32); + + if (*pu32AgainLin >= gain_table[total - 1]) { + *pu32AgainLin = *pu32AgainDb = gain_table[total - 1]; + return CVI_SUCCESS; + } + + for (i = 1; i < total; i++) { + if (*pu32AgainLin < gain_table[i]) + break; + } + i--; + // find the pregain + pregain = *pu32AgainLin * 64 / gain_table[i]; + // set the Db as the AE algo gain, we need this to do gain update + *pu32AgainDb = *pu32AgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32AgainLin = pregain * gain_table[i] / 64; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 pregain; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + UNUSED(ViPipe); + // find the pregain + pregain = *pu32DgainLin * 64 / 1024; + // set the Db as the AE algo gain, we need this to do gain update + *pu32DgainDb = *pu32DgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32DgainLin = pregain * 16; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + int i, total; + + total = sizeof(gain_table) / sizeof(CVI_U32); + + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* only surpport linear mode */ + u32Again = pu32Again[0]; + /* To kepp the linearity. we assume AE algo adjusts the dgain only when the again reachs the maximum value */ + if (u32Again < (74976)) { + for (i = 1; i < total; i++) { + if (*pu32Again < gain_table[i]) + break; + } + i--; + // find the pregain + u32Dgain = u32Again * 64 / gain_table[i]; + u32Again = i; + } else { + u32Again = total - 1; + // find the pregain + u32Dgain = pu32Dgain[0] * 64 / 1024; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][0]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][1]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][2]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG1].u32Data = regValTable[u32Again][3]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_HOLD].u32Data = 0X2D; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG2].u32Data = regValTable[u32Again][4]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG3].u32Data = regValTable[u32Again][5]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG4].u32Data = regValTable[u32Again][6]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REL].u32Data = 0X28; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 6); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2; + } else { + pstSnsRegsInfo->astI2cData[WDR_AGAIN_L].u32Data = regValTable_WDR[u32Again][0]; + pstSnsRegsInfo->astI2cData[WDR_COL_AGAIN_H].u32Data = regValTable_WDR[u32Again][1]; + pstSnsRegsInfo->astI2cData[WDR_COL_AGAIN_L].u32Data = regValTable_WDR[u32Again][2]; + pstSnsRegsInfo->astI2cData[WDR_AGAIN_MAG1].u32Data = regValTable_WDR[u32Again][3]; + pstSnsRegsInfo->astI2cData[WDR_AGAIN_HOLD].u32Data = 0X2D; + pstSnsRegsInfo->astI2cData[WDR_AGAIN_MAG2].u32Data = regValTable_WDR[u32Again][4]; + pstSnsRegsInfo->astI2cData[WDR_AGAIN_MAG3].u32Data = regValTable_WDR[u32Again][5]; + pstSnsRegsInfo->astI2cData[WDR_AGAIN_MAG4].u32Data = regValTable_WDR[u32Again][6]; + pstSnsRegsInfo->astI2cData[WDR_AGAIN_HOLD].u32Data = 0X28; + + pstSnsRegsInfo->astI2cData[WDR_DGAIN_H].u32Data = (u32Dgain >> 6); + pstSnsRegsInfo->astI2cData[WDR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2; + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 1; + CVI_U32 u32ShortTimeMaxLimit = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + /* + *exp_shortau32FL[1] - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + /*expect new max sexp*/ + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 1) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32ShortTimeMaxLimit = pstSnsState->au32FL[0] - 1088 - 20 - 1 - 8; + /*real new max sexp*/ + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + /*we need to make sure sexp <= frame length-window_height-20 -1*/ + u32IntTimeMaxTmp = (u32IntTimeMaxTmp <= u32ShortTimeMaxLimit) ? u32IntTimeMaxTmp : u32ShortTimeMaxLimit; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + CVI_TRACE_SNS(CVI_DBG_DEBUG, "sexp[%d, %d], lexp[%d, %d], ratio:%d\n", + au32IntTimeMin[0], au32IntTimeMax[0], + au32IntTimeMin[1], au32IntTimeMax[1], au32Ratio[0]); + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio is too large!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + UNUSED(ViPipe); + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + UNUSED(ViPipe); + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + CMOS_CHECK_POINTER(pstBlc); + UNUSED(ViPipe); + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC2093_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astGc2093_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == GC2093_MODE_1920X1080P30_WDR) + pstSnsState->u8ImgMode = GC2093_MODE_1920X1080P30; + + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astGc2093_mode[pstSnsState->u8ImgMode].u32VtsDef; + //syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == GC2093_MODE_1920X1080P30) + pstSnsState->u8ImgMode = GC2093_MODE_1920X1080P30_WDR; + + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astGc2093_mode[pstSnsState->u8ImgMode].u32VtsDef; + //syslog(LOG_INFO, "2to1 line WDR 1080p mode(60fps->30fps)\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunGc2093_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = gc2093_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc2093_addr_byte; + pstI2c_data[i].u32DataByteNum = gc2093_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + //WDR Mode Regs + + pstI2c_data[WDR_LEXP_H].u32RegAddr = GC2093_EXP_H_ADDR; + pstI2c_data[WDR_LEXP_L].u32RegAddr = GC2093_EXP_L_ADDR; + pstI2c_data[WDR_SEXP_H].u32RegAddr = GC2093_SEXP_H_ADDR; + pstI2c_data[WDR_SEXP_L].u32RegAddr = GC2093_SEXP_L_ADDR; + pstI2c_data[WDR_AGAIN_L].u32RegAddr = GC2093_AGAIN_L_ADDR; + pstI2c_data[WDR_COL_AGAIN_H].u32RegAddr = GC2093_COL_AGAIN_H_ADDR; + pstI2c_data[WDR_COL_AGAIN_L].u32RegAddr = GC2093_COL_AGAIN_L_ADDR; + pstI2c_data[WDR_AGAIN_MAG1].u32RegAddr = GC2093_AGAIN_MAG1; + pstI2c_data[WDR_AGAIN_HOLD].u32RegAddr = GC2093_AGAIN_HOLD; + pstI2c_data[WDR_AGAIN_MAG2].u32RegAddr = GC2093_AGAIN_MAG2; + pstI2c_data[WDR_AGAIN_MAG3].u32RegAddr = GC2093_AGAIN_MAG3; + pstI2c_data[WDR_AGAIN_MAG4].u32RegAddr = GC2093_AGAIN_MAG4; + pstI2c_data[WDR_AGAIN_REL].u32RegAddr = GC2093_AGAIN_HOLD; + pstI2c_data[WDR_DGAIN_H].u32RegAddr = GC2093_DGAIN_H_ADDR; + pstI2c_data[WDR_DGAIN_L].u32RegAddr = GC2093_DGAIN_L_ADDR; + pstI2c_data[WDR_VTS_H].u32RegAddr = GC2093_VTS_H_ADDR; + pstI2c_data[WDR_VTS_H].u8DelayFrmNum = 1; + pstI2c_data[WDR_VTS_L].u32RegAddr = GC2093_VTS_L_ADDR; + pstI2c_data[WDR_VTS_L].u8DelayFrmNum = 1; + break; + default: + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC2093_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC2093_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC2093_AGAIN_L_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC2093_COL_AGAIN_H_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC2093_COL_AGAIN_L_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG1].u32RegAddr = GC2093_AGAIN_MAG1; + pstI2c_data[LINEAR_AGAIN_HOLD].u32RegAddr = GC2093_AGAIN_HOLD; + pstI2c_data[LINEAR_AGAIN_MAG2].u32RegAddr = GC2093_AGAIN_MAG2; + pstI2c_data[LINEAR_AGAIN_MAG3].u32RegAddr = GC2093_AGAIN_MAG3; + pstI2c_data[LINEAR_AGAIN_MAG4].u32RegAddr = GC2093_AGAIN_MAG4; + pstI2c_data[LINEAR_AGAIN_REL].u32RegAddr = GC2093_AGAIN_HOLD; + pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC2093_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC2093_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC2093_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_H].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC2093_VTS_L_ADDR; + pstI2c_data[LINEAR_VTS_L].u8DelayFrmNum = 1; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + + CVI_U32 gainsUpdate = 0; + + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((i >= LINEAR_AGAIN_L) && (i <= LINEAR_DGAIN_L)) + gainsUpdate = 1; + } else { + if ((i >= WDR_AGAIN_L) && (i <= WDR_DGAIN_L)) + gainsUpdate = 1; + } + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (gainsUpdate) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG1].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_HOLD].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG2].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG3].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG4].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_REL].bUpdate = CVI_TRUE; + + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L].bUpdate = CVI_TRUE; + } else { + pstCfg0->snsCfg.astI2cData[WDR_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[WDR_COL_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[WDR_COL_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[WDR_AGAIN_MAG1].bUpdate = CVI_TRUE; + + pstCfg0->snsCfg.astI2cData[WDR_AGAIN_HOLD].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[WDR_AGAIN_MAG2].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[WDR_AGAIN_MAG3].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[WDR_AGAIN_MAG4].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[WDR_AGAIN_REL].bUpdate = CVI_TRUE; + + pstCfg0->snsCfg.astI2cData[WDR_DGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[WDR_DGAIN_L].bUpdate = CVI_TRUE; + } + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC2093_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC2093_MODE_1920X1080P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (GC2093_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = GC2093_MODE_1920X1080P30_WDR; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc2093_MirrorFip[ViPipe] != eSnsMirrorFlip) { + gc2093_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeGc2093_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC2093_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astGc2093_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astGc2093_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astGc2093_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc2093_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astGc2093_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astGc2093_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc2093_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc2093_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc2093_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 gc2093_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc2093_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2093_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC2093_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2093_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC2093_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC2093_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC2093_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC2093_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC2093_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Gc2093_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc2093_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc2093_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc2093_standby, + .pfnRestart = gc2093_restart, + .pfnWriteReg = gc2093_write_register, + .pfnReadReg = gc2093_read_register, + .pfnSetBusInfo = gc2093_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2093/gc2093_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2093/gc2093_cmos_ex.h new file mode 100644 index 000000000..d0f8c9869 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2093/gc2093_cmos_ex.h @@ -0,0 +1,116 @@ +#ifndef __GC2093_CMOS_EX_H_ +#define __GC2093_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum gc2093_linear_regs_e { + LINEAR_EXP_H = 0, //03 + LINEAR_EXP_L, //04 + LINEAR_AGAIN_L, //b3 + LINEAR_COL_AGAIN_H, //b8 + LINEAR_COL_AGAIN_L, //b9 + LINEAR_AGAIN_MAG1, //0x155 + LINEAR_AGAIN_HOLD, //0x031d + LINEAR_AGAIN_MAG2, //0xc2 + LINEAR_AGAIN_MAG3, //0xcf + LINEAR_AGAIN_MAG4, //0xd9 + LINEAR_AGAIN_REL, //0x031d + LINEAR_DGAIN_H, //b1 + LINEAR_DGAIN_L, //b2 + LINEAR_VTS_H, //0x41 (frame length) + LINEAR_VTS_L, //0x42 + LINEAR_REGS_NUM +}; + +enum gc2093_wdr_regs_e { + WDR_SEXP_H = 0, //01 + WDR_SEXP_L, //02 + WDR_LEXP_H, //03 + WDR_LEXP_L, //04 + WDR_AGAIN_L, //b3 + WDR_COL_AGAIN_H, //b8 + WDR_COL_AGAIN_L, //b9 + WDR_AGAIN_MAG1, //0x155 + WDR_AGAIN_HOLD, //0x031d + WDR_AGAIN_MAG2, //0xc2 + WDR_AGAIN_MAG3, //0xcf + WDR_AGAIN_MAG4, //0xd9 + WDR_AGAIN_REL, //0x031d + WDR_DGAIN_H, //b1 + WDR_DGAIN_L, //b2 + WDR_VTS_H, //0x41 (frame length) + WDR_VTS_L, //0x42 + WDR_REGS_NUM +}; + + +typedef enum _GC2093_MODE_E { + GC2093_MODE_1920X1080P30 = 0, + GC2093_MODE_LINEAR_NUM, + GC2093_MODE_1920X1080P30_WDR = GC2093_MODE_LINEAR_NUM, + GC2093_MODE_NUM +} GC2093_MODE_E; + +typedef struct _GC2093_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC2093_STATE_S; + +typedef struct _GC2093_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} GC2093_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc2093[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc2093_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2093_MirrorFip[VI_MAX_PIPE_NUM]; +extern const CVI_U8 gc2093_i2c_addr; +extern const CVI_U32 gc2093_addr_byte; +extern const CVI_U32 gc2093_data_byte; +extern void gc2093_init(VI_PIPE ViPipe); +extern void gc2093_exit(VI_PIPE ViPipe); +extern void gc2093_standby(VI_PIPE ViPipe); +extern void gc2093_restart(VI_PIPE ViPipe); +extern int gc2093_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc2093_read_register(VI_PIPE ViPipe, int addr); +extern void gc2093_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int gc2093_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2093_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2093/gc2093_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2093/gc2093_cmos_param.h new file mode 100644 index 000000000..6166d549f --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2093/gc2093_cmos_param.h @@ -0,0 +1,287 @@ +#ifndef __GC2093_CMOS_PARAM_H_ +#define __GC2093_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2093_cmos_ex.h" + +static const GC2093_MODE_S g_astGc2093_mode[GC2093_MODE_NUM] = { + [GC2093_MODE_1920X1080P30] = { + .name = "1920X1080P30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.07, /* 1125 * 30 / 0x3FFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 0x3fff, + .u16Def = 0x2000, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 64, + .u32Max = 62977, + .u32Def = 64, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 64*16, + .u32Max = 7073*16, + .u32Def = 581*16, + .u32Step = 10*16, + }, + }, + [GC2093_MODE_1920X1080P30_WDR] = { + .name = "1920X1080P30_WDR", + .astImg[0] = { + /* sef */ + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .astImg[1] = { + /* lef */ + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.29, /* 1250 * 30 / 0x3FFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1250, + .stAgain[0] = { + .u32Min = 64, + .u32Max = 62977, + .u32Def = 64, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 64, + .u32Max = 62977, + .u32Def = 64, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 64*16, + .u32Max = 7073*16, + .u32Def = 581*16, + .u32Step = 10*16, + }, + .stDgain[1] = { + .u32Min = 64*16, + .u32Max = 7073*16, + .u32Def = 581*16, + .u32Step = 10*16, + }, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.05999477580189704895, 0.13019448518753051758}, //B: slope, intercept + {0.06732148677110671997, -1.36387133598327636719}, //Gb: slope, intercept + {0.06651904433965682983, -1.10093510150909423828}, //Gr: slope, intercept + {0.06406146287918090820, 0.33316791057586669922}, //R: slope, intercept + }, + { //iso 200 + {0.06256803125143051147, 4.54908418655395507813}, //B: slope, intercept + {0.06911934912204742432, 2.79023528099060058594}, //Gb: slope, intercept + {0.06846688687801361084, 2.88726186752319335938}, //Gr: slope, intercept + {0.06652788817882537842, 4.40276956558227539063}, //R: slope, intercept + }, + { //iso 400 + {0.06841833144426345825, 11.72280883789062500000}, //B: slope, intercept + {0.07257881015539169312, 10.86985683441162109375}, //Gb: slope, intercept + {0.07174283266067504883, 11.20646286010742187500}, //Gr: slope, intercept + {0.07294593751430511475, 11.17350578308105468750}, //R: slope, intercept + }, + { //iso 800 + {0.07805790752172470093, 20.62956619262695312500}, //B: slope, intercept + {0.07694032043218612671, 22.20356750488281250000}, //Gb: slope, intercept + {0.07647507637739181519, 22.50957298278808593750}, //Gr: slope, intercept + {0.08402533829212188721, 19.11953735351562500000}, //R: slope, intercept + }, + { //iso 1600 + {0.09468275308609008789, 34.07563018798828125000}, //B: slope, intercept + {0.08710632473230361938, 39.15500259399414062500}, //Gb: slope, intercept + {0.08662072569131851196, 39.37175750732421875000}, //Gr: slope, intercept + {0.10222808271646499634, 31.34789276123046875000}, //R: slope, intercept + }, + { //iso 3200 + {0.12651191651821136475, 49.56183242797851562500}, //B: slope, intercept + {0.10816962271928787231, 59.42719650268554687500}, //Gb: slope, intercept + {0.10751257836818695068, 59.90552902221679687500}, //Gr: slope, intercept + {0.13802853226661682129, 45.09576034545898437500}, //R: slope, intercept + }, + { //iso 6400 + {0.17422541975975036621, 70.04063415527343750000}, //B: slope, intercept + {0.14234761893749237061, 85.51583862304687500000}, //Gb: slope, intercept + {0.14159946143627166748, 86.23278045654296875000}, //Gr: slope, intercept + {0.19450971484184265137, 62.65447235107421875000}, //R: slope, intercept + }, + { //iso 12800 + {0.24947367608547210693, 108.30633544921875000000}, //B: slope, intercept + {0.19751225411891937256, 130.88159179687500000000}, //Gb: slope, intercept + {0.19614629447460174561, 132.49082946777343750000}, //Gr: slope, intercept + {0.28106108307838439941, 97.15969085693359375000}, //R: slope, intercept + }, + { //iso 25600 + {0.35420843958854675293, 137.06745910644531250000}, //B: slope, intercept + {0.27778801321983337402, 168.72366333007812500000}, //Gb: slope, intercept + {0.27540388703346252441, 170.54939270019531250000}, //Gr: slope, intercept + {0.39949953556060791016, 123.29409790039062500000}, //R: slope, intercept + }, + { //iso 51200 + {0.45704349875450134277, 179.20147705078125000000}, //B: slope, intercept + {0.32142028212547302246, 246.71363830566406250000}, //Gb: slope, intercept + {0.31958609819412231445, 246.82630920410156250000}, //Gr: slope, intercept + {0.51058447360992431641, 161.86299133300781250000}, //R: slope, intercept + }, + { //iso 102400 + {0.61760461330413818359, 222.90534973144531250000}, //B: slope, intercept + {0.42568457126617431641, 319.29257202148437500000}, //Gb: slope, intercept + {0.41750904917716979980, 324.93432617187500000000}, //Gr: slope, intercept + {0.67956107854843139648, 203.78948974609375000000}, //R: slope, intercept + }, + { //iso 204800 + {0.63289469480514526367, 216.99952697753906250000}, //B: slope, intercept + {0.44890350103378295898, 306.80810546875000000000}, //Gb: slope, intercept + {0.44229975342750549316, 310.13763427734375000000}, //Gr: slope, intercept + {0.69596910476684570313, 196.70443725585937500000}, //R: slope, intercept + }, + { //iso 409600 + {0.71106964349746704102, 187.98352050781250000000}, //B: slope, intercept + {0.55859673023223876953, 246.22378540039062500000}, //Gb: slope, intercept + {0.55284017324447631836, 249.86463928222656250000}, //Gr: slope, intercept + {0.77318203449249267578, 168.85035705566406250000}, //R: slope, intercept + }, + { //iso 819200 + {0.70888006687164306641, 188.44216918945312500000}, //B: slope, intercept + {0.56110274791717529297, 245.46603393554687500000}, //Gb: slope, intercept + {0.55100852251052856445, 250.33049011230468750000}, //Gr: slope, intercept + {0.76897650957107543945, 169.31251525878906250000}, //R: slope, intercept + }, + { //iso 1638400 + {0.70520979166030883789, 188.93899536132812500000}, //B: slope, intercept + {0.56178557872772216797, 245.21235656738281250000}, //Gb: slope, intercept + {0.55338454246520996094, 249.57423400878906250000}, //Gr: slope, intercept + {0.77306479215621948242, 168.86497497558593750000}, //R: slope, intercept + }, + { //iso 3276800 + {0.71255809068679809570, 187.86839294433593750000}, //B: slope, intercept + {0.56056070327758789063, 245.57748413085937500000}, //Gb: slope, intercept + {0.55358195304870605469, 249.62020874023437500000}, //Gr: slope, intercept + {0.77431541681289672852, 168.74313354492187500000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {256, 257, 257, 257, 259, 259, 260, 267, 278, 298, 366, 383, 366, 373, 372, 372 }, + {256, 257, 257, 257, 258, 259, 261, 266, 274, 297, 379, 377, 372, 365, 373, 374 }, + {256, 257, 257, 257, 258, 259, 261, 266, 275, 296, 376, 388, 366, 374, 376, 372 }, + {256, 257, 257, 257, 258, 259, 260, 264, 274, 294, 362, 363, 365, 361, 353, 367 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1093, 1093, 1093, 1093, 1093, 1093, 1095, 1099, 1104, 1125, 1130, 1125, 1127, + 1126, 1126}, + {1092, 1093, 1093, 1093, 1093, 1093, 1094, 1095, 1097, 1104, 1128, 1128, 1126, 1124, + 1127, 1127}, + {1092, 1093, 1093, 1093, 1093, 1093, 1094, 1095, 1098, 1104, 1128, 1131, 1125, 1127, + 1128, 1126}, + {1092, 1093, 1093, 1093, 1093, 1093, 1093, 1095, 1097, 1103, 1123, 1124, 1124, 1123, + 1121, 1125}, +#endif + }, + }, +}; + +struct combo_dev_attr_s gc2093_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {1, 0, 2, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2093_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2093/gc2093_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2093/gc2093_sensor_ctl.c new file mode 100644 index 000000000..c8ce2cfa2 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2093/gc2093_sensor_ctl.c @@ -0,0 +1,562 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2093_cmos_ex.h" + +static void gc2093_linear_1080p30_init(VI_PIPE ViPipe); +static void gc2093_wdr_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 gc2093_i2c_addr = 0x37;//0x6e +const CVI_U32 gc2093_addr_byte = 2; +const CVI_U32 gc2093_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc2093_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc2093_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc2093_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc2093_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc2093_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (gc2093_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc2093_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, gc2093_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc2093_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int gc2093_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc2093_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + if (gc2093_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc2093_addr_byte + gc2093_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + ret = read(g_fd[ViPipe], buf, gc2093_addr_byte + gc2093_data_byte); + //syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void gc2093_standby(VI_PIPE ViPipe) +{ + gc2093_write_register(ViPipe, 0x003e, 0x00); + gc2093_write_register(ViPipe, 0x03f7, 0x00); + gc2093_write_register(ViPipe, 0x03fc, 0x01); + gc2093_write_register(ViPipe, 0x03f9, 0x41); + + printf("gc2093_standby\n"); +} + +void gc2093_restart(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastGc2093[ViPipe]->enWDRMode; + u8ImgMode = g_pastGc2093[ViPipe]->u8ImgMode; + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == GC2093_MODE_1920X1080P30_WDR) { + gc2093_write_register(ViPipe, 0x03f9, 0x40); + usleep(1); + gc2093_write_register(ViPipe, 0x03f7, 0x01); + gc2093_write_register(ViPipe, 0x03fc, 0x8e); + gc2093_write_register(ViPipe, 0x003e, 0x91); + } + } else { + gc2093_write_register(ViPipe, 0x03f9, 0x42); + usleep(1); + gc2093_write_register(ViPipe, 0x03f7, 0x11); + gc2093_write_register(ViPipe, 0x03fc, 0x8e); + gc2093_write_register(ViPipe, 0x003e, 0x91); + } + + printf("gc2093_restart\n"); +} + +void gc2093_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc2093[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc2093_write_register(ViPipe, + g_pastGc2093[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc2093[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define GC2093_CHIP_ID_ADDR_H 0x03f0 +#define GC2093_CHIP_ID_ADDR_L 0x03f1 +#define GC2093_CHIP_ID 0x2093 + +void gc2093_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 value = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + value = 0x01; + break; + case ISP_SNS_FLIP: + value = 0x02; + break; + case ISP_SNS_MIRROR_FLIP: + value = 0x03; + break; + default: + return; + } + gc2093_write_register(ViPipe, 0xfe, 0x00); + gc2093_write_register(ViPipe, 0x17, value); +} + +int gc2093_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc2093_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc2093_read_register(ViPipe, GC2093_CHIP_ID_ADDR_H); + nVal2 = gc2093_read_register(ViPipe, GC2093_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC2093_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc2093_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastGc2093[ViPipe]->enWDRMode; + u8ImgMode = g_pastGc2093[ViPipe]->u8ImgMode; + + gc2093_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == GC2093_MODE_1920X1080P30_WDR) { + gc2093_wdr_1080p30_init(ViPipe); + } + } else { + gc2093_linear_1080p30_init(ViPipe); + } + + + g_pastGc2093[ViPipe]->bInit = CVI_TRUE; +} + +void gc2093_exit(VI_PIPE ViPipe) +{ + gc2093_i2c_exit(ViPipe); +} + +static void gc2093_linear_1080p30_init(VI_PIPE ViPipe) +{ + delay_ms(10); + /****system****/ + gc2093_write_register(ViPipe, 0x03fe, 0xf0); + gc2093_write_register(ViPipe, 0x03fe, 0xf0); + gc2093_write_register(ViPipe, 0x03fe, 0xf0); + gc2093_write_register(ViPipe, 0x03fe, 0x00); + gc2093_write_register(ViPipe, 0x03f2, 0x00); + gc2093_write_register(ViPipe, 0x03f3, 0x00); + gc2093_write_register(ViPipe, 0x03f4, 0x36); + gc2093_write_register(ViPipe, 0x03f5, 0xc0); + gc2093_write_register(ViPipe, 0x03f6, 0x0B); + gc2093_write_register(ViPipe, 0x03f7, 0x11); + gc2093_write_register(ViPipe, 0x03f8, 0x2A); + gc2093_write_register(ViPipe, 0x03f9, 0x42); + gc2093_write_register(ViPipe, 0x03fc, 0x8e); + /****CISCTL & ANALOG*/ + gc2093_write_register(ViPipe, 0x0087, 0x18); + gc2093_write_register(ViPipe, 0x00ee, 0x30); + gc2093_write_register(ViPipe, 0x00d0, 0xbf); + gc2093_write_register(ViPipe, 0x01a0, 0x00); + gc2093_write_register(ViPipe, 0x01a4, 0x40); + gc2093_write_register(ViPipe, 0x01a5, 0x40); + gc2093_write_register(ViPipe, 0x01a6, 0x40); + gc2093_write_register(ViPipe, 0x01af, 0x09); + gc2093_write_register(ViPipe, 0x0003, 0x04); + gc2093_write_register(ViPipe, 0x0004, 0x65); + gc2093_write_register(ViPipe, 0x0005, 0x05); + gc2093_write_register(ViPipe, 0x0006, 0x78); + gc2093_write_register(ViPipe, 0x0007, 0x00); + gc2093_write_register(ViPipe, 0x0008, 0x11); + gc2093_write_register(ViPipe, 0x0009, 0x00); + gc2093_write_register(ViPipe, 0x000a, 0x02); + gc2093_write_register(ViPipe, 0x000b, 0x00); + gc2093_write_register(ViPipe, 0x000c, 0x04); + gc2093_write_register(ViPipe, 0x000d, 0x04); + gc2093_write_register(ViPipe, 0x000e, 0x40); + gc2093_write_register(ViPipe, 0x000f, 0x07); + gc2093_write_register(ViPipe, 0x0010, 0x8c); + gc2093_write_register(ViPipe, 0x0013, 0x15); + gc2093_write_register(ViPipe, 0x0019, 0x0c); + gc2093_write_register(ViPipe, 0x0041, 0x04); + gc2093_write_register(ViPipe, 0x0042, 0x65); + gc2093_write_register(ViPipe, 0x0053, 0x60); + gc2093_write_register(ViPipe, 0x008d, 0x92); + gc2093_write_register(ViPipe, 0x0090, 0x00); + gc2093_write_register(ViPipe, 0x00c7, 0xe1); + gc2093_write_register(ViPipe, 0x001b, 0x73); + gc2093_write_register(ViPipe, 0x0028, 0x0d); + gc2093_write_register(ViPipe, 0x0029, 0x40); + gc2093_write_register(ViPipe, 0x002b, 0x04); + gc2093_write_register(ViPipe, 0x002e, 0x23); + gc2093_write_register(ViPipe, 0x0037, 0x03); + gc2093_write_register(ViPipe, 0x0043, 0x04); + gc2093_write_register(ViPipe, 0x0044, 0x30); + gc2093_write_register(ViPipe, 0x004a, 0x01); + gc2093_write_register(ViPipe, 0x004b, 0x28); + gc2093_write_register(ViPipe, 0x0055, 0x30); + gc2093_write_register(ViPipe, 0x0066, 0x3f); + gc2093_write_register(ViPipe, 0x0068, 0x3f); + gc2093_write_register(ViPipe, 0x006b, 0x44); + gc2093_write_register(ViPipe, 0x0077, 0x00); + gc2093_write_register(ViPipe, 0x0078, 0x20); + gc2093_write_register(ViPipe, 0x007c, 0xa1); + gc2093_write_register(ViPipe, 0x00ce, 0x7c); + gc2093_write_register(ViPipe, 0x00d3, 0xd4); + gc2093_write_register(ViPipe, 0x00e6, 0x50); + /*gain*/ + gc2093_write_register(ViPipe, 0x00b6, 0xc0); + gc2093_write_register(ViPipe, 0x00b0, 0x68); + gc2093_write_register(ViPipe, 0x00b3, 0x00); + gc2093_write_register(ViPipe, 0x00b8, 0x01); + gc2093_write_register(ViPipe, 0x00b9, 0x00); + gc2093_write_register(ViPipe, 0x00b1, 0x01); + gc2093_write_register(ViPipe, 0x00b2, 0x00); + /*isp*/ + gc2093_write_register(ViPipe, 0x0101, 0x0c); + gc2093_write_register(ViPipe, 0x0102, 0x89); + gc2093_write_register(ViPipe, 0x0104, 0x01); + gc2093_write_register(ViPipe, 0x0107, 0xa6); + gc2093_write_register(ViPipe, 0x0108, 0xa9); + gc2093_write_register(ViPipe, 0x0109, 0xa8); + gc2093_write_register(ViPipe, 0x010a, 0xa7); + gc2093_write_register(ViPipe, 0x010b, 0xff); + gc2093_write_register(ViPipe, 0x010c, 0xff); + gc2093_write_register(ViPipe, 0x010f, 0x00); + gc2093_write_register(ViPipe, 0x0158, 0x00); + gc2093_write_register(ViPipe, 0x0428, 0x86); + gc2093_write_register(ViPipe, 0x0429, 0x86); + gc2093_write_register(ViPipe, 0x042a, 0x86); + gc2093_write_register(ViPipe, 0x042b, 0x68); + gc2093_write_register(ViPipe, 0x042c, 0x68); + gc2093_write_register(ViPipe, 0x042d, 0x68); + gc2093_write_register(ViPipe, 0x042e, 0x68); + gc2093_write_register(ViPipe, 0x042f, 0x68); + gc2093_write_register(ViPipe, 0x0430, 0x4f); + gc2093_write_register(ViPipe, 0x0431, 0x68); + gc2093_write_register(ViPipe, 0x0432, 0x67); + gc2093_write_register(ViPipe, 0x0433, 0x66); + gc2093_write_register(ViPipe, 0x0434, 0x66); + gc2093_write_register(ViPipe, 0x0435, 0x66); + gc2093_write_register(ViPipe, 0x0436, 0x66); + gc2093_write_register(ViPipe, 0x0437, 0x66); + gc2093_write_register(ViPipe, 0x0438, 0x62); + gc2093_write_register(ViPipe, 0x0439, 0x62); + gc2093_write_register(ViPipe, 0x043a, 0x62); + gc2093_write_register(ViPipe, 0x043b, 0x62); + gc2093_write_register(ViPipe, 0x043c, 0x62); + gc2093_write_register(ViPipe, 0x043d, 0x62); + gc2093_write_register(ViPipe, 0x043e, 0x62); + gc2093_write_register(ViPipe, 0x043f, 0x62); + /*dark sun*/ + gc2093_write_register(ViPipe, 0x0123, 0x08); + gc2093_write_register(ViPipe, 0x0123, 0x00); + gc2093_write_register(ViPipe, 0x0120, 0x01); + gc2093_write_register(ViPipe, 0x0121, 0x04); + gc2093_write_register(ViPipe, 0x0122, 0x65); + gc2093_write_register(ViPipe, 0x0124, 0x03); + gc2093_write_register(ViPipe, 0x0125, 0xff); + gc2093_write_register(ViPipe, 0x001a, 0x8c); + gc2093_write_register(ViPipe, 0x00c6, 0xe0); + /*blk*/ + gc2093_write_register(ViPipe, 0x0026, 0x30); + gc2093_write_register(ViPipe, 0x0142, 0x00); + gc2093_write_register(ViPipe, 0x0149, 0x1e); + gc2093_write_register(ViPipe, 0x014a, 0x0f); + gc2093_write_register(ViPipe, 0x014b, 0x00); + gc2093_write_register(ViPipe, 0x0155, 0x07); + gc2093_write_register(ViPipe, 0x0414, 0x78); + gc2093_write_register(ViPipe, 0x0415, 0x78); + gc2093_write_register(ViPipe, 0x0416, 0x78); + gc2093_write_register(ViPipe, 0x0417, 0x78); + gc2093_write_register(ViPipe, 0x04e0, 0x18); + /*window*/ + gc2093_write_register(ViPipe, 0x0192, 0x02); + gc2093_write_register(ViPipe, 0x0194, 0x03); + gc2093_write_register(ViPipe, 0x0195, 0x04); + gc2093_write_register(ViPipe, 0x0196, 0x38); + gc2093_write_register(ViPipe, 0x0197, 0x07); + gc2093_write_register(ViPipe, 0x0198, 0x80); + /****DVP & MIPI****/ + gc2093_write_register(ViPipe, 0x019a, 0x06); + gc2093_write_register(ViPipe, 0x007b, 0x2a); + gc2093_write_register(ViPipe, 0x0023, 0x2d); + gc2093_write_register(ViPipe, 0x0201, 0x27); + gc2093_write_register(ViPipe, 0x0202, 0x56); + gc2093_write_register(ViPipe, 0x0203, 0xb6); + gc2093_write_register(ViPipe, 0x0212, 0x80); + gc2093_write_register(ViPipe, 0x0213, 0x07); + gc2093_write_register(ViPipe, 0x0215, 0x10); + gc2093_write_register(ViPipe, 0x003e, 0x91); + + gc2093_default_reg_init(ViPipe); + delay_ms(80); + + printf("ViPipe:%d,===GC2093 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +static void gc2093_wdr_1080p30_init(VI_PIPE ViPipe) +{ + delay_ms(10); + /****system**/ + gc2093_write_register(ViPipe, 0x03fe, 0xf0); + gc2093_write_register(ViPipe, 0x03fe, 0xf0); + gc2093_write_register(ViPipe, 0x03fe, 0xf0); + gc2093_write_register(ViPipe, 0x03fe, 0x00); + gc2093_write_register(ViPipe, 0x03f2, 0x00); + gc2093_write_register(ViPipe, 0x03f3, 0x00); + gc2093_write_register(ViPipe, 0x03f4, 0x36); + gc2093_write_register(ViPipe, 0x03f5, 0xc0); + gc2093_write_register(ViPipe, 0x03f6, 0x0B); + gc2093_write_register(ViPipe, 0x03f7, 0x01); + gc2093_write_register(ViPipe, 0x03f8, 0x58); + gc2093_write_register(ViPipe, 0x03f9, 0x40); + gc2093_write_register(ViPipe, 0x03fc, 0x8e); + /****CISCTL**/ + gc2093_write_register(ViPipe, 0x0087, 0x18); + gc2093_write_register(ViPipe, 0x00ee, 0x30); + gc2093_write_register(ViPipe, 0x00d0, 0xbf); + gc2093_write_register(ViPipe, 0x01a0, 0x00); + gc2093_write_register(ViPipe, 0x01a4, 0x40); + gc2093_write_register(ViPipe, 0x01a5, 0x40); + gc2093_write_register(ViPipe, 0x01a6, 0x40); + gc2093_write_register(ViPipe, 0x01af, 0x09); + gc2093_write_register(ViPipe, 0x0001, 0x00); + gc2093_write_register(ViPipe, 0x0002, 0x02); + gc2093_write_register(ViPipe, 0x0003, 0x04); + gc2093_write_register(ViPipe, 0x0004, 0x02); + gc2093_write_register(ViPipe, 0x0005, 0x02); + gc2093_write_register(ViPipe, 0x0006, 0x94); + gc2093_write_register(ViPipe, 0x0007, 0x00); + gc2093_write_register(ViPipe, 0x0008, 0x11); + gc2093_write_register(ViPipe, 0x0009, 0x00); + gc2093_write_register(ViPipe, 0x000a, 0x02); + gc2093_write_register(ViPipe, 0x000b, 0x00); + gc2093_write_register(ViPipe, 0x000c, 0x04); + gc2093_write_register(ViPipe, 0x000d, 0x04); + gc2093_write_register(ViPipe, 0x000e, 0x40); + gc2093_write_register(ViPipe, 0x000f, 0x07); + gc2093_write_register(ViPipe, 0x0010, 0x8c); + gc2093_write_register(ViPipe, 0x0013, 0x15); + gc2093_write_register(ViPipe, 0x0019, 0x0c); + gc2093_write_register(ViPipe, 0x0041, 0x04); + gc2093_write_register(ViPipe, 0x0042, 0xE2); + gc2093_write_register(ViPipe, 0x0053, 0x60); + gc2093_write_register(ViPipe, 0x008d, 0x92); + gc2093_write_register(ViPipe, 0x0090, 0x00); + gc2093_write_register(ViPipe, 0x00c7, 0xe1); + gc2093_write_register(ViPipe, 0x001b, 0x73); + gc2093_write_register(ViPipe, 0x0028, 0x0d); + gc2093_write_register(ViPipe, 0x0029, 0x24); + gc2093_write_register(ViPipe, 0x002b, 0x04); + gc2093_write_register(ViPipe, 0x002e, 0x23); + gc2093_write_register(ViPipe, 0x0037, 0x03); + gc2093_write_register(ViPipe, 0x0043, 0x04); + gc2093_write_register(ViPipe, 0x0044, 0x28); + gc2093_write_register(ViPipe, 0x004a, 0x01); + gc2093_write_register(ViPipe, 0x004b, 0x20); + gc2093_write_register(ViPipe, 0x0055, 0x28); + gc2093_write_register(ViPipe, 0x0066, 0x3f); + gc2093_write_register(ViPipe, 0x0068, 0x3f); + gc2093_write_register(ViPipe, 0x006b, 0x44); + gc2093_write_register(ViPipe, 0x0077, 0x00); + gc2093_write_register(ViPipe, 0x0078, 0x20); + gc2093_write_register(ViPipe, 0x007c, 0xa1); + gc2093_write_register(ViPipe, 0x00ce, 0x7c); + gc2093_write_register(ViPipe, 0x00d3, 0xd4); + gc2093_write_register(ViPipe, 0x00e6, 0x50); + /*gain*/ + gc2093_write_register(ViPipe, 0x00b6, 0xc0); + gc2093_write_register(ViPipe, 0x00b0, 0x68); + /*isp*/ + gc2093_write_register(ViPipe, 0x0101, 0x0c); + gc2093_write_register(ViPipe, 0x0102, 0x89); + gc2093_write_register(ViPipe, 0x0104, 0x01); + gc2093_write_register(ViPipe, 0x010e, 0x01); + gc2093_write_register(ViPipe, 0x010f, 0x00); + gc2093_write_register(ViPipe, 0x0158, 0x00); + /*dark sun*/ + gc2093_write_register(ViPipe, 0x0123, 0x08); + gc2093_write_register(ViPipe, 0x0123, 0x00); + gc2093_write_register(ViPipe, 0x0120, 0x01); + gc2093_write_register(ViPipe, 0x0121, 0x04); + gc2093_write_register(ViPipe, 0x0122, 0xd8); + gc2093_write_register(ViPipe, 0x0124, 0x03); + gc2093_write_register(ViPipe, 0x0125, 0xff); + gc2093_write_register(ViPipe, 0x001a, 0x8c); + gc2093_write_register(ViPipe, 0x00c6, 0xe0); + /*blk*/ + gc2093_write_register(ViPipe, 0x0026, 0x30); + gc2093_write_register(ViPipe, 0x0142, 0x00); + gc2093_write_register(ViPipe, 0x0149, 0x1e); + gc2093_write_register(ViPipe, 0x014a, 0x0f); + gc2093_write_register(ViPipe, 0x014b, 0x00); + gc2093_write_register(ViPipe, 0x0155, 0x07); + gc2093_write_register(ViPipe, 0x0414, 0x78); + gc2093_write_register(ViPipe, 0x0415, 0x78); + gc2093_write_register(ViPipe, 0x0416, 0x78); + gc2093_write_register(ViPipe, 0x0417, 0x78); + gc2093_write_register(ViPipe, 0x0454, 0x78); + gc2093_write_register(ViPipe, 0x0455, 0x78); + gc2093_write_register(ViPipe, 0x0456, 0x78); + gc2093_write_register(ViPipe, 0x0457, 0x78); + gc2093_write_register(ViPipe, 0x04e0, 0x18); + /*window*/ + gc2093_write_register(ViPipe, 0x0192, 0x02); + gc2093_write_register(ViPipe, 0x0194, 0x03); + gc2093_write_register(ViPipe, 0x0195, 0x04); + gc2093_write_register(ViPipe, 0x0196, 0x38); + gc2093_write_register(ViPipe, 0x0197, 0x07); + gc2093_write_register(ViPipe, 0x0198, 0x80); + /****DVP**/ + gc2093_write_register(ViPipe, 0x019a, 0x06); + gc2093_write_register(ViPipe, 0x007b, 0x2a); + gc2093_write_register(ViPipe, 0x0023, 0x2d); + gc2093_write_register(ViPipe, 0x0201, 0x27); + gc2093_write_register(ViPipe, 0x0202, 0x56); + gc2093_write_register(ViPipe, 0x0203, 0xb6); + gc2093_write_register(ViPipe, 0x0212, 0x80); + gc2093_write_register(ViPipe, 0x0213, 0x07); + gc2093_write_register(ViPipe, 0x0215, 0x10); + gc2093_write_register(ViPipe, 0x003e, 0x91); + /****HDR EN**/ + gc2093_write_register(ViPipe, 0x0027, 0x71); + gc2093_write_register(ViPipe, 0x0215, 0x92); + gc2093_write_register(ViPipe, 0x024d, 0x01); + gc2093_default_reg_init(ViPipe); + delay_ms(80); + + printf("ViPipe:%d,===GC2093 1080P 30fps 10bit LINE WDR2TO1 OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2145/Makefile b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2145/Makefile new file mode 100644 index 000000000..ba45cb01b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2145/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc2145.a +TARGET_SO = $(MW_LIB)/libsns_gc2145.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2145/gc2145_cmos.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2145/gc2145_cmos.c new file mode 100644 index 000000000..ae1f61ced --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2145/gc2145_cmos.c @@ -0,0 +1,305 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "gc2145_cmos_ex.h" +#include "gc2145_cmos_param.h" + +#define GC2145_ID 0x2145 +#define GC2145_I2C_ADDR_1 0x3f +#define GC2145_I2C_ADDR_2 0x37 +#define GC2145_I2C_ADDR_IS_VALID(addr) ((addr) == GC2145_I2C_ADDR_1 || (addr) == GC2145_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc2145[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC2145_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc2145[dev]) +#define GC2145_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc2145[dev] = pstCtx) +#define GC2145_SENSOR_RESET_CTX(dev) (g_pastGc2145[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc2145_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +#define GC2145_RES_IS_1200P(w, h) ((w) == 1600 && (h) == 1200) + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC2145_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2145_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astGc2145_mode; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->stImg, sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC2145_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstCfg0 = &pstSnsState->astSyncInfo[0]; + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC2145_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 12) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC2145_RES_IS_1200P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC2145_MODE_1600X1200P12; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2145_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC2145_MODE_1600X1200P12; + pstSnsState->enWDRMode = WDR_MODE_NONE; +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2145_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc2145_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astGc2145_mode.stImg.stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astGc2145_mode.stImg.stSnsSize.u32Height; + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc2145_rx_attr; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc2145_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc2145_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (GC2145_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc2145_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc2145_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc2145_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2145_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC2145_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2145_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC2145_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + (void) pstAeLib; + (void) pstAwbLib; + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC2145_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + (void) pstAeLib; + (void) pstAwbLib; + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC2145_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc2145_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc2145_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = CVI_NULL, + .pfnRestart = CVI_NULL, + .pfnWriteReg = gc2145_write_register, + .pfnReadReg = gc2145_read_register, + .pfnSetBusInfo = gc2145_set_bus_info, + .pfnSetInit = CVI_NULL, + .pfnMirrorFlip = CVI_NULL, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = CVI_NULL, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2145/gc2145_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2145/gc2145_cmos_ex.h new file mode 100644 index 000000000..34bb36b24 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2145/gc2145_cmos_ex.h @@ -0,0 +1,64 @@ +#ifndef __GC2145_CMOS_EX_H_ +#define __GC2145_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +typedef enum _GC2145_MODE_E { + GC2145_MODE_1600X1200P12 = 0, + GC2145_MODE_NUM +} GC2145_SLAVE_MODE_E; + +typedef struct _GC2145_MODE_S { + ISP_WDR_SIZE_S stImg; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp; + SNS_ATTR_LARGE_S stAgain; + SNS_ATTR_LARGE_S stDgain; + char name[64]; +} GC2145_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc2145[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc2145_BusInfo[]; +extern CVI_U8 gc2145_i2c_addr; +extern const CVI_U32 gc2145_addr_byte; +extern const CVI_U32 gc2145_data_byte; +extern void gc2145_init(VI_PIPE ViPipe); +extern void gc2145_exit(VI_PIPE ViPipe); +extern void gc2145_standby(VI_PIPE ViPipe); +extern void gc2145_restart(VI_PIPE ViPipe); +extern int gc2145_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc2145_read_register(VI_PIPE ViPipe, int addr); +extern void gc2145_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int gc2145_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2145_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2145/gc2145_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2145/gc2145_cmos_param.h new file mode 100644 index 000000000..ab7c9caba --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2145/gc2145_cmos_param.h @@ -0,0 +1,72 @@ +#ifndef __GC2145_CMOS_PARAM_H_ +#define __GC2145_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2145_cmos_ex.h" + +static const GC2145_MODE_S g_astGc2145_mode = { + .name = "1600X1200P12", + .stImg = { + .stSnsSize = { + .u32Width = 1600, + .u32Height = 1200, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1600, + .u32Height = 1200, + }, + .stMaxSize = { + .u32Width = 1600, + .u32Height = 1200, + }, + }, +}; + +struct combo_dev_attr_s gc2145_rx_attr = { + .input_mode = INPUT_MODE_BT601, + .mac_clk = RX_MAC_CLK_400M, + .ttl_attr = { + .vi = TTL_VI_SRC_VI1, + .ttl_fmt = TTL_VSDE_11B, + .raw_data_type = RAW_DATA_8BIT, + .func = { + 8, -1, -1, 7, + 2, 3, 4, 5, + 6, 9, 10, 1, + -1, -1, -1, -1, + -1, -1, -1, -1, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2145_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc2145/gc2145_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2145/gc2145_sensor_ctl.c new file mode 100644 index 000000000..20c98157b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc2145/gc2145_sensor_ctl.c @@ -0,0 +1,875 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2145_cmos_ex.h" + +static void gc2145_linear_1200p12_init(VI_PIPE ViPipe); + +CVI_U8 gc2145_i2c_addr = 0x3C;//0x78 +const CVI_U32 gc2145_addr_byte = 1; +const CVI_U32 gc2145_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc2145_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc2145_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc2145_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc2145_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc2145_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (gc2145_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc2145_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, gc2145_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc2145_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int gc2145_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc2145_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (gc2145_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc2145_addr_byte + gc2145_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + //syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +#define GC2145_CHIP_ID_ADDR_H 0xf0 +#define GC2145_CHIP_ID_ADDR_L 0xf1 +#define GC2145_CHIP_ID 0x2145 + +int gc2145_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc2145_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc2145_read_register(ViPipe, GC2145_CHIP_ID_ADDR_H); + nVal2 = gc2145_read_register(ViPipe, GC2145_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC2145_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc2145_init(VI_PIPE ViPipe) +{ + gc2145_i2c_init(ViPipe); + + gc2145_linear_1200p12_init(ViPipe); + + g_pastGc2145[ViPipe]->bInit = CVI_TRUE; +} + +void gc2145_exit(VI_PIPE ViPipe) +{ + gc2145_i2c_exit(ViPipe); +} + +static void gc2145_linear_1200p12_init(VI_PIPE ViPipe) +{ + gc2145_write_register(ViPipe, 0xfe, 0xf0); + gc2145_write_register(ViPipe, 0xfe, 0xf0); + gc2145_write_register(ViPipe, 0xfe, 0xf0); + gc2145_write_register(ViPipe, 0xfc, 0x06); + gc2145_write_register(ViPipe, 0xf6, 0x00); + gc2145_write_register(ViPipe, 0xf7, 0x1d); + gc2145_write_register(ViPipe, 0xf8, 0x84); + gc2145_write_register(ViPipe, 0xfa, 0x00); + gc2145_write_register(ViPipe, 0xf9, 0xfe); + gc2145_write_register(ViPipe, 0xf2, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0x03, 0x04); + gc2145_write_register(ViPipe, 0x04, 0xe2); + gc2145_write_register(ViPipe, 0x09, 0x00); + gc2145_write_register(ViPipe, 0x0a, 0x00); + gc2145_write_register(ViPipe, 0x0b, 0x00); + gc2145_write_register(ViPipe, 0x0c, 0x00); + gc2145_write_register(ViPipe, 0x0d, 0x04); + gc2145_write_register(ViPipe, 0x0e, 0xc0); + gc2145_write_register(ViPipe, 0x0f, 0x06); + gc2145_write_register(ViPipe, 0x10, 0x52); + gc2145_write_register(ViPipe, 0x12, 0x2e); + gc2145_write_register(ViPipe, 0x17, 0x14); + gc2145_write_register(ViPipe, 0x18, 0x22); + gc2145_write_register(ViPipe, 0x19, 0x0e); + gc2145_write_register(ViPipe, 0x1a, 0x01); + gc2145_write_register(ViPipe, 0x1b, 0x4b); + gc2145_write_register(ViPipe, 0x1c, 0x07); + gc2145_write_register(ViPipe, 0x1d, 0x10); + gc2145_write_register(ViPipe, 0x1e, 0x88); + gc2145_write_register(ViPipe, 0x1f, 0x78); + gc2145_write_register(ViPipe, 0x20, 0x03); + gc2145_write_register(ViPipe, 0x21, 0x40); + gc2145_write_register(ViPipe, 0x22, 0xa0); + gc2145_write_register(ViPipe, 0x24, 0x16); + gc2145_write_register(ViPipe, 0x25, 0x01); + gc2145_write_register(ViPipe, 0x26, 0x10); + gc2145_write_register(ViPipe, 0x2d, 0x60); + gc2145_write_register(ViPipe, 0x30, 0x01); + gc2145_write_register(ViPipe, 0x31, 0x90); + gc2145_write_register(ViPipe, 0x33, 0x06); + gc2145_write_register(ViPipe, 0x34, 0x01); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0x80, 0x7f); + gc2145_write_register(ViPipe, 0x81, 0x26); + gc2145_write_register(ViPipe, 0x82, 0xfa); + gc2145_write_register(ViPipe, 0x83, 0x00); + gc2145_write_register(ViPipe, 0x84, 0x00); + gc2145_write_register(ViPipe, 0x86, 0x02); + gc2145_write_register(ViPipe, 0x88, 0x03); + gc2145_write_register(ViPipe, 0x89, 0x03); + gc2145_write_register(ViPipe, 0x85, 0x08); + gc2145_write_register(ViPipe, 0x8a, 0x00); + gc2145_write_register(ViPipe, 0x8b, 0x00); + gc2145_write_register(ViPipe, 0xb0, 0x55); + gc2145_write_register(ViPipe, 0xc3, 0x00); + gc2145_write_register(ViPipe, 0xc4, 0x80); + gc2145_write_register(ViPipe, 0xc5, 0x90); + gc2145_write_register(ViPipe, 0xc6, 0x3b); + gc2145_write_register(ViPipe, 0xc7, 0x46); + gc2145_write_register(ViPipe, 0xec, 0x06); + gc2145_write_register(ViPipe, 0xed, 0x04); + gc2145_write_register(ViPipe, 0xee, 0x60); + gc2145_write_register(ViPipe, 0xef, 0x90); + gc2145_write_register(ViPipe, 0xb6, 0x01); + gc2145_write_register(ViPipe, 0x90, 0x01); + gc2145_write_register(ViPipe, 0x91, 0x00); + gc2145_write_register(ViPipe, 0x92, 0x00); + gc2145_write_register(ViPipe, 0x93, 0x00); + gc2145_write_register(ViPipe, 0x94, 0x00); + gc2145_write_register(ViPipe, 0x95, 0x04); + gc2145_write_register(ViPipe, 0x96, 0xb0); + gc2145_write_register(ViPipe, 0x97, 0x06); + gc2145_write_register(ViPipe, 0x98, 0x40); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0x40, 0x42); + gc2145_write_register(ViPipe, 0x41, 0x00); + gc2145_write_register(ViPipe, 0x43, 0x5b); + gc2145_write_register(ViPipe, 0x5e, 0x00); + gc2145_write_register(ViPipe, 0x5f, 0x00); + gc2145_write_register(ViPipe, 0x60, 0x00); + gc2145_write_register(ViPipe, 0x61, 0x00); + gc2145_write_register(ViPipe, 0x62, 0x00); + gc2145_write_register(ViPipe, 0x63, 0x00); + gc2145_write_register(ViPipe, 0x64, 0x00); + gc2145_write_register(ViPipe, 0x65, 0x00); + gc2145_write_register(ViPipe, 0x66, 0x20); + gc2145_write_register(ViPipe, 0x67, 0x20); + gc2145_write_register(ViPipe, 0x68, 0x20); + gc2145_write_register(ViPipe, 0x69, 0x20); + gc2145_write_register(ViPipe, 0x76, 0x00); + gc2145_write_register(ViPipe, 0x6a, 0x08); + gc2145_write_register(ViPipe, 0x6b, 0x08); + gc2145_write_register(ViPipe, 0x6c, 0x08); + gc2145_write_register(ViPipe, 0x6d, 0x08); + gc2145_write_register(ViPipe, 0x6e, 0x08); + gc2145_write_register(ViPipe, 0x6f, 0x08); + gc2145_write_register(ViPipe, 0x70, 0x08); + gc2145_write_register(ViPipe, 0x71, 0x08); + gc2145_write_register(ViPipe, 0x76, 0x00); + gc2145_write_register(ViPipe, 0x72, 0xf0); + gc2145_write_register(ViPipe, 0x7e, 0x3c); + gc2145_write_register(ViPipe, 0x7f, 0x00); + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0x48, 0x15); + + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x01, 0x04); + gc2145_write_register(ViPipe, 0x02, 0xc0); + gc2145_write_register(ViPipe, 0x03, 0x04); + gc2145_write_register(ViPipe, 0x04, 0x90); + gc2145_write_register(ViPipe, 0x05, 0x30); + gc2145_write_register(ViPipe, 0x06, 0x90); + gc2145_write_register(ViPipe, 0x07, 0x30); + gc2145_write_register(ViPipe, 0x08, 0x80); + gc2145_write_register(ViPipe, 0x09, 0x00); + gc2145_write_register(ViPipe, 0x0a, 0x82); + gc2145_write_register(ViPipe, 0x0b, 0x11); + gc2145_write_register(ViPipe, 0x0c, 0x10); + gc2145_write_register(ViPipe, 0x11, 0x10); + gc2145_write_register(ViPipe, 0x13, 0x7b); + gc2145_write_register(ViPipe, 0x17, 0x00); + gc2145_write_register(ViPipe, 0x1c, 0x11); + gc2145_write_register(ViPipe, 0x1e, 0x61); + gc2145_write_register(ViPipe, 0x1f, 0x35); + gc2145_write_register(ViPipe, 0x20, 0x40); + gc2145_write_register(ViPipe, 0x22, 0x40); + gc2145_write_register(ViPipe, 0x23, 0x20); + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0x0f, 0x04); + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x12, 0x35); + gc2145_write_register(ViPipe, 0x15, 0xb0); + gc2145_write_register(ViPipe, 0x10, 0x31); + gc2145_write_register(ViPipe, 0x3e, 0x28); + gc2145_write_register(ViPipe, 0x3f, 0xb0); + gc2145_write_register(ViPipe, 0x40, 0x90); + gc2145_write_register(ViPipe, 0x41, 0x0f); + + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0x90, 0x6c); + gc2145_write_register(ViPipe, 0x91, 0x03); + gc2145_write_register(ViPipe, 0x92, 0xcb); + gc2145_write_register(ViPipe, 0x94, 0x33); + gc2145_write_register(ViPipe, 0x95, 0x84); + gc2145_write_register(ViPipe, 0x97, 0x65); + gc2145_write_register(ViPipe, 0xa2, 0x11); + gc2145_write_register(ViPipe, 0xfe, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0x80, 0xc1); + gc2145_write_register(ViPipe, 0x81, 0x08); + gc2145_write_register(ViPipe, 0x82, 0x05); + gc2145_write_register(ViPipe, 0x83, 0x08); + gc2145_write_register(ViPipe, 0x84, 0x0a); + gc2145_write_register(ViPipe, 0x86, 0xf0); + gc2145_write_register(ViPipe, 0x87, 0x50); + gc2145_write_register(ViPipe, 0x88, 0x15); + gc2145_write_register(ViPipe, 0x89, 0xb0); + gc2145_write_register(ViPipe, 0x8a, 0x30); + gc2145_write_register(ViPipe, 0x8b, 0x10); + + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x21, 0x04); + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0xa3, 0x50); + gc2145_write_register(ViPipe, 0xa4, 0x20); + gc2145_write_register(ViPipe, 0xa5, 0x40); + gc2145_write_register(ViPipe, 0xa6, 0x80); + gc2145_write_register(ViPipe, 0xab, 0x40); + gc2145_write_register(ViPipe, 0xae, 0x0c); + gc2145_write_register(ViPipe, 0xb3, 0x46); + gc2145_write_register(ViPipe, 0xb4, 0x64); + gc2145_write_register(ViPipe, 0xb6, 0x38); + gc2145_write_register(ViPipe, 0xb7, 0x01); + gc2145_write_register(ViPipe, 0xb9, 0x2b); + gc2145_write_register(ViPipe, 0x3c, 0x04); + gc2145_write_register(ViPipe, 0x3d, 0x15); + gc2145_write_register(ViPipe, 0x4b, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x20); + gc2145_write_register(ViPipe, 0xfe, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0x10, 0x09); + gc2145_write_register(ViPipe, 0x11, 0x0d); + gc2145_write_register(ViPipe, 0x12, 0x13); + gc2145_write_register(ViPipe, 0x13, 0x19); + gc2145_write_register(ViPipe, 0x14, 0x27); + gc2145_write_register(ViPipe, 0x15, 0x37); + gc2145_write_register(ViPipe, 0x16, 0x45); + gc2145_write_register(ViPipe, 0x17, 0x53); + gc2145_write_register(ViPipe, 0x18, 0x69); + gc2145_write_register(ViPipe, 0x19, 0x7d); + gc2145_write_register(ViPipe, 0x1a, 0x8f); + gc2145_write_register(ViPipe, 0x1b, 0x9d); + gc2145_write_register(ViPipe, 0x1c, 0xa9); + gc2145_write_register(ViPipe, 0x1d, 0xbd); + gc2145_write_register(ViPipe, 0x1e, 0xcd); + gc2145_write_register(ViPipe, 0x1f, 0xd9); + gc2145_write_register(ViPipe, 0x20, 0xe3); + gc2145_write_register(ViPipe, 0x21, 0xea); + gc2145_write_register(ViPipe, 0x22, 0xef); + gc2145_write_register(ViPipe, 0x23, 0xf5); + gc2145_write_register(ViPipe, 0x24, 0xf9); + gc2145_write_register(ViPipe, 0x25, 0xff); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0xc6, 0x20); + gc2145_write_register(ViPipe, 0xc7, 0x2b); + + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0x26, 0x0f); + gc2145_write_register(ViPipe, 0x27, 0x14); + gc2145_write_register(ViPipe, 0x28, 0x19); + gc2145_write_register(ViPipe, 0x29, 0x1e); + gc2145_write_register(ViPipe, 0x2a, 0x27); + gc2145_write_register(ViPipe, 0x2b, 0x33); + gc2145_write_register(ViPipe, 0x2c, 0x3b); + gc2145_write_register(ViPipe, 0x2d, 0x45); + gc2145_write_register(ViPipe, 0x2e, 0x59); + gc2145_write_register(ViPipe, 0x2f, 0x69); + gc2145_write_register(ViPipe, 0x30, 0x7c); + gc2145_write_register(ViPipe, 0x31, 0x89); + gc2145_write_register(ViPipe, 0x32, 0x98); + gc2145_write_register(ViPipe, 0x33, 0xae); + gc2145_write_register(ViPipe, 0x34, 0xc0); + gc2145_write_register(ViPipe, 0x35, 0xcf); + gc2145_write_register(ViPipe, 0x36, 0xda); + gc2145_write_register(ViPipe, 0x37, 0xe2); + gc2145_write_register(ViPipe, 0x38, 0xe9); + gc2145_write_register(ViPipe, 0x39, 0xf3); + gc2145_write_register(ViPipe, 0x3a, 0xf9); + gc2145_write_register(ViPipe, 0x3b, 0xff); + + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0xd1, 0x32); + gc2145_write_register(ViPipe, 0xd2, 0x32); + gc2145_write_register(ViPipe, 0xd3, 0x40); + gc2145_write_register(ViPipe, 0xd6, 0xf0); + gc2145_write_register(ViPipe, 0xd7, 0x10); + gc2145_write_register(ViPipe, 0xd8, 0xda); + gc2145_write_register(ViPipe, 0xdd, 0x14); + gc2145_write_register(ViPipe, 0xde, 0x86); + gc2145_write_register(ViPipe, 0xed, 0x80); + gc2145_write_register(ViPipe, 0xee, 0x00); + gc2145_write_register(ViPipe, 0xef, 0x3f); + gc2145_write_register(ViPipe, 0xd8, 0xd8); + + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x9f, 0x40); + + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0xc2, 0x14); + gc2145_write_register(ViPipe, 0xc3, 0x0d); + gc2145_write_register(ViPipe, 0xc4, 0x0c); + gc2145_write_register(ViPipe, 0xc8, 0x15); + gc2145_write_register(ViPipe, 0xc9, 0x0d); + gc2145_write_register(ViPipe, 0xca, 0x0a); + gc2145_write_register(ViPipe, 0xbc, 0x24); + gc2145_write_register(ViPipe, 0xbd, 0x10); + gc2145_write_register(ViPipe, 0xbe, 0x0b); + gc2145_write_register(ViPipe, 0xb6, 0x25); + gc2145_write_register(ViPipe, 0xb7, 0x16); + gc2145_write_register(ViPipe, 0xb8, 0x15); + gc2145_write_register(ViPipe, 0xc5, 0x00); + gc2145_write_register(ViPipe, 0xc6, 0x00); + gc2145_write_register(ViPipe, 0xc7, 0x00); + gc2145_write_register(ViPipe, 0xcb, 0x00); + gc2145_write_register(ViPipe, 0xcc, 0x00); + gc2145_write_register(ViPipe, 0xcd, 0x00); + gc2145_write_register(ViPipe, 0xbf, 0x07); + gc2145_write_register(ViPipe, 0xc0, 0x00); + gc2145_write_register(ViPipe, 0xc1, 0x00); + gc2145_write_register(ViPipe, 0xb9, 0x00); + gc2145_write_register(ViPipe, 0xba, 0x00); + gc2145_write_register(ViPipe, 0xbb, 0x00); + gc2145_write_register(ViPipe, 0xaa, 0x01); + gc2145_write_register(ViPipe, 0xab, 0x01); + gc2145_write_register(ViPipe, 0xac, 0x00); + gc2145_write_register(ViPipe, 0xad, 0x05); + gc2145_write_register(ViPipe, 0xae, 0x06); + gc2145_write_register(ViPipe, 0xaf, 0x0e); + gc2145_write_register(ViPipe, 0xb0, 0x0b); + gc2145_write_register(ViPipe, 0xb1, 0x07); + gc2145_write_register(ViPipe, 0xb2, 0x06); + gc2145_write_register(ViPipe, 0xb3, 0x17); + gc2145_write_register(ViPipe, 0xb4, 0x0e); + gc2145_write_register(ViPipe, 0xb5, 0x0e); + gc2145_write_register(ViPipe, 0xd0, 0x09); + gc2145_write_register(ViPipe, 0xd1, 0x00); + gc2145_write_register(ViPipe, 0xd2, 0x00); + gc2145_write_register(ViPipe, 0xd6, 0x08); + gc2145_write_register(ViPipe, 0xd7, 0x00); + gc2145_write_register(ViPipe, 0xd8, 0x00); + gc2145_write_register(ViPipe, 0xd9, 0x00); + gc2145_write_register(ViPipe, 0xda, 0x00); + gc2145_write_register(ViPipe, 0xdb, 0x00); + gc2145_write_register(ViPipe, 0xd3, 0x0a); + gc2145_write_register(ViPipe, 0xd4, 0x00); + gc2145_write_register(ViPipe, 0xd5, 0x00); + gc2145_write_register(ViPipe, 0xa4, 0x00); + gc2145_write_register(ViPipe, 0xa5, 0x00); + gc2145_write_register(ViPipe, 0xa6, 0x77); + gc2145_write_register(ViPipe, 0xa7, 0x77); + gc2145_write_register(ViPipe, 0xa8, 0x77); + gc2145_write_register(ViPipe, 0xa9, 0x77); + gc2145_write_register(ViPipe, 0xa1, 0x80); + gc2145_write_register(ViPipe, 0xa2, 0x80); + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0xdf, 0x0d); + gc2145_write_register(ViPipe, 0xdc, 0x25); + gc2145_write_register(ViPipe, 0xdd, 0x30); + gc2145_write_register(ViPipe, 0xe0, 0x77); + gc2145_write_register(ViPipe, 0xe1, 0x80); + gc2145_write_register(ViPipe, 0xe2, 0x77); + gc2145_write_register(ViPipe, 0xe3, 0x90); + gc2145_write_register(ViPipe, 0xe6, 0x90); + gc2145_write_register(ViPipe, 0xe7, 0xa0); + gc2145_write_register(ViPipe, 0xe8, 0x90); + gc2145_write_register(ViPipe, 0xe9, 0xa0); + gc2145_write_register(ViPipe, 0xfe, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x4f, 0x00); + gc2145_write_register(ViPipe, 0x4f, 0x00); + gc2145_write_register(ViPipe, 0x4b, 0x01); + gc2145_write_register(ViPipe, 0x4f, 0x00); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x71); + gc2145_write_register(ViPipe, 0x4e, 0x01); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x91); + gc2145_write_register(ViPipe, 0x4e, 0x01); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x70); + gc2145_write_register(ViPipe, 0x4e, 0x01); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x90); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xb0); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x8f); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x6f); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xaf); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xd0); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xf0); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xcf); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xef); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x6e); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x8e); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xae); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xce); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x4d); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x6d); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x8d); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xad); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xcd); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x4c); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x6c); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x8c); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xac); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xcc); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xcb); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x4b); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x6b); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x8b); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xab); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x8a); + gc2145_write_register(ViPipe, 0x4e, 0x04); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xaa); + gc2145_write_register(ViPipe, 0x4e, 0x04); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xca); + gc2145_write_register(ViPipe, 0x4e, 0x04); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xca); + gc2145_write_register(ViPipe, 0x4e, 0x04); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xc9); + gc2145_write_register(ViPipe, 0x4e, 0x04); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x8a); + gc2145_write_register(ViPipe, 0x4e, 0x04); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x89); + gc2145_write_register(ViPipe, 0x4e, 0x04); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xa9); + gc2145_write_register(ViPipe, 0x4e, 0x04); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x0b); + gc2145_write_register(ViPipe, 0x4e, 0x05); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x0a); + gc2145_write_register(ViPipe, 0x4e, 0x05); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xeb); + gc2145_write_register(ViPipe, 0x4e, 0x05); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xea); + gc2145_write_register(ViPipe, 0x4e, 0x05); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x09); + gc2145_write_register(ViPipe, 0x4e, 0x05); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x29); + gc2145_write_register(ViPipe, 0x4e, 0x05); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x2a); + gc2145_write_register(ViPipe, 0x4e, 0x05); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x4a); + gc2145_write_register(ViPipe, 0x4e, 0x05); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x8a); + gc2145_write_register(ViPipe, 0x4e, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x49); + gc2145_write_register(ViPipe, 0x4e, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x69); + gc2145_write_register(ViPipe, 0x4e, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x89); + gc2145_write_register(ViPipe, 0x4e, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xa9); + gc2145_write_register(ViPipe, 0x4e, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x48); + gc2145_write_register(ViPipe, 0x4e, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x68); + gc2145_write_register(ViPipe, 0x4e, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x69); + gc2145_write_register(ViPipe, 0x4e, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xca); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xc9); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xe9); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x03); + gc2145_write_register(ViPipe, 0x4d, 0x09); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xc8); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xe8); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xa7); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xc7); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xe7); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x03); + gc2145_write_register(ViPipe, 0x4d, 0x07); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4f, 0x01); + gc2145_write_register(ViPipe, 0x50, 0x80); + gc2145_write_register(ViPipe, 0x51, 0xa8); + gc2145_write_register(ViPipe, 0x52, 0x47); + gc2145_write_register(ViPipe, 0x53, 0x38); + gc2145_write_register(ViPipe, 0x54, 0xc7); + gc2145_write_register(ViPipe, 0x56, 0x0e); + gc2145_write_register(ViPipe, 0x58, 0x08); + gc2145_write_register(ViPipe, 0x5b, 0x00); + gc2145_write_register(ViPipe, 0x5c, 0x74); + gc2145_write_register(ViPipe, 0x5d, 0x8b); + gc2145_write_register(ViPipe, 0x61, 0xdb); + gc2145_write_register(ViPipe, 0x62, 0xb8); + gc2145_write_register(ViPipe, 0x63, 0x86); + gc2145_write_register(ViPipe, 0x64, 0xc0); + gc2145_write_register(ViPipe, 0x65, 0x04); + gc2145_write_register(ViPipe, 0x67, 0xa8); + gc2145_write_register(ViPipe, 0x68, 0xb0); + gc2145_write_register(ViPipe, 0x69, 0x00); + gc2145_write_register(ViPipe, 0x6a, 0xa8); + gc2145_write_register(ViPipe, 0x6b, 0xb0); + gc2145_write_register(ViPipe, 0x6c, 0xaf); + gc2145_write_register(ViPipe, 0x6d, 0x8b); + gc2145_write_register(ViPipe, 0x6e, 0x50); + gc2145_write_register(ViPipe, 0x6f, 0x18); + gc2145_write_register(ViPipe, 0x73, 0xf0); + gc2145_write_register(ViPipe, 0x70, 0x0d); + gc2145_write_register(ViPipe, 0x71, 0x60); + gc2145_write_register(ViPipe, 0x72, 0x80); + gc2145_write_register(ViPipe, 0x74, 0x01); + gc2145_write_register(ViPipe, 0x75, 0x01); + gc2145_write_register(ViPipe, 0x7f, 0x0c); + gc2145_write_register(ViPipe, 0x76, 0x70); + gc2145_write_register(ViPipe, 0x77, 0x58); + gc2145_write_register(ViPipe, 0x78, 0xa0); + gc2145_write_register(ViPipe, 0x79, 0x5e); + gc2145_write_register(ViPipe, 0x7a, 0x54); + gc2145_write_register(ViPipe, 0x7b, 0x58); + gc2145_write_register(ViPipe, 0xfe, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0xc0, 0x01); + gc2145_write_register(ViPipe, 0xc1, 0x44); + gc2145_write_register(ViPipe, 0xc2, 0xfd); + gc2145_write_register(ViPipe, 0xc3, 0x04); + gc2145_write_register(ViPipe, 0xc4, 0xF0); + gc2145_write_register(ViPipe, 0xc5, 0x48); + gc2145_write_register(ViPipe, 0xc6, 0xfd); + gc2145_write_register(ViPipe, 0xc7, 0x46); + gc2145_write_register(ViPipe, 0xc8, 0xfd); + gc2145_write_register(ViPipe, 0xc9, 0x02); + gc2145_write_register(ViPipe, 0xca, 0xe0); + gc2145_write_register(ViPipe, 0xcb, 0x45); + gc2145_write_register(ViPipe, 0xcc, 0xec); + gc2145_write_register(ViPipe, 0xcd, 0x48); + gc2145_write_register(ViPipe, 0xce, 0xf0); + gc2145_write_register(ViPipe, 0xcf, 0xf0); + gc2145_write_register(ViPipe, 0xe3, 0x0c); + gc2145_write_register(ViPipe, 0xe4, 0x4b); + gc2145_write_register(ViPipe, 0xe5, 0xe0); + + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x9f, 0x40); + gc2145_write_register(ViPipe, 0xfe, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0xf2, 0x0f); + + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0x40, 0xbf); + gc2145_write_register(ViPipe, 0x46, 0xcf); + gc2145_write_register(ViPipe, 0xfe, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0x05, 0x01); + gc2145_write_register(ViPipe, 0x06, 0x56); + gc2145_write_register(ViPipe, 0x07, 0x00); + gc2145_write_register(ViPipe, 0x08, 0x32); + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x25, 0x00); + gc2145_write_register(ViPipe, 0x26, 0xfa); + gc2145_write_register(ViPipe, 0x27, 0x04); + gc2145_write_register(ViPipe, 0x28, 0xe2); + gc2145_write_register(ViPipe, 0x29, 0x06); + gc2145_write_register(ViPipe, 0x2a, 0xd6); + gc2145_write_register(ViPipe, 0x2b, 0x07); + gc2145_write_register(ViPipe, 0x2c, 0xd0); + gc2145_write_register(ViPipe, 0x2d, 0x0b); + gc2145_write_register(ViPipe, 0x2e, 0xb8); + gc2145_write_register(ViPipe, 0xfe, 0x00); + + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0xfd, 0x00); + gc2145_write_register(ViPipe, 0xf8, 0x82); + gc2145_write_register(ViPipe, 0xfa, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0x90, 0x01); + gc2145_write_register(ViPipe, 0x91, 0x00); + gc2145_write_register(ViPipe, 0x92, 0x00); + gc2145_write_register(ViPipe, 0x93, 0x00); + gc2145_write_register(ViPipe, 0x94, 0x00); + gc2145_write_register(ViPipe, 0x95, 0x04); + gc2145_write_register(ViPipe, 0x96, 0xb0); + gc2145_write_register(ViPipe, 0x97, 0x06); + gc2145_write_register(ViPipe, 0x98, 0x40); + gc2145_write_register(ViPipe, 0x99, 0x11); + gc2145_write_register(ViPipe, 0x9a, 0x06); + gc2145_write_register(ViPipe, 0x9b, 0x00); + gc2145_write_register(ViPipe, 0x9c, 0x00); + gc2145_write_register(ViPipe, 0x9d, 0x00); + gc2145_write_register(ViPipe, 0x9e, 0x00); + gc2145_write_register(ViPipe, 0x9f, 0x00); + gc2145_write_register(ViPipe, 0xa0, 0x00); + gc2145_write_register(ViPipe, 0xa1, 0x00); + gc2145_write_register(ViPipe, 0xa2, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0xec, 0x06); + gc2145_write_register(ViPipe, 0xed, 0x04); + gc2145_write_register(ViPipe, 0xee, 0x60); + gc2145_write_register(ViPipe, 0xef, 0x90); + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x74, 0x01); + + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x01, 0x04); + gc2145_write_register(ViPipe, 0x02, 0xc0); + gc2145_write_register(ViPipe, 0x03, 0x04); + gc2145_write_register(ViPipe, 0x04, 0x90); + gc2145_write_register(ViPipe, 0x05, 0x30); + gc2145_write_register(ViPipe, 0x06, 0x90); + gc2145_write_register(ViPipe, 0x07, 0x30); + gc2145_write_register(ViPipe, 0x08, 0x80); + gc2145_write_register(ViPipe, 0x0a, 0x82); + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x21, 0x15); + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0x20, 0x15); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0x05, 0x01); + gc2145_write_register(ViPipe, 0x06, 0x2f); + gc2145_write_register(ViPipe, 0x07, 0x00); + gc2145_write_register(ViPipe, 0x08, 0x64); + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x25, 0x00); + gc2145_write_register(ViPipe, 0x26, 0xa0); + gc2145_write_register(ViPipe, 0x27, 0x05); + gc2145_write_register(ViPipe, 0x28, 0x00); + gc2145_write_register(ViPipe, 0x29, 0x05); + gc2145_write_register(ViPipe, 0x2a, 0x00); + gc2145_write_register(ViPipe, 0x2b, 0x05); + gc2145_write_register(ViPipe, 0x2c, 0x00); + gc2145_write_register(ViPipe, 0x2d, 0x05); + gc2145_write_register(ViPipe, 0x2e, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + + delay_ms(100); + + printf("ViPipe:%d,===GC2145 1200P 12fps YUV Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc4023/Makefile b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4023/Makefile new file mode 100644 index 000000000..cd2e0182f --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4023/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc4023.a +TARGET_SO = $(MW_LIB)/libsns_gc4023.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc4023/gc4023_cmos.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4023/gc4023_cmos.c new file mode 100644 index 000000000..ad5ce6ff9 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4023/gc4023_cmos.c @@ -0,0 +1,934 @@ +#include +#include +#include +#include +#include +#include +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" +#include "gc4023_cmos_ex.h" +#include "gc4023_cmos_param.h" +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#include "cvi_type.h" +#else +#include +#include +#include +#endif + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define GC4023_ID 4023 +#define GC4023_I2C_ADDR_1 0x21 +#define GC4023_I2C_ADDR_2 0x29 +#define GC4023_I2C_ADDR_IS_VALID(addr) ((addr) == GC4023_I2C_ADDR_1 || (addr) == GC4023_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ***************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc4023[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC4023_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc4023[dev]) +#define GC4023_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc4023[dev] = pstCtx) +#define GC4023_SENSOR_RESET_CTX(dev) (g_pastGc4023[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc4023_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 3}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc4023_MirrorFip[VI_MAX_PIPE_NUM] = {ISP_SNS_NORMAL}; + +CVI_U16 g_au16Gc4023_GainMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ***************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Gc4023 Lines Range*****/ +#define GC4023_FULL_LINES_MAX (0x3fff) + +/*****Gc4023 Register Address*****/ +#define GC4023_EXP_H_ADDR 0x0202 //bit[13:8] +#define GC4023_EXP_L_ADDR 0x0203 + +#define GC4023_AGAIN_H_ADDR 0x0615 //bit[11:8] +#define GC4023_AGAIN_L_ADDR 0x0614 +#define GC4023_COL_AGAIN_H_ADDR 0x00b8 //bit[13:8] +#define GC4023_COL_AGAIN_L_ADDR 0x00b9 + + +#define GC4023_AGAIN_MAG1_ADDR 0x0218 +#define GC4023_AGAIN_MAG2_ADDR 0x1467 +#define GC4023_AGAIN_MAG3_ADDR 0x1468 + + +#define GC4023_VTS_H_ADDR 0x0340 //bit[13:8] +#define GC4023_VTS_L_ADDR 0x0341 + +#define GC4023_MIRROR_FLIP_ADDR 0x022c +#define GC4023_OTP_MIRROR_FLIP_ADDR 0x0a73 + +#define GC4023_RES_IS_1440P(w, h) ((w) <= 2560 && (h) <= 1440) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC4023_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astGc4023_mode[GC4023_MODE_2560X1440P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astGc4023_mode[GC4023_MODE_2560X1440P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 60880; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 1024; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? + g_au32InitExposure[ViPipe] : g_astGc4023_mode[GC4023_MODE_2560X1440P30].stExp[0].u16Def; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstAeSnsDft->u32MinIntTime = g_astGc4023_mode[GC4023_MODE_2560X1440P30].stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astGc4023_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astGc4023_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astGc4023_mode[pstSnsState->u8ImgMode].f32MinFps; + + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + + u32VMAX = (u32VMAX > GC4023_FULL_LINES_MAX) ? GC4023_FULL_LINES_MAX : u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = (u32IntTime[0] >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_U32 regValTable[25][7] = { + /*[reg] 0x0614 0x0615 0x0218 0x1467 0x1468 0x00b8 0x00b9*/ + {0x00, 0x00, 0x00, 0x0D, 0x15, 0x01, 0x00}, + {0x80, 0x02, 0x00, 0x0D, 0x15, 0x01, 0x0B}, + {0x01, 0x00, 0x00, 0x0D, 0x15, 0x01, 0x19}, + {0x81, 0x02, 0x00, 0x0E, 0x16, 0x01, 0x2A}, + {0x02, 0x00, 0x00, 0x0E, 0x16, 0x02, 0x00}, + {0x82, 0x02, 0x00, 0x0F, 0x17, 0x02, 0x17}, + {0x03, 0x00, 0x00, 0x10, 0x18, 0x02, 0x33}, + {0x83, 0x02, 0x00, 0x11, 0x19, 0x03, 0x14}, + {0x04, 0x00, 0x00, 0x12, 0x1a, 0x04, 0x00}, + {0x80, 0x02, 0x20, 0x13, 0x1b, 0x04, 0x2F}, + {0x01, 0x00, 0x20, 0x14, 0x1c, 0x05, 0x26}, + {0x81, 0x02, 0x20, 0x15, 0x1d, 0x06, 0x28}, + {0x02, 0x00, 0x20, 0x16, 0x1e, 0x08, 0x00}, + {0x82, 0x02, 0x20, 0x16, 0x1e, 0x09, 0x1E}, + {0x03, 0x00, 0x20, 0x18, 0x20, 0x0B, 0x0C}, + {0x83, 0x02, 0x20, 0x18, 0x20, 0x0D, 0x11}, + {0x04, 0x00, 0x20, 0x18, 0x20, 0x10, 0x00}, + {0x84, 0x02, 0x20, 0x19, 0x21, 0x12, 0x3D}, + {0x05, 0x00, 0x20, 0x19, 0x21, 0x16, 0x19}, + {0x85, 0x02, 0x20, 0x1A, 0x22, 0x1A, 0x22}, + {0xb5, 0x04, 0x20, 0x1B, 0x23, 0x20, 0x00}, + {0x85, 0x05, 0x20, 0x1B, 0x23, 0x25, 0x3A}, + {0x05, 0x08, 0x20, 0x1C, 0x24, 0x2C, 0x33}, + {0x45, 0x09, 0x20, 0x1D, 0x25, 0x35, 0x05}, + {0x55, 0x0a, 0x20, 0x1F, 0x27, 0x40, 0x00}, +}; + +static CVI_U32 gain_table[25] = { + 16*64, + 16*76, + 16*90, + 16*107, + 16*125, + 16*148, + 16*177, + 16*211, + 16*245, + 16*301, + 16*362, + 16*439, + 16*526, + 16*634, + 16*756, + 16*891, + 16*1026, + 16*1205, + 16*1408, + 16*1655, + 16*1962, + 16*2106, + 16*2733, + 16*3222, + 16*3805, +}; + +int total = sizeof(gain_table) / sizeof(CVI_U32); + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + UNUSED(ViPipe); + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[total - 1]) { + *pu32AgainDb = total - 1; + *pu32AgainLin = gain_table[total - 1]; + return CVI_SUCCESS; + } + + for (i = 0; i < total; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainDb = i - 1; + break; + } + } + *pu32AgainLin = gain_table[i - 1]; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + UNUSED(ViPipe); + + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + /* only surpport linear mode */ + u32Again = pu32Again[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][0]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][1]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG1].u32Data = regValTable[u32Again][2]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG2].u32Data = regValTable[u32Again][3]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG3].u32Data = regValTable[u32Again][4]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][5]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][6]; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + UNUSED(ViPipe); + UNUSED(u16ManRatioEnable); + UNUSED(au32Ratio); + UNUSED(au32IntTimeMax); + UNUSED(au32IntTimeMin); + UNUSED(pu32LFMaxIntTime); + + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode\n"); + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + UNUSED(ViPipe); + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + UNUSED(ViPipe); + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + CMOS_CHECK_POINTER(pstBlc); + UNUSED(ViPipe); + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC4023_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astGc4023_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + UNUSED(ViPipe); + UNUSED(u8Mode); + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunGc4023_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = gc4023_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc4023_addr_byte; + pstI2c_data[i].u32DataByteNum = gc4023_data_byte; + } + + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC4023_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC4023_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC4023_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC4023_AGAIN_L_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG1].u32RegAddr = GC4023_AGAIN_MAG1_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG2].u32RegAddr = GC4023_AGAIN_MAG2_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG3].u32RegAddr = GC4023_AGAIN_MAG3_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC4023_COL_AGAIN_H_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC4023_COL_AGAIN_L_ADDR; + + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC4023_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC4023_VTS_L_ADDR; + pstI2c_data[LINEAR_MIRROR_FLIP].u32RegAddr = GC4023_MIRROR_FLIP_ADDR; + pstI2c_data[LINEAR_OTP_MIRROR_FLIP].u32RegAddr = GC4023_OTP_MIRROR_FLIP_ADDR; + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + + CVI_U32 gainsUpdate = 0, shutterUpdate = 0, vtsUpdate = 0; + + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + + //if ((i >= LINEAR_AGAIN_H) && (i <= LINEAR_DGAIN_L)) + if ((i >= LINEAR_AGAIN_H) && (i <= LINEAR_COL_AGAIN_L)) + gainsUpdate = 1; + + if (i <= LINEAR_EXP_L) + shutterUpdate = 1; + + if ((i >= LINEAR_VTS_H) && (i <= LINEAR_VTS_L)) + vtsUpdate = 1; + + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (gainsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG1].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG2].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG3].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_L].bUpdate = CVI_TRUE; + } + if (shutterUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_L].bUpdate = CVI_TRUE; + } + if (vtsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_VTS_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_VTS_L].bUpdate = CVI_TRUE; + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + pstCfg0->snsCfg.astI2cData[LINEAR_MIRROR_FLIP].bDropFrm = CVI_FALSE; + pstCfg0->snsCfg.astI2cData[LINEAR_OTP_MIRROR_FLIP].bDropFrm = CVI_FALSE; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC4023_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC4023_MODE_2560X1440P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U8 value, otp_value; + + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc4023_MirrorFip[ViPipe] != eSnsMirrorFlip) { + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + value = 0; + otp_value = 0x60; + break; + case ISP_SNS_MIRROR: + value = 0x01; + otp_value = 0x61; + break; + case ISP_SNS_FLIP: + value = 0x02; + otp_value = 0x62; + break; + case ISP_SNS_MIRROR_FLIP: + value = 0x03; + otp_value = 0x63; + break; + default: + return; + } + + pstSnsRegsInfo->astI2cData[LINEAR_MIRROR_FLIP].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_OTP_MIRROR_FLIP].u32Data = otp_value; + pstSnsRegsInfo->astI2cData[LINEAR_MIRROR_FLIP].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_MIRROR_FLIP].u8DropFrmNum = 1; + pstSnsRegsInfo->astI2cData[LINEAR_OTP_MIRROR_FLIP].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_OTP_MIRROR_FLIP].u8DropFrmNum = 1; + g_aeGc4023_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC4023_MODE_2560X1440P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astGc4023_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astGc4023_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astGc4023_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc4023_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astGc4023_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astGc4023_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc4023_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc4023_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc4023_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (GC4023_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc4023_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc4023_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc4023_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC4023_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC4023_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC4023_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC4023_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC4023_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC4023_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC4023_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC4023_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Gc4023_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc4023_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc4023_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc4023_standby, + .pfnRestart = gc4023_restart, + .pfnWriteReg = gc4023_write_register, + .pfnReadReg = gc4023_read_register, + .pfnSetBusInfo = gc4023_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc4023/gc4023_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4023/gc4023_cmos_ex.h new file mode 100644 index 000000000..924944c9c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4023/gc4023_cmos_ex.h @@ -0,0 +1,90 @@ +#ifndef __GC4023_CMOS_EX_H_ +#define __GC4023_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum gc4023_linear_regs_e { + LINEAR_EXP_H, + LINEAR_EXP_L, + LINEAR_AGAIN_L, + LINEAR_AGAIN_H, + LINEAR_AGAIN_MAG1, + LINEAR_AGAIN_MAG2, + LINEAR_AGAIN_MAG3, + LINEAR_COL_AGAIN_H, + LINEAR_COL_AGAIN_L, + LINEAR_VTS_H, + LINEAR_VTS_L, + LINEAR_MIRROR_FLIP, + LINEAR_OTP_MIRROR_FLIP, + LINEAR_REGS_NUM +}; + +typedef enum _GC4023_MODE_E { + GC4023_MODE_2560X1440P30 = 0, + GC4023_MODE_LINEAR_NUM, + GC4023_MODE_NUM +} GC4023_MODE_E; + +typedef struct _GC4023_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC4023_STATE_S; + +typedef struct _GC4023_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} GC4023_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc4023[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc4023_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc4023_MirrorFip[VI_MAX_PIPE_NUM]; +extern CVI_U8 gc4023_i2c_addr; +extern const CVI_U32 gc4023_addr_byte; +extern const CVI_U32 gc4023_data_byte; +extern void gc4023_init(VI_PIPE ViPipe); +extern void gc4023_exit(VI_PIPE ViPipe); +extern void gc4023_standby(VI_PIPE ViPipe); +extern void gc4023_restart(VI_PIPE ViPipe); +extern int gc4023_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc4023_read_register(VI_PIPE ViPipe, int addr); +extern int gc4023_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC4023_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc4023/gc4023_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4023/gc4023_cmos_param.h new file mode 100644 index 000000000..a7de56790 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4023/gc4023_cmos_param.h @@ -0,0 +1,223 @@ +#ifndef __GC4023_CMOS_PARAM_H_ +#define __GC4023_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif + +#include "cvi_sns_ctrl.h" +#include "gc4023_cmos_ex.h" + +static const GC4023_MODE_S g_astGc4023_mode[GC4023_MODE_NUM] = { + [GC4023_MODE_2560X1440P30] = { + .name = "2560X1440P30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 5.49, /* 1500 * 30 / 8191*/ + .u32HtsDef = 2400, + .u32VtsDef = 1500, + .stExp[0] = { + .u16Min = 1, + .u16Max = 0x3fff, + .u16Def = 100, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 16*3805, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 1024, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.04006369039416313171, 5.73531675338745117188}, //B: slope, intercept + {0.03064448758959770203, 8.56994438171386718750}, //Gb: slope, intercept + {0.03068985790014266968, 8.82220363616943359375}, //Gr: slope, intercept + {0.03361049667000770569, 7.20687675476074218750}, //R: slope, intercept + }, + { //iso 200 + {0.05054308474063873291, 7.91628408432006835938}, //B: slope, intercept + {0.03632996603846549988, 13.05291843414306640625}, //Gb: slope, intercept + {0.03697143867611885071, 12.49540805816650390625}, //Gr: slope, intercept + {0.04156460240483283997, 10.44298553466796875000}, //R: slope, intercept + }, + { //iso 400 + {0.06805337965488433838, 11.55693244934082031250}, //B: slope, intercept + {0.04390667378902435303, 18.59673881530761718750}, //Gb: slope, intercept + {0.04630871489644050598, 17.90183258056640625000}, //Gr: slope, intercept + {0.05292420834302902222, 15.17318439483642578125}, //R: slope, intercept + }, + { //iso 800 + {0.08635756373405456543, 17.79124641418457031250}, //B: slope, intercept + {0.05776864662766456604, 26.76541900634765625000}, //Gb: slope, intercept + {0.05839699879288673401, 26.44194030761718750000}, //Gr: slope, intercept + {0.06750740110874176025, 22.42554473876953125000}, //R: slope, intercept + }, + { //iso 1600 + {0.12254384160041809082, 26.20610046386718750000}, //B: slope, intercept + {0.07916855812072753906, 39.39273834228515625000}, //Gb: slope, intercept + {0.07857896387577056885, 39.03499984741210937500}, //Gr: slope, intercept + {0.09273355454206466675, 33.09597778320312500000}, //R: slope, intercept + }, + { //iso 3200 + {0.18002016842365264893, 34.86975860595703125000}, //B: slope, intercept + {0.10951708257198333740, 54.58878326416015625000}, //Gb: slope, intercept + {0.10485322028398513794, 57.16654205322265625000}, //Gr: slope, intercept + {0.13257601857185363770, 46.27093505859375000000}, //R: slope, intercept + }, + { //iso 6400 + {0.24713687598705291748, 48.62341690063476562500}, //B: slope, intercept + {0.14974890649318695068, 77.06428527832031250000}, //Gb: slope, intercept + {0.14544390141963958740, 76.57913970947265625000}, //Gr: slope, intercept + {0.19056233763694763184, 62.13500213623046875000}, //R: slope, intercept + }, + { //iso 12800 + {0.37728109955787658691, 58.15543365478515625000}, //B: slope, intercept + {0.20440576970577239990, 100.45700073242187500000}, //Gb: slope, intercept + {0.20059910416603088379, 102.35488891601562500000}, //Gr: slope, intercept + {0.27388775348663330078, 79.65499877929687500000}, //R: slope, intercept + }, + { //iso 25600 + {0.36612421274185180664, 115.28938293457031250000}, //B: slope, intercept + {0.22633622586727142334, 164.58416748046875000000}, //Gb: slope, intercept + {0.21590474247932434082, 168.92042541503906250000}, //Gr: slope, intercept + {0.33193346858024597168, 127.92090606689453125000}, //R: slope, intercept + }, + { //iso 51200 + {0.48242908716201782227, 147.39015197753906250000}, //B: slope, intercept + {0.28994381427764892578, 223.02711486816406250000}, //Gb: slope, intercept + {0.29200506210327148438, 220.64030456542968750000}, //Gr: slope, intercept + {0.42304891347885131836, 173.74638366699218750000}, //R: slope, intercept + }, + { //iso 102400 + {0.62099909782409667969, 130.97862243652343750000}, //B: slope, intercept + {0.39534106850624084473, 219.74490356445312500000}, //Gb: slope, intercept + {0.39458695054054260254, 213.37374877929687500000}, //Gr: slope, intercept + {0.55690109729766845703, 158.37773132324218750000}, //R: slope, intercept + }, + { //iso 204800 + {0.75350415706634521484, 77.81707000732421875000}, //B: slope, intercept + {0.52716732025146484375, 148.77879333496093750000}, //Gb: slope, intercept + {0.51073729991912841797, 153.86495971679687500000}, //Gr: slope, intercept + {0.68910604715347290039, 102.12422180175781250000}, //R: slope, intercept + }, + { //iso 409600 + {0.90276730060577392578, 43.78258514404296875000}, //B: slope, intercept + {0.62851423025131225586, 119.41429138183593750000}, //Gb: slope, intercept + {0.64918899536132812500, 110.74241638183593750000}, //Gr: slope, intercept + {0.80880594253540039063, 68.89983367919921875000}, //R: slope, intercept + }, + { //iso 819200 + {0.90276730060577392578, 43.78258514404296875000}, //B: slope, intercept + {0.62851423025131225586, 119.41429138183593750000}, //Gb: slope, intercept + {0.64918899536132812500, 110.74241638183593750000}, //Gr: slope, intercept + {0.80880594253540039063, 68.89983367919921875000}, //R: slope, intercept + }, + { //iso 1638400 + {0.90276730060577392578, 43.78258514404296875000}, //B: slope, intercept + {0.62851423025131225586, 119.41429138183593750000}, //Gb: slope, intercept + {0.64918899536132812500, 110.74241638183593750000}, //Gr: slope, intercept + {0.80880594253540039063, 68.89983367919921875000}, //R: slope, intercept + }, + { //iso 3276800 + {0.90276730060577392578, 43.78258514404296875000}, //B: slope, intercept + {0.62851423025131225586, 119.41429138183593750000}, //Gb: slope, intercept + {0.64918899536132812500, 110.74241638183593750000}, //Gr: slope, intercept + {0.80880594253540039063, 68.89983367919921875000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {252, 252, 252, 252, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1091, 1091, 1091, 1091 +#endif + }, + .stAuto = { + {252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 }, + {252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 }, + {252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 }, + {252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, + 1091, 1091}, + {1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, + 1091, 1091}, + {1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, + 1091, 1091}, + {1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, + 1091, 1091}, +#endif + }, + }, +}; + +struct combo_dev_attr_s gc4023_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 1, 3, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC4023_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc4023/gc4023_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4023/gc4023_sensor_ctl.c new file mode 100644 index 000000000..3e1383686 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4023/gc4023_sensor_ctl.c @@ -0,0 +1,397 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc4023_cmos_ex.h" +#define GC4023_CHIP_ID_ADDR_H 0x03f0 +#define GC4023_CHIP_ID_ADDR_L 0x03f1 +#define GC4023_CHIP_ID 0x4023 + +#define GC4023_MIRROR_NORMAL + +#if defined(GC4023_MIRROR_NORMAL) +#define MIRROR 0x00 +#define OTP_MIRROR 0x60 +#elif defined(GC4023_MIRROR_H) +#define MIRROR 0x01 +#define OTP_MIRROR 0x61 +#elif defined(GC4023_MIRROR_V) +#define MIRROR 0x02 +#define OTP_MIRROR 0x62 +#elif defined(GC4023_MIRROR_HV) +#define MIRROR 0x03 +#define OTP_MIRROR 0x63 +#else +#define MIRROR 0x00 +#define OTP_MIRROR 0x60 +#endif + +static void gc4023_linear_1440p30_init(VI_PIPE ViPipe); + +CVI_U8 gc4023_i2c_addr = 0x29; +const CVI_U32 gc4023_addr_byte = 2; +const CVI_U32 gc4023_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc4023_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc4023_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc4023_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc4023_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc4023_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (gc4023_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc4023_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, gc4023_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc4023_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_INFO, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int gc4023_write_register(VI_PIPE ViPipe, int addr, int data) +{ + int idx = 0; + int ret; + char buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc4023_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + if (gc4023_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc4023_addr_byte + gc4023_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + ret = read(g_fd[ViPipe], buf, gc4023_addr_byte + gc4023_data_byte); + syslog(LOG_INFO, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void gc4023_prog(VI_PIPE ViPipe, int *rom) +{ + int i = 0; + + while (1) { + int lookup = rom[i++]; + int addr = (lookup >> 16) & 0xFFFF; + int data = lookup & 0xFFFF; + + if (addr == 0xFFFE) + delay_ms(data); + else if (addr != 0xFFFF) + gc4023_write_register(ViPipe, addr, data); + } +} + +void gc4023_standby(VI_PIPE ViPipe) +{ + gc4023_write_register(ViPipe, 0x0100, 0x00); + gc4023_write_register(ViPipe, 0x0a34, 0x00); + gc4023_write_register(ViPipe, 0x061c, 0x10); + gc4023_write_register(ViPipe, 0x031c, 0x01); + gc4023_write_register(ViPipe, 0x0a38, 0x00); +} + +void gc4023_restart(VI_PIPE ViPipe) +{ + gc4023_write_register(ViPipe, 0x0a38, 0x01); + gc4023_write_register(ViPipe, 0x0a34, 0x40); + gc4023_write_register(ViPipe, 0x061c, 0x50); + gc4023_write_register(ViPipe, 0x031c, 0xce); + gc4023_write_register(ViPipe, 0x0100, 0x09); +} + +void gc4023_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc4023[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc4023_write_register(ViPipe, + g_pastGc4023[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc4023[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} +int gc4023_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc4023_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc4023_read_register(ViPipe, GC4023_CHIP_ID_ADDR_H); + nVal2 = gc4023_read_register(ViPipe, GC4023_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC4023_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc4023_init(VI_PIPE ViPipe) +{ + gc4023_i2c_init(ViPipe); + + gc4023_linear_1440p30_init(ViPipe); + + g_pastGc4023[ViPipe]->bInit = CVI_TRUE; +} + +void gc4023_exit(VI_PIPE ViPipe) +{ + gc4023_i2c_exit(ViPipe); +} + +static void gc4023_linear_1440p30_init(VI_PIPE ViPipe) +{ + usleep(10*1000); + gc4023_write_register(ViPipe, 0x03fe, 0xf0); + gc4023_write_register(ViPipe, 0x03fe, 0x00); + gc4023_write_register(ViPipe, 0x03fe, 0x10); + gc4023_write_register(ViPipe, 0x03fe, 0x00); + gc4023_write_register(ViPipe, 0x0a38, 0x00); + gc4023_write_register(ViPipe, 0x0a38, 0x01); + gc4023_write_register(ViPipe, 0x0a20, 0x07); + gc4023_write_register(ViPipe, 0x061c, 0x50); + gc4023_write_register(ViPipe, 0x061d, 0x22); + gc4023_write_register(ViPipe, 0x061e, 0x78); + gc4023_write_register(ViPipe, 0x061f, 0x06); + gc4023_write_register(ViPipe, 0x0a21, 0x10); + gc4023_write_register(ViPipe, 0x0a34, 0x40); + gc4023_write_register(ViPipe, 0x0a35, 0x01); + gc4023_write_register(ViPipe, 0x0a36, 0x4e); + gc4023_write_register(ViPipe, 0x0a37, 0x06); + gc4023_write_register(ViPipe, 0x0314, 0x50); + gc4023_write_register(ViPipe, 0x0315, 0x00); + gc4023_write_register(ViPipe, 0x031c, 0xce); + gc4023_write_register(ViPipe, 0x0219, 0x47); + gc4023_write_register(ViPipe, 0x0342, 0x04); + gc4023_write_register(ViPipe, 0x0343, 0xb0); + gc4023_write_register(ViPipe, 0x0259, 0x05); + gc4023_write_register(ViPipe, 0x025a, 0xa0); + gc4023_write_register(ViPipe, 0x0340, 0x05); + gc4023_write_register(ViPipe, 0x0341, 0xdc); + gc4023_write_register(ViPipe, 0x0347, 0x02); + gc4023_write_register(ViPipe, 0x0348, 0x0a); + gc4023_write_register(ViPipe, 0x0349, 0x08); + gc4023_write_register(ViPipe, 0x034a, 0x05); + gc4023_write_register(ViPipe, 0x034b, 0xa8); + gc4023_write_register(ViPipe, 0x0094, 0x0a); + gc4023_write_register(ViPipe, 0x0095, 0x00); + gc4023_write_register(ViPipe, 0x0096, 0x05); + gc4023_write_register(ViPipe, 0x0097, 0xa0); + gc4023_write_register(ViPipe, 0x0099, 0x04); + gc4023_write_register(ViPipe, 0x009b, 0x04); + gc4023_write_register(ViPipe, 0x060c, 0x01); + gc4023_write_register(ViPipe, 0x060e, 0x08); + gc4023_write_register(ViPipe, 0x060f, 0x05); + gc4023_write_register(ViPipe, 0x070c, 0x01); + gc4023_write_register(ViPipe, 0x070e, 0x08); + gc4023_write_register(ViPipe, 0x070f, 0x05); + gc4023_write_register(ViPipe, 0x0909, 0x03); + gc4023_write_register(ViPipe, 0x0902, 0x04); + gc4023_write_register(ViPipe, 0x0904, 0x0b); + gc4023_write_register(ViPipe, 0x0907, 0x54); + gc4023_write_register(ViPipe, 0x0908, 0x06); + gc4023_write_register(ViPipe, 0x0903, 0x9d); + gc4023_write_register(ViPipe, 0x072a, 0x18); + gc4023_write_register(ViPipe, 0x0724, 0x0a); + gc4023_write_register(ViPipe, 0x0727, 0x0a); + gc4023_write_register(ViPipe, 0x072a, 0x1c); + gc4023_write_register(ViPipe, 0x072b, 0x0a); + gc4023_write_register(ViPipe, 0x1466, 0x10); + gc4023_write_register(ViPipe, 0x1468, 0x0b); + gc4023_write_register(ViPipe, 0x1467, 0x13); + gc4023_write_register(ViPipe, 0x1469, 0x80); + gc4023_write_register(ViPipe, 0x146a, 0xe8); + gc4023_write_register(ViPipe, 0x0707, 0x07); + gc4023_write_register(ViPipe, 0x0737, 0x0f); + gc4023_write_register(ViPipe, 0x0704, 0x01); + gc4023_write_register(ViPipe, 0x0706, 0x03); + gc4023_write_register(ViPipe, 0x0716, 0x03); + gc4023_write_register(ViPipe, 0x0708, 0xc8); + gc4023_write_register(ViPipe, 0x0718, 0xc8); + gc4023_write_register(ViPipe, 0x061a, 0x00); + gc4023_write_register(ViPipe, 0x1430, 0x80); + gc4023_write_register(ViPipe, 0x1407, 0x10); + gc4023_write_register(ViPipe, 0x1408, 0x16); + gc4023_write_register(ViPipe, 0x1409, 0x03); + gc4023_write_register(ViPipe, 0x146d, 0x0e); + gc4023_write_register(ViPipe, 0x146e, 0x42); + gc4023_write_register(ViPipe, 0x146f, 0x43); + gc4023_write_register(ViPipe, 0x1470, 0x3c); + gc4023_write_register(ViPipe, 0x1471, 0x3d); + gc4023_write_register(ViPipe, 0x1472, 0x3a); + gc4023_write_register(ViPipe, 0x1473, 0x3a); + gc4023_write_register(ViPipe, 0x1474, 0x40); + gc4023_write_register(ViPipe, 0x1475, 0x46); + gc4023_write_register(ViPipe, 0x1420, 0x14); + gc4023_write_register(ViPipe, 0x1464, 0x15); + gc4023_write_register(ViPipe, 0x146c, 0x40); + gc4023_write_register(ViPipe, 0x146d, 0x40); + gc4023_write_register(ViPipe, 0x1423, 0x08); + gc4023_write_register(ViPipe, 0x1428, 0x10); + gc4023_write_register(ViPipe, 0x1462, 0x18); + gc4023_write_register(ViPipe, 0x02ce, 0x04); + gc4023_write_register(ViPipe, 0x143a, 0x0f); + gc4023_write_register(ViPipe, 0x142b, 0x88); + gc4023_write_register(ViPipe, 0x0245, 0xc9); + gc4023_write_register(ViPipe, 0x023a, 0x08); + gc4023_write_register(ViPipe, 0x02cd, 0x99); + gc4023_write_register(ViPipe, 0x0612, 0x02); + gc4023_write_register(ViPipe, 0x0613, 0xc7); + gc4023_write_register(ViPipe, 0x0243, 0x03); + gc4023_write_register(ViPipe, 0x021b, 0x09); + gc4023_write_register(ViPipe, 0x0089, 0x03); + gc4023_write_register(ViPipe, 0x0040, 0xa3); + gc4023_write_register(ViPipe, 0x0075, 0x64); + gc4023_write_register(ViPipe, 0x0004, 0x0f); + gc4023_write_register(ViPipe, 0x0002, 0xab); + gc4023_write_register(ViPipe, 0x0053, 0x0a); + gc4023_write_register(ViPipe, 0x0205, 0x0c); + gc4023_write_register(ViPipe, 0x0202, 0x06); + gc4023_write_register(ViPipe, 0x0203, 0x27); + gc4023_write_register(ViPipe, 0x0614, 0x00); + gc4023_write_register(ViPipe, 0x0615, 0x00); + gc4023_write_register(ViPipe, 0x0181, 0x0c); + gc4023_write_register(ViPipe, 0x0182, 0x05); + gc4023_write_register(ViPipe, 0x0185, 0x01); + gc4023_write_register(ViPipe, 0x0180, 0x46); + gc4023_write_register(ViPipe, 0x0100, 0x08); + gc4023_write_register(ViPipe, 0x0106, 0x38); + gc4023_write_register(ViPipe, 0x010d, 0x80); + gc4023_write_register(ViPipe, 0x010e, 0x0c); + gc4023_write_register(ViPipe, 0x0113, 0x02); + gc4023_write_register(ViPipe, 0x0114, 0x01); + gc4023_write_register(ViPipe, 0x0115, 0x10); + gc4023_write_register(ViPipe, 0x022c, MIRROR); + gc4023_write_register(ViPipe, 0x0100, 0x09); + + gc4023_write_register(ViPipe, 0x0a67, 0x80); + gc4023_write_register(ViPipe, 0x0a54, 0x0e); + gc4023_write_register(ViPipe, 0x0a65, 0x10); + gc4023_write_register(ViPipe, 0x0a98, 0x10); + gc4023_write_register(ViPipe, 0x05be, 0x00); + gc4023_write_register(ViPipe, 0x05a9, 0x01); + gc4023_write_register(ViPipe, 0x0029, 0x08); + gc4023_write_register(ViPipe, 0x002b, 0xa8); + gc4023_write_register(ViPipe, 0x0a83, 0xe0); + gc4023_write_register(ViPipe, 0x0a72, 0x02); + gc4023_write_register(ViPipe, 0x0a73, OTP_MIRROR); + gc4023_write_register(ViPipe, 0x0a75, 0x41); + gc4023_write_register(ViPipe, 0x0a70, 0x03); + gc4023_write_register(ViPipe, 0x0a5a, 0x80); + usleep(20*1000); + gc4023_write_register(ViPipe, 0x05be, 0x01); + gc4023_write_register(ViPipe, 0x0a70, 0x00); + gc4023_write_register(ViPipe, 0x0080, 0x02); + gc4023_write_register(ViPipe, 0x0a67, 0x00); + + gc4023_default_reg_init(ViPipe); + usleep(10*1000); + + printf("ViPipe:%d,===GC4023 1440P 30fps 10bit LINEAR Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc4653/Makefile b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4653/Makefile new file mode 100644 index 000000000..553faf605 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4653/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc4653.a +TARGET_SO = $(MW_LIB)/libsns_gc4653.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc4653/gc4653_cmos.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4653/gc4653_cmos.c new file mode 100644 index 000000000..d09bdc86e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4653/gc4653_cmos.c @@ -0,0 +1,960 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "gc4653_cmos_ex.h" +#include "gc4653_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define GC4653_ID 4653 +#define GC4653_I2C_ADDR_1 0x10 +#define GC4653_I2C_ADDR_2 0x29 +#define GC4653_I2C_ADDR_IS_VALID(addr) ((addr) == GC4653_I2C_ADDR_1 || (addr) == GC4653_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ***************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc4653[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC4653_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc4653[dev]) +#define GC4653_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc4653[dev] = pstCtx) +#define GC4653_SENSOR_RESET_CTX(dev) (g_pastGc4653[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc4653_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 3}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc4653_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16Gc4653_GainMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ***************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Gc4653 Lines Range*****/ +#define GC4653_FULL_LINES_MAX (0x3fff) + +/*****Gc4653 Register Address*****/ +#define GC4653_EXP_H_ADDR 0x0202 //bit[13:8] +#define GC4653_EXP_L_ADDR 0x0203 + +#define GC4653_AGAIN_H_ADDR 0x02b4 //bit[10:8] +#define GC4653_AGAIN_L_ADDR 0x02b3 +#define GC4653_COL_AGAIN_H_ADDR 0x02b8 //bit[13:8] +#define GC4653_COL_AGAIN_L_ADDR 0x02b9 +#define GC4653_DGAIN_H_ADDR 0x020e //bit[9:6] +#define GC4653_DGAIN_L_ADDR 0x020f //bit[5:0] +#define GC4653_AGAIN_MAG1_ADDR 0x0515 +#define GC4653_AGAIN_MAG2_ADDR 0x0519 +#define GC4653_AGAIN_MAG3_ADDR 0x02d9 + +#define GC4653_VTS_H_ADDR 0x0340 //bit[13:8] +#define GC4653_VTS_L_ADDR 0x0341 + +#define GC4653_FLIP_MIRROR_ADDR 0x0101 +#define GC4653_FRAME_BUF_ADDR 0x031D + +#define GC4653_RES_IS_1440P(w, h) ((w) <= 2560 && (h) <= 1440) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC4653_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astGc4653_mode[GC4653_MODE_2560X1440P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astGc4653_mode[GC4653_MODE_2560X1440P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 77648; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 10240; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 2; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? + g_au32InitExposure[ViPipe] : g_astGc4653_mode[GC4653_MODE_2560X1440P30].stExp[0].u16Def; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstAeSnsDft->u32MinIntTime = g_astGc4653_mode[GC4653_MODE_2560X1440P30].stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astGc4653_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astGc4653_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astGc4653_mode[pstSnsState->u8ImgMode].f32MinFps; + + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + + u32VMAX = (u32VMAX > GC4653_FULL_LINES_MAX) ? GC4653_FULL_LINES_MAX : u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = ((u32IntTime[0] >> 8) & 0x3F); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_U32 regValTable[26][7] = { + /* [reg] 0x2b3, 0x2b4, 0x2b8, 0x2b9, 0x515, 0x519, 0x2d9 + * [name] AGAIN_L AGAIN_H COLGA_H COLGA_L MAG1 MAG2 MAG3 + */ + {0x00, 0x00, 0x01, 0x00, 0x30, 0x1e, 0x5C}, + {0x20, 0x00, 0x01, 0x0B, 0x30, 0x1e, 0x5C}, + {0x01, 0x00, 0x01, 0x19, 0x30, 0x1d, 0x5B}, + {0x21, 0x00, 0x01, 0x2A, 0x30, 0x1e, 0x5C}, + {0x02, 0x00, 0x02, 0x00, 0x30, 0x1e, 0x5C}, + {0x22, 0x00, 0x02, 0x17, 0x30, 0x1d, 0x5B}, + {0x03, 0x00, 0x02, 0x33, 0x20, 0x16, 0x54}, + {0x23, 0x00, 0x03, 0x14, 0x20, 0x17, 0x55}, + {0x04, 0x00, 0x04, 0x00, 0x20, 0x17, 0x55}, + {0x24, 0x00, 0x04, 0x2F, 0x20, 0x19, 0x57}, + {0x05, 0x00, 0x05, 0x26, 0x20, 0x19, 0x57}, + {0x25, 0x00, 0x06, 0x28, 0x20, 0x1b, 0x59}, + {0x0c, 0x00, 0x08, 0x00, 0x20, 0x1d, 0x5B}, + {0x2C, 0x00, 0x09, 0x1E, 0x20, 0x1f, 0x5D}, + {0x0D, 0x00, 0x0B, 0x0C, 0x20, 0x21, 0x5F}, + {0x2D, 0x00, 0x0D, 0x11, 0x20, 0x24, 0x62}, + {0x1C, 0x00, 0x10, 0x00, 0x20, 0x26, 0x64}, + {0x3C, 0x00, 0x12, 0x3D, 0x18, 0x2a, 0x68}, + {0x5C, 0x00, 0x16, 0x19, 0x18, 0x2c, 0x6A}, + {0x7C, 0x00, 0x1A, 0x22, 0x18, 0x2e, 0x6C}, + {0x9C, 0x00, 0x20, 0x00, 0x18, 0x32, 0x70}, + {0xBC, 0x00, 0x25, 0x3A, 0x18, 0x35, 0x73}, + {0xDC, 0x00, 0x2C, 0x33, 0x10, 0x36, 0x74}, + {0xFC, 0x00, 0x35, 0x05, 0x10, 0x38, 0x76}, + {0x1C, 0x01, 0x40, 0x00, 0x10, 0x3c, 0x7A}, + {0x3C, 0x01, 0x4B, 0x35, 0x10, 0x42, 0x80}, +}; + +static CVI_U32 gain_table[26] = { + 1024, 1200, 1424, 1696, 2048, 2416, 2864, 3392, 4096, 4848, 5728, + 6784, 8192, 9696, 11456, 13584, 16384, 19408, 22928, 27168, 32768, + 38816, 45872, 54352, 65536, 77648 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i, total; + CVI_U32 pregain; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + UNUSED(ViPipe); + total = sizeof(gain_table) / sizeof(CVI_U32); + + if (*pu32AgainLin >= gain_table[total - 1]) { + *pu32AgainLin = *pu32AgainDb = gain_table[total - 1]; + return CVI_SUCCESS; + } + + for (i = 1; i < total; i++) { + if (*pu32AgainLin < gain_table[i]) + break; + } + i--; + // find the pregain + pregain = *pu32AgainLin * 64 / gain_table[i]; + // set the Db as the AE algo gain, we need this to do gain update + *pu32AgainDb = *pu32AgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32AgainLin = pregain * gain_table[i] / 64; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 pregain; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + UNUSED(ViPipe); + // find the pregain + pregain = *pu32DgainLin * 64 / 1024; + // set the Db as the AE algo gain, we need this to do gain update + *pu32DgainDb = *pu32DgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32DgainLin = pregain * 16; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + int i, total; + + total = sizeof(gain_table) / sizeof(CVI_U32); + + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* only surpport linear mode */ + u32Again = pu32Again[0]; + /* To kepp the linearity. we assume AE algo adjusts the dgain only when the again reachs the maximum value */ + if (u32Again < (77648)) { + for (i = 1; i < total; i++) { + if (*pu32Again < gain_table[i]) + break; + } + i--; + // find the pregain + u32Dgain = u32Again * 64 / gain_table[i]; + u32Again = i; + } else { + u32Again = total - 1; + // find the pregain + u32Dgain = pu32Dgain[0] * 64 / 1024; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][0]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][1]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][2]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][3]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG1].u32Data = regValTable[u32Again][4]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG2].u32Data = regValTable[u32Again][5]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG3].u32Data = regValTable[u32Again][6]; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 6); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + UNUSED(ViPipe); + UNUSED(u16ManRatioEnable); + UNUSED(au32Ratio); + UNUSED(au32IntTimeMax); + UNUSED(au32IntTimeMin); + UNUSED(pu32LFMaxIntTime); + + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode\n"); + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + UNUSED(ViPipe); + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + UNUSED(ViPipe); + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + CMOS_CHECK_POINTER(pstBlc); + UNUSED(ViPipe); + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC4653_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astGc4653_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + UNUSED(ViPipe); + UNUSED(u8Mode); + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunGc4653_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = gc4653_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc4653_addr_byte; + pstI2c_data[i].u32DataByteNum = gc4653_data_byte; + } + + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC4653_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC4653_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC4653_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC4653_AGAIN_L_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC4653_COL_AGAIN_H_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC4653_COL_AGAIN_L_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG1].u32RegAddr = GC4653_AGAIN_MAG1_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG2].u32RegAddr = GC4653_AGAIN_MAG2_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG3].u32RegAddr = GC4653_AGAIN_MAG3_ADDR; + pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC4653_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC4653_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC4653_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC4653_VTS_L_ADDR; + pstI2c_data[LINEAR_FLIP_MIRROR].u32RegAddr = GC4653_FLIP_MIRROR_ADDR; + pstI2c_data[LINEAR_FRAME_BUF_ON].u32RegAddr = GC4653_FRAME_BUF_ADDR; + pstI2c_data[LINEAR_FRAME_BUF_ON].u32Data = 0x2D; + pstI2c_data[LINEAR_FRAME_BUF_OFF].u32RegAddr = GC4653_FRAME_BUF_ADDR; + pstI2c_data[LINEAR_FRAME_BUF_OFF].u32Data = 0x28; + + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + + CVI_U32 gainsUpdate = 0, shutterUpdate = 0, vtsUpdate = 0; + + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + + if ((i >= LINEAR_AGAIN_H) && (i <= LINEAR_DGAIN_L)) + gainsUpdate = 1; + + if (i <= LINEAR_EXP_L) + shutterUpdate = 1; + + if ((i >= LINEAR_VTS_H) && (i <= LINEAR_VTS_L)) + vtsUpdate = 1; + + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (gainsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG1].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG2].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG3].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L].bUpdate = CVI_TRUE; + } + if (shutterUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_L].bUpdate = CVI_TRUE; + } + if (vtsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_VTS_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_VTS_L].bUpdate = CVI_TRUE; + } + if (pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR].bUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_FRAME_BUF_ON].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_FRAME_BUF_OFF].bUpdate = CVI_TRUE; + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = CVI_FALSE; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC4653_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC4653_MODE_2560X1440P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U8 value; + + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc4653_MirrorFip[ViPipe] != eSnsMirrorFlip) { + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + value = 0; + break; + case ISP_SNS_MIRROR: + value = 1; + break; + case ISP_SNS_FLIP: + value = 2; + break; + case ISP_SNS_MIRROR_FLIP: + value = 3; + break; + default: + return; + } + + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u8DropFrmNum = 2; + g_aeGc4653_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC4653_MODE_2560X1440P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astGc4653_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astGc4653_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astGc4653_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc4653_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astGc4653_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astGc4653_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc4653_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc4653_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc4653_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (GC4653_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc4653_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc4653_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc4653_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC4653_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC4653_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC4653_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC4653_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC4653_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC4653_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC4653_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC4653_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Gc4653_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc4653_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc4653_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc4653_standby, + .pfnRestart = gc4653_restart, + .pfnWriteReg = gc4653_write_register, + .pfnReadReg = gc4653_read_register, + .pfnSetBusInfo = gc4653_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc4653/gc4653_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4653/gc4653_cmos_ex.h new file mode 100644 index 000000000..eb04a9fb5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4653/gc4653_cmos_ex.h @@ -0,0 +1,93 @@ +#ifndef __GC4653_CMOS_EX_H_ +#define __GC4653_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum gc4653_linear_regs_e { + LINEAR_EXP_H, //0x0202 bit[13:8] + LINEAR_EXP_L, //0x0203 + LINEAR_AGAIN_L, //0x02b3 + LINEAR_AGAIN_H, //0x02b4 bit[10:8] + LINEAR_COL_AGAIN_H, //0x02b8 bit[13:8] + LINEAR_COL_AGAIN_L, //0x02b9 + LINEAR_AGAIN_MAG1, //0x0515 + LINEAR_AGAIN_MAG2, //0x0519 + LINEAR_AGAIN_MAG3, //0x02d9 + LINEAR_DGAIN_H, //0x020e bit[9:6] + LINEAR_DGAIN_L, //0x020f bit[5:0] + LINEAR_VTS_H, //0x0341 bit[13:8] + LINEAR_VTS_L, //0x0342 + LINEAR_FRAME_BUF_ON,//0x031D + LINEAR_FLIP_MIRROR, + LINEAR_FRAME_BUF_OFF,//0x031D + LINEAR_REGS_NUM +}; + +typedef enum _GC4653_MODE_E { + GC4653_MODE_2560X1440P30 = 0, + GC4653_MODE_LINEAR_NUM, + GC4653_MODE_NUM +} GC4653_MODE_E; + +typedef struct _GC4653_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC4653_STATE_S; + +typedef struct _GC4653_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} GC4653_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc4653[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc4653_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc4653_MirrorFip[VI_MAX_PIPE_NUM]; +extern CVI_U8 gc4653_i2c_addr; +extern const CVI_U32 gc4653_addr_byte; +extern const CVI_U32 gc4653_data_byte; +extern void gc4653_init(VI_PIPE ViPipe); +extern void gc4653_exit(VI_PIPE ViPipe); +extern void gc4653_standby(VI_PIPE ViPipe); +extern void gc4653_restart(VI_PIPE ViPipe); +extern int gc4653_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc4653_read_register(VI_PIPE ViPipe, int addr); +extern int gc4653_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC4653_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc4653/gc4653_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4653/gc4653_cmos_param.h new file mode 100644 index 000000000..72cab59d5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4653/gc4653_cmos_param.h @@ -0,0 +1,222 @@ +#ifndef __GC4653_CMOS_PARAM_H_ +#define __GC4653_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc4653_cmos_ex.h" + +static const GC4653_MODE_S g_astGc4653_mode[GC4653_MODE_NUM] = { + [GC4653_MODE_2560X1440P30] = { + .name = "2560X1440P30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.75, /* 1500 * 30 / 16383 */ + .u32HtsDef = 2200, + .u32VtsDef = 1500, + .stExp[0] = { + .u16Min = 1, + .u16Max = 0x3fff, + .u16Def = 0x2000, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 77648, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16368, + .u32Def = 1024, + .u32Step = 64, + }, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.04006369039416313171, 5.73531675338745117188}, //B: slope, intercept + {0.03064448758959770203, 8.56994438171386718750}, //Gb: slope, intercept + {0.03068985790014266968, 8.82220363616943359375}, //Gr: slope, intercept + {0.03361049667000770569, 7.20687675476074218750}, //R: slope, intercept + }, + { //iso 200 + {0.05054308474063873291, 7.91628408432006835938}, //B: slope, intercept + {0.03632996603846549988, 13.05291843414306640625}, //Gb: slope, intercept + {0.03697143867611885071, 12.49540805816650390625}, //Gr: slope, intercept + {0.04156460240483283997, 10.44298553466796875000}, //R: slope, intercept + }, + { //iso 400 + {0.06805337965488433838, 11.55693244934082031250}, //B: slope, intercept + {0.04390667378902435303, 18.59673881530761718750}, //Gb: slope, intercept + {0.04630871489644050598, 17.90183258056640625000}, //Gr: slope, intercept + {0.05292420834302902222, 15.17318439483642578125}, //R: slope, intercept + }, + { //iso 800 + {0.08635756373405456543, 17.79124641418457031250}, //B: slope, intercept + {0.05776864662766456604, 26.76541900634765625000}, //Gb: slope, intercept + {0.05839699879288673401, 26.44194030761718750000}, //Gr: slope, intercept + {0.06750740110874176025, 22.42554473876953125000}, //R: slope, intercept + }, + { //iso 1600 + {0.12254384160041809082, 26.20610046386718750000}, //B: slope, intercept + {0.07916855812072753906, 39.39273834228515625000}, //Gb: slope, intercept + {0.07857896387577056885, 39.03499984741210937500}, //Gr: slope, intercept + {0.09273355454206466675, 33.09597778320312500000}, //R: slope, intercept + }, + { //iso 3200 + {0.18002016842365264893, 34.86975860595703125000}, //B: slope, intercept + {0.10951708257198333740, 54.58878326416015625000}, //Gb: slope, intercept + {0.10485322028398513794, 57.16654205322265625000}, //Gr: slope, intercept + {0.13257601857185363770, 46.27093505859375000000}, //R: slope, intercept + }, + { //iso 6400 + {0.24713687598705291748, 48.62341690063476562500}, //B: slope, intercept + {0.14974890649318695068, 77.06428527832031250000}, //Gb: slope, intercept + {0.14544390141963958740, 76.57913970947265625000}, //Gr: slope, intercept + {0.19056233763694763184, 62.13500213623046875000}, //R: slope, intercept + }, + { //iso 12800 + {0.37728109955787658691, 58.15543365478515625000}, //B: slope, intercept + {0.20440576970577239990, 100.45700073242187500000}, //Gb: slope, intercept + {0.20059910416603088379, 102.35488891601562500000}, //Gr: slope, intercept + {0.27388775348663330078, 79.65499877929687500000}, //R: slope, intercept + }, + { //iso 25600 + {0.36612421274185180664, 115.28938293457031250000}, //B: slope, intercept + {0.22633622586727142334, 164.58416748046875000000}, //Gb: slope, intercept + {0.21590474247932434082, 168.92042541503906250000}, //Gr: slope, intercept + {0.33193346858024597168, 127.92090606689453125000}, //R: slope, intercept + }, + { //iso 51200 + {0.48242908716201782227, 147.39015197753906250000}, //B: slope, intercept + {0.28994381427764892578, 223.02711486816406250000}, //Gb: slope, intercept + {0.29200506210327148438, 220.64030456542968750000}, //Gr: slope, intercept + {0.42304891347885131836, 173.74638366699218750000}, //R: slope, intercept + }, + { //iso 102400 + {0.62099909782409667969, 130.97862243652343750000}, //B: slope, intercept + {0.39534106850624084473, 219.74490356445312500000}, //Gb: slope, intercept + {0.39458695054054260254, 213.37374877929687500000}, //Gr: slope, intercept + {0.55690109729766845703, 158.37773132324218750000}, //R: slope, intercept + }, + { //iso 204800 + {0.75350415706634521484, 77.81707000732421875000}, //B: slope, intercept + {0.52716732025146484375, 148.77879333496093750000}, //Gb: slope, intercept + {0.51073729991912841797, 153.86495971679687500000}, //Gr: slope, intercept + {0.68910604715347290039, 102.12422180175781250000}, //R: slope, intercept + }, + { //iso 409600 + {0.90276730060577392578, 43.78258514404296875000}, //B: slope, intercept + {0.62851423025131225586, 119.41429138183593750000}, //Gb: slope, intercept + {0.64918899536132812500, 110.74241638183593750000}, //Gr: slope, intercept + {0.80880594253540039063, 68.89983367919921875000}, //R: slope, intercept + }, + { //iso 819200 + {0.90276730060577392578, 43.78258514404296875000}, //B: slope, intercept + {0.62851423025131225586, 119.41429138183593750000}, //Gb: slope, intercept + {0.64918899536132812500, 110.74241638183593750000}, //Gr: slope, intercept + {0.80880594253540039063, 68.89983367919921875000}, //R: slope, intercept + }, + { //iso 1638400 + {0.90276730060577392578, 43.78258514404296875000}, //B: slope, intercept + {0.62851423025131225586, 119.41429138183593750000}, //Gb: slope, intercept + {0.64918899536132812500, 110.74241638183593750000}, //Gr: slope, intercept + {0.80880594253540039063, 68.89983367919921875000}, //R: slope, intercept + }, + { //iso 3276800 + {0.90276730060577392578, 43.78258514404296875000}, //B: slope, intercept + {0.62851423025131225586, 119.41429138183593750000}, //Gb: slope, intercept + {0.64918899536132812500, 110.74241638183593750000}, //Gr: slope, intercept + {0.80880594253540039063, 68.89983367919921875000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {255, 256, 256, 257, 260, 264, 272, 289, 324, 400, 468, 474, 475, 476, 466, 496 }, + {255, 256, 256, 257, 260, 264, 272, 289, 325, 404, 469, 476, 477, 477, 467, 493 }, + {255, 256, 256, 257, 260, 264, 272, 289, 325, 401, 468, 477, 476, 477, 467, 495 }, + {255, 256, 256, 257, 260, 264, 272, 290, 325, 404, 471, 477, 478, 478, 468, 493 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1092, 1092, 1093, 1093, 1095, 1097, 1102, 1112, 1135, 1156, 1158, 1158, 1159, + 1155, 1165}, + {1092, 1092, 1092, 1093, 1093, 1095, 1097, 1102, 1112, 1136, 1156, 1159, 1159, 1159, + 1156, 1164}, + {1092, 1092, 1092, 1093, 1093, 1095, 1097, 1102, 1112, 1135, 1156, 1159, 1159, 1159, + 1156, 1165}, + {1092, 1092, 1092, 1093, 1093, 1095, 1097, 1102, 1112, 1136, 1157, 1159, 1159, 1159, + 1156, 1164}, +#endif + }, + }, +}; + +struct combo_dev_attr_s gc4653_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 1, 3, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC4653_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv180x/gcore_gc4653/gc4653_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4653/gc4653_sensor_ctl.c new file mode 100644 index 000000000..99ab959d6 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/gcore_gc4653/gc4653_sensor_ctl.c @@ -0,0 +1,388 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc4653_cmos_ex.h" + +#define GC4653_CHIP_ID_ADDR_H 0x03f0 +#define GC4653_CHIP_ID_ADDR_L 0x03f1 +#define GC4653_CHIP_ID 0x4653 + +static void gc4653_linear_1440p30_init(VI_PIPE ViPipe); + +CVI_U8 gc4653_i2c_addr = 0x10; +const CVI_U32 gc4653_addr_byte = 2; +const CVI_U32 gc4653_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc4653_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc4653_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc4653_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc4653_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc4653_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (gc4653_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc4653_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, gc4653_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc4653_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int gc4653_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc4653_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + if (gc4653_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc4653_addr_byte + gc4653_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + ret = read(g_fd[ViPipe], buf, gc4653_addr_byte + gc4653_data_byte); + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void gc4653_standby(VI_PIPE ViPipe) +{ + gc4653_write_register(ViPipe, 0x0100, 0x00); + gc4653_write_register(ViPipe, 0x031c, 0xc7); + gc4653_write_register(ViPipe, 0x0317, 0x01); + + printf("gc4653_standby\n"); +} + +void gc4653_restart(VI_PIPE ViPipe) +{ + gc4653_write_register(ViPipe, 0x0317, 0x00); + gc4653_write_register(ViPipe, 0x031c, 0xc6); + gc4653_write_register(ViPipe, 0x0100, 0x09); + + printf("gc4653_restart\n"); +} + +void gc4653_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc4653[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc4653_write_register(ViPipe, + g_pastGc4653[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc4653[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +int gc4653_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc4653_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc4653_read_register(ViPipe, GC4653_CHIP_ID_ADDR_H); + nVal2 = gc4653_read_register(ViPipe, GC4653_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC4653_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc4653_init(VI_PIPE ViPipe) +{ + gc4653_i2c_init(ViPipe); + + gc4653_linear_1440p30_init(ViPipe); + + g_pastGc4653[ViPipe]->bInit = CVI_TRUE; +} + +void gc4653_exit(VI_PIPE ViPipe) +{ + gc4653_i2c_exit(ViPipe); +} + +static void gc4653_linear_1440p30_init(VI_PIPE ViPipe) +{ + delay_ms(10); + /****system****/ + gc4653_write_register(ViPipe, 0x03fe, 0xf0); + gc4653_write_register(ViPipe, 0x03fe, 0x00); + gc4653_write_register(ViPipe, 0x0317, 0x00); + gc4653_write_register(ViPipe, 0x0320, 0x77); + gc4653_write_register(ViPipe, 0x0324, 0xc8); + gc4653_write_register(ViPipe, 0x0325, 0x06); + gc4653_write_register(ViPipe, 0x0326, 0x60); + gc4653_write_register(ViPipe, 0x0327, 0x03); + gc4653_write_register(ViPipe, 0x0334, 0x40); + gc4653_write_register(ViPipe, 0x0336, 0x60); + gc4653_write_register(ViPipe, 0x0337, 0x82); + gc4653_write_register(ViPipe, 0x0315, 0x25); + gc4653_write_register(ViPipe, 0x031c, 0xc6); + /****************************************/ + /*frame structure*/ + /****************************************/ + gc4653_write_register(ViPipe, 0x0287, 0x18); + gc4653_write_register(ViPipe, 0x0084, 0x00); + gc4653_write_register(ViPipe, 0x0087, 0x50); + gc4653_write_register(ViPipe, 0x029d, 0x08); + gc4653_write_register(ViPipe, 0x0290, 0x00); + /**********AHD 30 other need change ******************/ + gc4653_write_register(ViPipe, 0x0340, 0x05); + gc4653_write_register(ViPipe, 0x0341, 0xdc); + gc4653_write_register(ViPipe, 0x0345, 0x06); + gc4653_write_register(ViPipe, 0x034b, 0xb0); + gc4653_write_register(ViPipe, 0x0352, 0x08); + gc4653_write_register(ViPipe, 0x0354, 0x08); + /****************************************/ + /*ANALOG CIRCUIT*/ + /****************************************/ + gc4653_write_register(ViPipe, 0x02d1, 0xe0); + gc4653_write_register(ViPipe, 0x0223, 0xf2); + gc4653_write_register(ViPipe, 0x0238, 0xa4); + gc4653_write_register(ViPipe, 0x02ce, 0x7f); + gc4653_write_register(ViPipe, 0x0232, 0xc4); + gc4653_write_register(ViPipe, 0x02d3, 0x05); + gc4653_write_register(ViPipe, 0x0243, 0x06); + gc4653_write_register(ViPipe, 0x02ee, 0x30); + gc4653_write_register(ViPipe, 0x026f, 0x70); + gc4653_write_register(ViPipe, 0x0257, 0x09); + gc4653_write_register(ViPipe, 0x0211, 0x02); + gc4653_write_register(ViPipe, 0x0219, 0x09); + gc4653_write_register(ViPipe, 0x023f, 0x2d); + gc4653_write_register(ViPipe, 0x0518, 0x00); + gc4653_write_register(ViPipe, 0x0519, 0x01); + gc4653_write_register(ViPipe, 0x0515, 0x08); + gc4653_write_register(ViPipe, 0x02d9, 0x3f); + gc4653_write_register(ViPipe, 0x02da, 0x02); + gc4653_write_register(ViPipe, 0x02db, 0xe8); + gc4653_write_register(ViPipe, 0x02e6, 0x20); + gc4653_write_register(ViPipe, 0x021b, 0x10); + gc4653_write_register(ViPipe, 0x0252, 0x22); + gc4653_write_register(ViPipe, 0x024e, 0x22); + gc4653_write_register(ViPipe, 0x02c4, 0x01); + gc4653_write_register(ViPipe, 0x021d, 0x17); + gc4653_write_register(ViPipe, 0x024a, 0x01); + gc4653_write_register(ViPipe, 0x02ca, 0x02); + gc4653_write_register(ViPipe, 0x0262, 0x10); + gc4653_write_register(ViPipe, 0x029a, 0x20); + gc4653_write_register(ViPipe, 0x021c, 0x0e); + gc4653_write_register(ViPipe, 0x0298, 0x03); + gc4653_write_register(ViPipe, 0x029c, 0x00); + gc4653_write_register(ViPipe, 0x027e, 0x14); + gc4653_write_register(ViPipe, 0x02c2, 0x10); + gc4653_write_register(ViPipe, 0x0540, 0x20); + gc4653_write_register(ViPipe, 0x0546, 0x01); + gc4653_write_register(ViPipe, 0x0548, 0x01); + gc4653_write_register(ViPipe, 0x0544, 0x01); + gc4653_write_register(ViPipe, 0x0242, 0x1b); + gc4653_write_register(ViPipe, 0x02c0, 0x1b); + gc4653_write_register(ViPipe, 0x02c3, 0x20); + gc4653_write_register(ViPipe, 0x02e4, 0x10); + gc4653_write_register(ViPipe, 0x022e, 0x00); + gc4653_write_register(ViPipe, 0x027b, 0x3f); + gc4653_write_register(ViPipe, 0x0269, 0x0f); + gc4653_write_register(ViPipe, 0x02d2, 0x40); + gc4653_write_register(ViPipe, 0x027c, 0x08); + gc4653_write_register(ViPipe, 0x023a, 0x2e); + gc4653_write_register(ViPipe, 0x0245, 0xce); + gc4653_write_register(ViPipe, 0x0530, 0x20); + gc4653_write_register(ViPipe, 0x0531, 0x02); + gc4653_write_register(ViPipe, 0x0228, 0x50); + gc4653_write_register(ViPipe, 0x02ab, 0x00); + gc4653_write_register(ViPipe, 0x0250, 0x00); + gc4653_write_register(ViPipe, 0x0221, 0x50); + gc4653_write_register(ViPipe, 0x02ac, 0x00); + gc4653_write_register(ViPipe, 0x02a5, 0x02); + gc4653_write_register(ViPipe, 0x0260, 0x0b); + gc4653_write_register(ViPipe, 0x0216, 0x04); + gc4653_write_register(ViPipe, 0x0299, 0x1C); + gc4653_write_register(ViPipe, 0x02bb, 0x0d); + gc4653_write_register(ViPipe, 0x02a3, 0x02); + gc4653_write_register(ViPipe, 0x02a4, 0x02); + gc4653_write_register(ViPipe, 0x021e, 0x02); + gc4653_write_register(ViPipe, 0x024f, 0x08); + gc4653_write_register(ViPipe, 0x028c, 0x08); + gc4653_write_register(ViPipe, 0x0532, 0x3f); + gc4653_write_register(ViPipe, 0x0533, 0x02); + gc4653_write_register(ViPipe, 0x0277, 0xc0); + gc4653_write_register(ViPipe, 0x0276, 0xc0); + gc4653_write_register(ViPipe, 0x0239, 0xc0); + /*exp*/ + gc4653_write_register(ViPipe, 0x0202, 0x05); + gc4653_write_register(ViPipe, 0x0203, 0x46); + /*gain*/ + gc4653_write_register(ViPipe, 0x0205, 0xc0); + gc4653_write_register(ViPipe, 0x02b0, 0x68); + /*dpc*/ + gc4653_write_register(ViPipe, 0x0002, 0xa9); + gc4653_write_register(ViPipe, 0x0004, 0x01); + /*dark_sun*/ + gc4653_write_register(ViPipe, 0x021a, 0x98); + gc4653_write_register(ViPipe, 0x0266, 0xa0); + gc4653_write_register(ViPipe, 0x0020, 0x01); + gc4653_write_register(ViPipe, 0x0021, 0x03); + gc4653_write_register(ViPipe, 0x0022, 0x00); + gc4653_write_register(ViPipe, 0x0023, 0x04); + /****************************************/ + /*mipi*/ + /****************************************/ + /*********** AHD 30 ******************/ + /*30fps*/ + gc4653_write_register(ViPipe, 0x0342, 0x06); + gc4653_write_register(ViPipe, 0x0343, 0x40); + /*30fps*/ + gc4653_write_register(ViPipe, 0x03fe, 0x10); + gc4653_write_register(ViPipe, 0x03fe, 0x00); + gc4653_write_register(ViPipe, 0x0106, 0x78); + gc4653_write_register(ViPipe, 0x0108, 0x0c); + gc4653_write_register(ViPipe, 0x0114, 0x01); + gc4653_write_register(ViPipe, 0x0115, 0x12); + gc4653_write_register(ViPipe, 0x0180, 0x46); + gc4653_write_register(ViPipe, 0x0181, 0x30); + gc4653_write_register(ViPipe, 0x0182, 0x05); + gc4653_write_register(ViPipe, 0x0185, 0x01); + gc4653_write_register(ViPipe, 0x03fe, 0x10); + gc4653_write_register(ViPipe, 0x03fe, 0x00); + gc4653_write_register(ViPipe, 0x0100, 0x09); + // 0x008e = 0x00, which means disabling bayer transformation when flip/mirroring + //gc4653_write_register(ViPipe, 0x008e, 0x00); + //fix FPN + gc4653_write_register(ViPipe, 0x0277, 0x38); + gc4653_write_register(ViPipe, 0x0276, 0xc0); + gc4653_write_register(ViPipe, 0x000f, 0x10); + gc4653_write_register(ViPipe, 0x0059, 0x00);//close dither + //otp + gc4653_write_register(ViPipe, 0x0080, 0x02); + gc4653_write_register(ViPipe, 0x0097, 0x0a); + gc4653_write_register(ViPipe, 0x0098, 0x10); + gc4653_write_register(ViPipe, 0x0099, 0x05); + gc4653_write_register(ViPipe, 0x009a, 0xb0); + gc4653_write_register(ViPipe, 0x0317, 0x08); + gc4653_write_register(ViPipe, 0x0a67, 0x80); + gc4653_write_register(ViPipe, 0x0a70, 0x03); + gc4653_write_register(ViPipe, 0x0a82, 0x00); + gc4653_write_register(ViPipe, 0x0a83, 0x10); + gc4653_write_register(ViPipe, 0x0a80, 0x2b); + gc4653_write_register(ViPipe, 0x05be, 0x00); + gc4653_write_register(ViPipe, 0x05a9, 0x01); + gc4653_write_register(ViPipe, 0x0313, 0x80); + gc4653_write_register(ViPipe, 0x05be, 0x01); + gc4653_write_register(ViPipe, 0x0317, 0x00); + gc4653_write_register(ViPipe, 0x0a67, 0x00); + + gc4653_default_reg_init(ViPipe); + delay_ms(10); + + printf("ViPipe:%d,===GC4653 1440P 30fps 10bit LINEAR Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/nextchip_n5/Makefile b/middleware/v2/component/isp/sensor/cv180x/nextchip_n5/Makefile new file mode 100644 index 000000000..a9cbf405d --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/nextchip_n5/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_n5.a +TARGET_SO = $(MW_LIB)/libsns_n5.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/nextchip_n5/n5_cmos.c b/middleware/v2/component/isp/sensor/cv180x/nextchip_n5/n5_cmos.c new file mode 100644 index 000000000..10f1f45e0 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/nextchip_n5/n5_cmos.c @@ -0,0 +1,290 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_isp.h" + +#include "n5_cmos_ex.h" +#include "n5_cmos_param.h" + +/**************************************************************************** + * global variables * + ****************************************************************************/ +ISP_SNS_COMMBUS_U g_aunN5_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_STATE_S *g_pastN5[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define N5_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastN5[dev]) +#define N5_SENSOR_SET_CTX(dev, pstCtx) (g_pastN5[dev] = pstCtx) +#define N5_SENSOR_RESET_CTX(dev) (g_pastN5[dev] = CVI_NULL) +#define N5_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) +#define N5_ID 0xE0 + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const N5_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + N5_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astN5_mode[pstSnsState->u8ImgMode]; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + N5_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstCfg0 = &pstSnsState->astSyncInfo[0]; + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + N5_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + + if (pstSensorImageMode->f32Fps <= 30) { + if (N5_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = N5_MODE_1080P_25P; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + N5_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->u8ImgMode = N5_MODE_1080P_25P; + pstSnsState->enWDRMode = WDR_MODE_NONE; +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + N5_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &n5_rx_attr, sizeof(*pstRxAttr)); + CVI_TRACE_SNS(CVI_DBG_ERR, "get n5_rx0_attr\n"); + + pstRxAttr->img_size.width = g_astN5_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astN5_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &n5_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = n5_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = n5_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 n5_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunN5_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + N5_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + N5_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + N5_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + N5_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + (void) pstAeLib; + (void) pstAwbLib; + + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = N5_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + (void) pstAeLib; + (void) pstAwbLib; + + CVI_S32 s32Ret; + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, N5_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsN5_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnMirrorFlip = CVI_NULL, + .pfnStandby = CVI_NULL, + .pfnRestart = CVI_NULL, + .pfnWriteReg = n5_write_register, + .pfnReadReg = n5_read_register, + .pfnSetBusInfo = n5_set_bus_info, + .pfnSetInit = CVI_NULL, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = CVI_NULL, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/nextchip_n5/n5_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/nextchip_n5/n5_cmos_ex.h new file mode 100644 index 000000000..1edfdcaa9 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/nextchip_n5/n5_cmos_ex.h @@ -0,0 +1,89 @@ +#ifndef __N5_CMOS_EX_H_ +#define __N5_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +typedef enum _N5_MODE_E { + N5_MODE_H720_NT = 1, + N5_MODE_H720_PAL, + N5_MODE_720P_30P, + N5_MODE_720P_25P, + N5_MODE_960P_30P, + N5_MODE_960P_25P, + N5_MODE_1080P_30P, + N5_MODE_1080P_25P, + N5_MODE_1080P_60P, + N5_MODE_1080P_50P, + N5_MODE_4M_30P, + N5_MODE_4M_25P, + N5_MODE_8M_15P, + N5_MODE_8M_12_5P, + N5_MODE_NUM +} N5_MODE_E; + +typedef enum _n5_outmode_sel { + N5_OUTMODE_1MUX_SD = 0, + N5_OUTMODE_1MUX_HD, + N5_OUTMODE_1MUX_FHD, + N5_OUTMODE_1MUX_FHD_HALF, + N5_OUTMODE_2MUX_SD, + N5_OUTMODE_2MUX_HD, + N5_OUTMODE_2MUX_FHD, + N5_OUTMODE_1MUX_BT1120S, + N5_OUTMODE_2MUX_BT1120S_720P, + N5_OUTMODE_2MUX_BT1120S_1080P, + N5_OUTMODE_BUTT +} N5_OUTMODE_SEL; + +typedef struct _N5_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + char name[64]; +} N5_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastN5[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunN5_BusInfo[]; +extern const CVI_U8 n5_i2c_addr; +extern const CVI_U32 n5_addr_byte; +extern const CVI_U32 n5_data_byte; +extern void n5_init(VI_PIPE ViPipe); +extern void n5_exit(VI_PIPE ViPipe); +extern void n5_standby(VI_PIPE ViPipe); +extern void n5_restart(VI_PIPE ViPipe); +extern int n5_write_register(VI_PIPE ViPipe, int addr, int data); +extern int n5_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __N5_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/nextchip_n5/n5_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/nextchip_n5/n5_cmos_param.h new file mode 100644 index 000000000..088dfe8c5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/nextchip_n5/n5_cmos_param.h @@ -0,0 +1,100 @@ +#ifndef __N5_CMOS_PARAM_H_ +#define __N5_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "n5_cmos_ex.h" + +static const N5_MODE_S g_astN5_mode[N5_MODE_NUM] = { + [N5_MODE_1080P_25P] = { + .name = "1080p25", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + }, +}; + +struct combo_dev_attr_s n5_rx_attr = { + .input_mode = INPUT_MODE_BT_DEMUX, + .mac_clk = RX_MAC_CLK_400M, + .mclk = { + .cam = 1, + .freq = CAMPLL_FREQ_27M, + }, + .bt_demux_attr = { + .func = { + -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, + -1, -1, -1, -1, + -1, -1, -1, -1 + }, + .v_fp = 0xF, + .h_fp = 0xF, + .v_bp = 0, + .h_bp = 0, + .mode = BT_DEMUX_2, + .sync_code_part_A = {0xFF, 0, 0}, + .sync_code_part_B[0] = { + .sav_vld = 0x80, + .sav_blk = 0xa0, + .eav_vld = 0x90, + .eav_blk = 0xb0, + }, + .sync_code_part_B[1] = { + .sav_vld = 0x81, + .sav_blk = 0xa1, + .eav_vld = 0x91, + .eav_blk = 0xb1, + }, + .sync_code_part_B[2] = { + .sav_vld = 0x82, + .sav_blk = 0xa2, + .eav_vld = 0x92, + .eav_blk = 0xb2, + }, + .sync_code_part_B[3] = { + .sav_vld = 0x83, + .sav_blk = 0xa3, + .eav_vld = 0x93, + .eav_blk = 0xb3, + }, + .yc_exchg = 0xF, + }, + .devno = 0, // btdemux must use mac0 +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __N5_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/nextchip_n5/n5_sensor_ctrl.c b/middleware/v2/component/isp/sensor/cv180x/nextchip_n5/n5_sensor_ctrl.c new file mode 100644 index 000000000..bfa617812 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/nextchip_n5/n5_sensor_ctrl.c @@ -0,0 +1,1218 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "n5_cmos_ex.h" +#include +#include + +const CVI_U8 n5_i2c_addr = 0x32; /* I2C slave address of N5, SA0=0:0x32, SA0=1:0x33*/ +const CVI_U32 n5_addr_byte = 1; +const CVI_U32 n5_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; +static pthread_t g_n5_thid; +unsigned char chn_mode[2] = {0xEE, 0xEE}; + +#define N5_TEST_PATTERN 1 + +int n5_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunN5_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + syslog(LOG_DEBUG, "open %s\n", acDevFile); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, n5_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int n5_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int n5_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return 0; + + if (n5_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, n5_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, n5_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (n5_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int n5_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (n5_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + if (n5_data_byte == 2) + buf[idx++] = (data >> 8) & 0xff; + + // add data byte 0 + buf[idx++] = data & 0xff; + + ret = write(g_fd[ViPipe], buf, n5_addr_byte + n5_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + +#if 0 // read back checing + ret = n5_read_register(ViPipe, addr); + if (ret != data) + syslog(LOG_DEBUG, "i2c readback-check fail, 0x%x != 0x%x\n", ret, data); +#endif + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void n5_common_setting(VI_PIPE ViPipe) +{ + n5_write_register(ViPipe, 0xff, 0x00); + n5_write_register(ViPipe, 0x00, 0x10); + n5_write_register(ViPipe, 0x01, 0x10); + n5_write_register(ViPipe, 0x18, 0x3f); + n5_write_register(ViPipe, 0x19, 0x3f); + n5_write_register(ViPipe, 0x22, 0x0b); + n5_write_register(ViPipe, 0x23, 0x41); + n5_write_register(ViPipe, 0x26, 0x0b); + n5_write_register(ViPipe, 0x27, 0x41); + n5_write_register(ViPipe, 0x54, 0x00); + n5_write_register(ViPipe, 0xa0, 0x05); + n5_write_register(ViPipe, 0xa1, 0x05); + n5_write_register(ViPipe, 0xff, 0x01); + n5_write_register(ViPipe, 0x97, 0x00); + n5_write_register(ViPipe, 0x97, 0x0f); + n5_write_register(ViPipe, 0x7A, 0x0f); + n5_write_register(ViPipe, 0xff, 0x05); + n5_write_register(ViPipe, 0x00, 0xd0); + n5_write_register(ViPipe, 0x01, 0x22); + n5_write_register(ViPipe, 0x05, 0x04); + n5_write_register(ViPipe, 0x08, 0x55); + n5_write_register(ViPipe, 0x1b, 0x08); + n5_write_register(ViPipe, 0x25, 0xdc); + n5_write_register(ViPipe, 0x28, 0x80); + n5_write_register(ViPipe, 0x2f, 0x00); + n5_write_register(ViPipe, 0x30, 0xe0); + n5_write_register(ViPipe, 0x31, 0x43); + n5_write_register(ViPipe, 0x32, 0xa2); + n5_write_register(ViPipe, 0x57, 0x00); + n5_write_register(ViPipe, 0x58, 0x77); + n5_write_register(ViPipe, 0x5b, 0x41); + n5_write_register(ViPipe, 0x5c, 0x7C); + n5_write_register(ViPipe, 0x5f, 0x00); + n5_write_register(ViPipe, 0x7b, 0x11); + n5_write_register(ViPipe, 0x7c, 0x01); + n5_write_register(ViPipe, 0x7d, 0x80); + n5_write_register(ViPipe, 0x80, 0x00); + n5_write_register(ViPipe, 0x90, 0x01); + n5_write_register(ViPipe, 0xa9, 0x00); + n5_write_register(ViPipe, 0xb8, 0x39); + n5_write_register(ViPipe, 0xb9, 0x72); + n5_write_register(ViPipe, 0xd1, 0x00); + n5_write_register(ViPipe, 0xd5, 0x80); + n5_write_register(ViPipe, 0xff, 0x06); + n5_write_register(ViPipe, 0x00, 0xd0); + n5_write_register(ViPipe, 0x01, 0x22); + n5_write_register(ViPipe, 0x05, 0x04); + n5_write_register(ViPipe, 0x08, 0x55); + n5_write_register(ViPipe, 0x1b, 0x08); + n5_write_register(ViPipe, 0x25, 0xdc); + n5_write_register(ViPipe, 0x28, 0x80); + n5_write_register(ViPipe, 0x2f, 0x00); + n5_write_register(ViPipe, 0x30, 0xe0); + n5_write_register(ViPipe, 0x31, 0x43); + n5_write_register(ViPipe, 0x32, 0xa2); + n5_write_register(ViPipe, 0x57, 0x00); + n5_write_register(ViPipe, 0x58, 0x77); + n5_write_register(ViPipe, 0x5b, 0x41); + n5_write_register(ViPipe, 0x5c, 0x7C); + n5_write_register(ViPipe, 0x5f, 0x00); + n5_write_register(ViPipe, 0x7b, 0x11); + n5_write_register(ViPipe, 0x7c, 0x01); + n5_write_register(ViPipe, 0x7d, 0x80); + n5_write_register(ViPipe, 0x80, 0x00); + n5_write_register(ViPipe, 0x90, 0x01); + n5_write_register(ViPipe, 0xa9, 0x00); + n5_write_register(ViPipe, 0xb8, 0x39); + n5_write_register(ViPipe, 0xb9, 0x72); + n5_write_register(ViPipe, 0xd1, 0x00); + n5_write_register(ViPipe, 0xd5, 0x80); + n5_write_register(ViPipe, 0xff, 0x09); + n5_write_register(ViPipe, 0x50, 0x30); + n5_write_register(ViPipe, 0x51, 0x6f); + n5_write_register(ViPipe, 0x52, 0x67); + n5_write_register(ViPipe, 0x53, 0x48); + n5_write_register(ViPipe, 0x54, 0x30); + n5_write_register(ViPipe, 0x55, 0x6f); + n5_write_register(ViPipe, 0x56, 0x67); + n5_write_register(ViPipe, 0x57, 0x48); + n5_write_register(ViPipe, 0x96, 0x00); + n5_write_register(ViPipe, 0x9e, 0x00); + n5_write_register(ViPipe, 0xb6, 0x00); + n5_write_register(ViPipe, 0xbe, 0x00); + n5_write_register(ViPipe, 0xff, 0x0a); + n5_write_register(ViPipe, 0x25, 0x10); + n5_write_register(ViPipe, 0x27, 0x1e); + n5_write_register(ViPipe, 0x30, 0xac); + n5_write_register(ViPipe, 0x31, 0x78); + n5_write_register(ViPipe, 0x32, 0x17); + n5_write_register(ViPipe, 0x33, 0xc1); + n5_write_register(ViPipe, 0x34, 0x40); + n5_write_register(ViPipe, 0x35, 0x00); + n5_write_register(ViPipe, 0x36, 0xc3); + n5_write_register(ViPipe, 0x37, 0x0a); + n5_write_register(ViPipe, 0x38, 0x00); + n5_write_register(ViPipe, 0x39, 0x02); + n5_write_register(ViPipe, 0x3a, 0x00); + n5_write_register(ViPipe, 0x3b, 0xb2); + n5_write_register(ViPipe, 0xa5, 0x10); + n5_write_register(ViPipe, 0xa7, 0x1e); + n5_write_register(ViPipe, 0xb0, 0xac); + n5_write_register(ViPipe, 0xb1, 0x78); + n5_write_register(ViPipe, 0xb2, 0x17); + n5_write_register(ViPipe, 0xb3, 0xc1); + n5_write_register(ViPipe, 0xb4, 0x40); + n5_write_register(ViPipe, 0xb5, 0x00); + n5_write_register(ViPipe, 0xb6, 0xc3); + n5_write_register(ViPipe, 0xb7, 0x0a); + n5_write_register(ViPipe, 0xb8, 0x00); + n5_write_register(ViPipe, 0xb9, 0x02); + n5_write_register(ViPipe, 0xba, 0x00); + n5_write_register(ViPipe, 0xbb, 0xb2); + n5_write_register(ViPipe, 0x77, 0x8F); + n5_write_register(ViPipe, 0xF7, 0x8F); + n5_write_register(ViPipe, 0xff, 0x13); + n5_write_register(ViPipe, 0x07, 0x47); + n5_write_register(ViPipe, 0x12, 0x04); + n5_write_register(ViPipe, 0x1e, 0x1f); + n5_write_register(ViPipe, 0x1f, 0x27); + n5_write_register(ViPipe, 0x2e, 0x10); + n5_write_register(ViPipe, 0x2f, 0xc8); + n5_write_register(ViPipe, 0x30, 0x00); + n5_write_register(ViPipe, 0x31, 0xff); + n5_write_register(ViPipe, 0x32, 0x00); + n5_write_register(ViPipe, 0x33, 0x00); + n5_write_register(ViPipe, 0x3a, 0xff); + n5_write_register(ViPipe, 0x3b, 0xff); + n5_write_register(ViPipe, 0x3c, 0xff); + n5_write_register(ViPipe, 0x3d, 0xff); + n5_write_register(ViPipe, 0x3e, 0xff); + n5_write_register(ViPipe, 0x3f, 0x0f); + n5_write_register(ViPipe, 0x70, 0x00); + n5_write_register(ViPipe, 0x72, 0x05); + n5_write_register(ViPipe, 0x7A, 0xf0); + n5_write_register(ViPipe, 0xff, 0x00); //8x8 color block test pattern + n5_write_register(ViPipe, 0x78, 0xba); + n5_write_register(ViPipe, 0xff, 0x05); + n5_write_register(ViPipe, 0x2c, 0x08); + n5_write_register(ViPipe, 0x6a, 0x80); + n5_write_register(ViPipe, 0xff, 0x06); + n5_write_register(ViPipe, 0x2c, 0x08); + n5_write_register(ViPipe, 0x6a, 0x80); +} + +void n5_set_chn_720h_ntsc(VI_PIPE ViPipe, CVI_U8 chn) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "%s chn=%d\n", __func__, chn); + n5_write_register(ViPipe, 0xff, 0x00); + n5_write_register(ViPipe, 0x08+chn, 0xa0); + n5_write_register(ViPipe, 0x34+chn, 0x00); + n5_write_register(ViPipe, 0x81+chn, 0x60); + n5_write_register(ViPipe, 0x85+chn, 0x00); + n5_write_register(ViPipe, 0x54, n5_read_register(ViPipe, 0x54)|(0x10<1mux(default), 2->2mux +void n5_set_portmode(VI_PIPE ViPipe, CVI_U8 port, CVI_U8 muxmode, CVI_U8 is_bt601) +{ + CVI_U8 val_1xc8, val_1xca, val_0x54; + // add delay for MUX2 + CVI_U8 clk_freq_array[4] = {0x83, 0x03, 0x43, 0x63}; //clk_freq: 0~3:37.125M/74.25M/148.5M/297M + //CVI_U8 clk_freq_array[4] = {0x83, 0x03, 0x4f, 0x63}; //clk_freq: 0~3:37.125M/74.25M/148.5M/297M + + n5_write_register(ViPipe, 0xff, 0x00); + val_0x54 = n5_read_register(ViPipe, 0x54); + + if ((muxmode == N5_OUTMODE_2MUX_SD) || + (muxmode == N5_OUTMODE_2MUX_HD) || + (muxmode == N5_OUTMODE_2MUX_FHD) || + (muxmode == N5_OUTMODE_2MUX_BT1120S_720P) || + (muxmode == N5_OUTMODE_2MUX_BT1120S_1080P)) + val_0x54 |= 0x01; + else + val_0x54 &= 0xFE; + + n5_write_register(ViPipe, 0x54, val_0x54); + n5_write_register(ViPipe, 0xff, 0x01); + val_1xc8 = n5_read_register(ViPipe, 0xc8); + switch (muxmode) { + case N5_OUTMODE_1MUX_SD: + n5_write_register(ViPipe, 0xA0+port, 0x00); + n5_write_register(ViPipe, 0xC0, 0x00); + n5_write_register(ViPipe, 0xC2, 0x11); + val_1xc8 &= (port == 1?0x0F:0xF0); + n5_write_register(ViPipe, 0xC8, val_1xc8); + n5_write_register(ViPipe, 0xCC+port, clk_freq_array[0]); + break; + case N5_OUTMODE_1MUX_HD: + n5_write_register(ViPipe, 0xA0+port, 0x00); + n5_write_register(ViPipe, 0xC0, 0x00); + n5_write_register(ViPipe, 0xC2, 0x11); + val_1xc8 &= (port == 1?0x0F:0xF0); + n5_write_register(ViPipe, 0xC8, val_1xc8); + n5_write_register(ViPipe, 0xCC+port, clk_freq_array[1]); + break; + case N5_OUTMODE_1MUX_FHD: + n5_write_register(ViPipe, 0xA0+port, 0x00); + n5_write_register(ViPipe, 0xC0, 0x00); + n5_write_register(ViPipe, 0xC2, 0x11); + val_1xc8 &= (port == 1?0x0F:0xF0); + n5_write_register(ViPipe, 0xC8, val_1xc8); + n5_write_register(ViPipe, 0xCC+port, clk_freq_array[2]); + break; + case N5_OUTMODE_1MUX_FHD_HALF: + n5_write_register(ViPipe, 0xA0+port, 0x00); + n5_write_register(ViPipe, 0xC0, 0x88); + n5_write_register(ViPipe, 0xC2, 0x99); + val_1xc8 &= (port == 1?0x0F:0xF0); + n5_write_register(ViPipe, 0xC8, val_1xc8); + n5_write_register(ViPipe, 0xCC+port, clk_freq_array[1]); + break; + case N5_OUTMODE_2MUX_SD: + n5_write_register(ViPipe, 0xA0+port, 0x20); + n5_write_register(ViPipe, 0xC0, 0x10); + n5_write_register(ViPipe, 0xC2, 0x10); + val_1xc8 &= (port == 1?0x0F:0xF0); + val_1xc8 |= (port == 1?0x20:0x02); + n5_write_register(ViPipe, 0xC8, val_1xc8); + n5_write_register(ViPipe, 0xCC+port, clk_freq_array[1]); + break; + case N5_OUTMODE_2MUX_HD: + n5_write_register(ViPipe, 0xA0+port, 0x20); + n5_write_register(ViPipe, 0xC0, 0x10); + n5_write_register(ViPipe, 0xC2, 0x10); + val_1xc8 &= (port == 1?0x0F:0xF0); + val_1xc8 |= (port == 1?0x20:0x02); + n5_write_register(ViPipe, 0xC8, val_1xc8); + n5_write_register(ViPipe, 0xCC+port, clk_freq_array[2]); + break; + case N5_OUTMODE_2MUX_FHD: + n5_write_register(ViPipe, 0xA0+port, 0x00); + n5_write_register(ViPipe, 0xC0, 0x10); + n5_write_register(ViPipe, 0xC2, 0x10); + val_1xc8 &= (port == 1?0x0F:0xF0); + val_1xc8 |= (port == 1?0x20:0x02); + n5_write_register(ViPipe, 0xC8, val_1xc8); + n5_write_register(ViPipe, 0xCC+port, clk_freq_array[2]); + break; + case N5_OUTMODE_1MUX_BT1120S: + n5_write_register(ViPipe, 0xA0, 0x00); + n5_write_register(ViPipe, 0xA1, 0x00); + n5_write_register(ViPipe, 0xC0, 0xCC); + n5_write_register(ViPipe, 0xC1, 0xCC); + n5_write_register(ViPipe, 0xC2, 0x44); + n5_write_register(ViPipe, 0xC3, 0x44); + n5_write_register(ViPipe, 0xC8, 0x00); + n5_write_register(ViPipe, 0xCA, 0x33); //two ports are enabled + n5_write_register(ViPipe, 0xCC, clk_freq_array[2]); + break; + case N5_OUTMODE_2MUX_BT1120S_720P: + n5_write_register(ViPipe, 0xA0, 0x00); + n5_write_register(ViPipe, 0xA1, 0x00); + n5_write_register(ViPipe, 0xC0, 0xDC); //C data + n5_write_register(ViPipe, 0xC1, 0xDC); + n5_write_register(ViPipe, 0xC2, 0x54); //Y data + n5_write_register(ViPipe, 0xC3, 0x54); + n5_write_register(ViPipe, 0xC8, 0x22); + n5_write_register(ViPipe, 0xCA, 0x33); //two ports are enabled + n5_write_register(ViPipe, 0xCC, clk_freq_array[1]); + break; + case N5_OUTMODE_2MUX_BT1120S_1080P: + n5_write_register(ViPipe, 0xA0, 0x20); + n5_write_register(ViPipe, 0xA1, 0x20); + n5_write_register(ViPipe, 0xC0, 0xDC); //C data + n5_write_register(ViPipe, 0xC1, 0xDC); + n5_write_register(ViPipe, 0xC2, 0x54); //Y data + n5_write_register(ViPipe, 0xC3, 0x54); + n5_write_register(ViPipe, 0xC8, 0x22); + n5_write_register(ViPipe, 0xCA, 0x33); //two ports are enabled + n5_write_register(ViPipe, 0xCC, clk_freq_array[1]); + break; + } + if (is_bt601 == 1) { + n5_write_register(ViPipe, 0xA8+port, 0x90+(port*0x10)); //h/v0 sync enabled +// n5_write_register(ViPipe, 0xA9, 0xA0); //h/v1 sync enabled +// n5_write_register(ViPipe, 0xBC, 0x10); //h/v0 swap enabled +// n5_write_register(ViPipe, 0xBD, 0x10); +// n5_write_register(ViPipe, 0xBE, 0x10); //h/v1 swap enabled +// n5_write_register(ViPipe, 0xBF, 0x10); + } else { + n5_write_register(ViPipe, 0xA8, 0x00); +// n5_write_register(ViPipe, 0xA9, 0x00); //h/v sync disable. + } + + if (muxmode == N5_OUTMODE_2MUX_BT1120S_720P) { + n5_write_register(ViPipe, 0xE4, 0x11); + n5_write_register(ViPipe, 0xE5, 0x11); + } else { + n5_write_register(ViPipe, 0xE4, 0x00); + n5_write_register(ViPipe, 0xE5, 0x00); + } + + val_1xca = n5_read_register(ViPipe, 0xca); + val_1xca |= (0x11<> ch) & 0x01; + n5_write_register(ViPipe, 0xff, 0x05+ch); + val_5xf0 = n5_read_register(ViPipe, 0xf0); + //if(0xFF == val_5xf0 || (0x0F == (val_5xf0&0x0F)) || (0xF0 == (val_5xf0&0xF0)) ) //no video + if (ch_vloss[ch] == 0 && ch_prevloss[ch] == 1) { + if (val_5xf0 == 0xFF) { + //printk("1pre_vfc[%d]=%2x val_5xf0=%2x\n",ch, pre_vfc[ch], val_5xf0); + if (chn_mode[ch] != NC_VIVO_CH_FORMATDEF_UNKNOWN) { + n5_set_chnmode(ViPipe, ch, NC_VIVO_CH_FORMATDEF_UNKNOWN); + n5_write_register(ViPipe, 0xff, 0x05+ch); + n5_write_register(ViPipe, 0xB8, 0xB8); + n5_write_register(ViPipe, 0xff, 0x13); + val_13x70 = n5_read_register(ViPipe, 0x70); + val_13x70 &= (~(0x01< +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_isp.h" + +#include "n6_cmos_ex.h" +#include "n6_cmos_param.h" + +/**************************************************************************** + * global variables * + ****************************************************************************/ +ISP_SNS_COMMBUS_U g_aunN6_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_STATE_S *g_pastN6[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define N6_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastN6[dev]) +#define N6_SENSOR_SET_CTX(dev, pstCtx) (g_pastN6[dev] = pstCtx) +#define N6_SENSOR_RESET_CTX(dev) (g_pastN6[dev] = CVI_NULL) +#define N6_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) +#define N6_ID 0xE0 + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const N6_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + N6_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astN6_mode[pstSnsState->u8ImgMode]; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + N6_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstCfg0 = &pstSnsState->astSyncInfo[0]; + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + N6_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + + if (pstSensorImageMode->f32Fps <= 30) { + if (N6_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = N6_MODE_1080P_25P; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + N6_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->u8ImgMode = N6_MODE_1080P_25P; + pstSnsState->enWDRMode = WDR_MODE_NONE; +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + N6_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &n6_rx_attr, sizeof(*pstRxAttr)); + CVI_TRACE_SNS(CVI_DBG_ERR, "get n6_rx0_attr\n"); + + pstRxAttr->img_size.width = g_astN6_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astN6_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &n6_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = n6_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = n6_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 n6_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunN6_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + N6_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + N6_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + N6_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + N6_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + (void) pstAeLib; + (void) pstAwbLib; + + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = N6_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + (void) pstAeLib; + (void) pstAwbLib; + + CVI_S32 s32Ret; + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, N6_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsN6_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnMirrorFlip = CVI_NULL, + .pfnStandby = CVI_NULL, + .pfnRestart = CVI_NULL, + .pfnWriteReg = n6_write_register, + .pfnReadReg = n6_read_register, + .pfnSetBusInfo = n6_set_bus_info, + .pfnSetInit = CVI_NULL, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = CVI_NULL, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/nextchip_n6/n6_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/nextchip_n6/n6_cmos_ex.h new file mode 100644 index 000000000..485a8021b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/nextchip_n6/n6_cmos_ex.h @@ -0,0 +1,107 @@ +#ifndef __N6_CMOS_EX_H_ +#define __N6_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +typedef enum _N6_MODE_E { + N6_MODE_H720_NT = 1, + N6_MODE_H720_PAL, + N6_MODE_720P_30P, + N6_MODE_720P_25P, + N6_MODE_960P_30P, + N6_MODE_960P_25P, + N6_MODE_1080P_30P, + N6_MODE_1080P_25P, + N6_MODE_1080P_60P, + N6_MODE_1080P_50P, + N6_MODE_4M_30P, + N6_MODE_4M_25P, + N6_MODE_8M_15P, + N6_MODE_8M_12_5P, + N6_MODE_NUM +} N6_MODE_E; + +typedef enum _n6_outmode_sel { + N6_OUTMODE_1MUX_SD = 0, + N6_OUTMODE_1MUX_HD, + N6_OUTMODE_1MUX_FHD, + N6_OUTMODE_1MUX_FHD_HALF, + N6_OUTMODE_2MUX_SD, + N6_OUTMODE_2MUX_HD, + N6_OUTMODE_2MUX_FHD, + N6_OUTMODE_1MUX_BT1120S, + N6_OUTMODE_2MUX_BT1120S_720P, + N6_OUTMODE_2MUX_BT1120S_1080P, + N6_OUTMODE_BUTT +} N6_OUTMODE_SEL; + +typedef struct _N6_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + char name[64]; +} N6_MODE_S; + +#define _MIPI_PORT0_ +//#define _MIPI_PORT1_ + +#ifdef _MIPI_PORT0_ +#define _MAR_BANK_ 0x20 +#define _MTX_BANK_ 0x23 +#else +#define _MAR_BANK_ 0x30 +#define _MTX_BANK_ 0x33 +#endif + +#define CH0_NO 0 +#define CH1_NO 1 +#define NTPAL 0 + +#define VFMT_NTSC 0 +#define VFMT_PAL 1 + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastN6[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunN6_BusInfo[]; +extern const CVI_U8 n6_i2c_addr; +extern const CVI_U32 n6_addr_byte; +extern const CVI_U32 n6_data_byte; +extern void n6_init(VI_PIPE ViPipe); +extern void n6_exit(VI_PIPE ViPipe); +extern void n6_standby(VI_PIPE ViPipe); +extern void n6_restart(VI_PIPE ViPipe); +extern int n6_write_register(VI_PIPE ViPipe, int addr, int data); +extern int n6_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __N6_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/nextchip_n6/n6_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/nextchip_n6/n6_cmos_param.h new file mode 100644 index 000000000..0698002ba --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/nextchip_n6/n6_cmos_param.h @@ -0,0 +1,71 @@ +#ifndef __N6_CMOS_PARAM_H_ +#define __N6_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "n6_cmos_ex.h" + +static const N6_MODE_S g_astN6_mode[N6_MODE_NUM] = { + [N6_MODE_1080P_25P] = { + .name = "1080p25", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + }, +}; + +struct combo_dev_attr_s n6_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_400M, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .mipi_attr = { + .raw_data_type = YUV422_8BIT, + .lane_id = {2, 0, 1, 3, 4}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + .demux = { + .demux_en = 1, + .vc_mapping = {0, 1, 2, 3}, + }, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __N6_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/nextchip_n6/n6_sensor_ctrl.c b/middleware/v2/component/isp/sensor/cv180x/nextchip_n6/n6_sensor_ctrl.c new file mode 100644 index 000000000..f803c9c11 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/nextchip_n6/n6_sensor_ctrl.c @@ -0,0 +1,842 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include +#include "cvi_sns_ctrl.h" +#include "n6_cmos_ex.h" +#include +#include + +const CVI_U8 n6_i2c_addr = 0x31; /* I2C slave address of N6, SA0=0:0x32, SA0=1:0x33*/ +const CVI_U32 n6_addr_byte = 1; +const CVI_U32 n6_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; +static CVI_U32 adet; +//static CVI_U32 fmt = 1; //0:960h 1:720P 2:1080P +//static unsigned int ntpal = 0; //0:ntsc/30p 1:pal/25p +static CVI_U32 mclk = 1; //0:1458 1:756 + +#define N6_TEST_PATTERN 1 + +int n6_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunN6_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + syslog(LOG_DEBUG, "open %s\n", acDevFile); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, n6_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int n6_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int n6_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return 0; + + if (n6_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, n6_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, n6_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (n6_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int n6_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (n6_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + if (n6_data_byte == 2) + buf[idx++] = (data >> 8) & 0xff; + + // add data byte 0 + buf[idx++] = data & 0xff; + + ret = write(g_fd[ViPipe], buf, n6_addr_byte + n6_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + +#if 0 // read back checing + ret = n6_read_register(ViPipe, addr); + if (ret != data) + syslog(LOG_DEBUG, "i2c readback-check fail, 0x%x != 0x%x\n", ret, data); +#endif + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void n6_common_setting(VI_PIPE ViPipe) +{ + CVI_U8 ch; + + n6_write_register(ViPipe, 0xff, 0x00); + n6_write_register(ViPipe, 0x80, 0x0f); + n6_write_register(ViPipe, 0x00, 0x10); + n6_write_register(ViPipe, 0x01, 0x10); + n6_write_register(ViPipe, 0x02, 0x10); + n6_write_register(ViPipe, 0x03, 0x10); + n6_write_register(ViPipe, 0x22, 0x0b); + n6_write_register(ViPipe, 0x23, 0x41); + n6_write_register(ViPipe, 0x26, 0x0b); + n6_write_register(ViPipe, 0x27, 0x41); + n6_write_register(ViPipe, 0x2a, 0x0b); + n6_write_register(ViPipe, 0x2b, 0x41); + n6_write_register(ViPipe, 0x2e, 0x0b); + n6_write_register(ViPipe, 0x2f, 0x41); + + n6_write_register(ViPipe, 0xff, 0x01); + n6_write_register(ViPipe, 0x98, 0x30); + n6_write_register(ViPipe, 0xed, 0x00); + + for (ch = 0; ch < 4; ch++) { + n6_write_register(ViPipe, 0xff, 0x05 + ch); + n6_write_register(ViPipe, 0x00, 0xd0); + n6_write_register(ViPipe, 0x01, 0x22); + n6_write_register(ViPipe, 0x47, 0xee); + n6_write_register(ViPipe, 0x50, 0xc6); + n6_write_register(ViPipe, 0x57, 0x00); + n6_write_register(ViPipe, 0x58, 0x77); + n6_write_register(ViPipe, 0x5b, 0x41); + n6_write_register(ViPipe, 0x5c, 0x78); + n6_write_register(ViPipe, 0xB8, 0xB8); + } + + n6_write_register(ViPipe, 0xff, 0x09); + n6_write_register(ViPipe, 0x50, 0x30); + n6_write_register(ViPipe, 0x51, 0x6f); + n6_write_register(ViPipe, 0x52, 0x67); + n6_write_register(ViPipe, 0x53, 0x48); + n6_write_register(ViPipe, 0x54, 0x30); + n6_write_register(ViPipe, 0x55, 0x6f); + n6_write_register(ViPipe, 0x56, 0x67); + n6_write_register(ViPipe, 0x57, 0x48); + n6_write_register(ViPipe, 0x58, 0x30); + n6_write_register(ViPipe, 0x59, 0x6f); + n6_write_register(ViPipe, 0x5a, 0x67); + n6_write_register(ViPipe, 0x5b, 0x48); + n6_write_register(ViPipe, 0x5c, 0x30); + n6_write_register(ViPipe, 0x5d, 0x6f); + n6_write_register(ViPipe, 0x5e, 0x67); + n6_write_register(ViPipe, 0x5f, 0x48); + + n6_write_register(ViPipe, 0xff, 0x0a); + n6_write_register(ViPipe, 0x25, 0x10); + n6_write_register(ViPipe, 0x27, 0x1e); + n6_write_register(ViPipe, 0x30, 0xac); + n6_write_register(ViPipe, 0x31, 0x78); + n6_write_register(ViPipe, 0x32, 0x17); + n6_write_register(ViPipe, 0x33, 0xc1); + n6_write_register(ViPipe, 0x34, 0x40); + n6_write_register(ViPipe, 0x35, 0x00); + n6_write_register(ViPipe, 0x36, 0xc3); + n6_write_register(ViPipe, 0x37, 0x0a); + n6_write_register(ViPipe, 0x38, 0x00); + n6_write_register(ViPipe, 0x39, 0x02); + n6_write_register(ViPipe, 0x3a, 0x00); + n6_write_register(ViPipe, 0x3b, 0xb2); + n6_write_register(ViPipe, 0xa5, 0x10); + n6_write_register(ViPipe, 0xa7, 0x1e); + n6_write_register(ViPipe, 0xb0, 0xac); + n6_write_register(ViPipe, 0xb1, 0x78); + n6_write_register(ViPipe, 0xb2, 0x17); + n6_write_register(ViPipe, 0xb3, 0xc1); + n6_write_register(ViPipe, 0xb4, 0x40); + n6_write_register(ViPipe, 0xb5, 0x00); + n6_write_register(ViPipe, 0xb6, 0xc3); + n6_write_register(ViPipe, 0xb7, 0x0a); + n6_write_register(ViPipe, 0xb8, 0x00); + n6_write_register(ViPipe, 0xb9, 0x02); + n6_write_register(ViPipe, 0xba, 0x00); + n6_write_register(ViPipe, 0xbb, 0xb2); + n6_write_register(ViPipe, 0xff, 0x0b); + n6_write_register(ViPipe, 0x25, 0x10); + n6_write_register(ViPipe, 0x27, 0x1e); + n6_write_register(ViPipe, 0x30, 0xac); + n6_write_register(ViPipe, 0x31, 0x78); + n6_write_register(ViPipe, 0x32, 0x17); + n6_write_register(ViPipe, 0x33, 0xc1); + n6_write_register(ViPipe, 0x34, 0x40); + n6_write_register(ViPipe, 0x35, 0x00); + n6_write_register(ViPipe, 0x36, 0xc3); + n6_write_register(ViPipe, 0x37, 0x0a); + n6_write_register(ViPipe, 0x38, 0x00); + n6_write_register(ViPipe, 0x39, 0x02); + n6_write_register(ViPipe, 0x3a, 0x00); + n6_write_register(ViPipe, 0x3b, 0xb2); + n6_write_register(ViPipe, 0xa5, 0x10); + n6_write_register(ViPipe, 0xa7, 0x1e); + n6_write_register(ViPipe, 0xb0, 0xac); + n6_write_register(ViPipe, 0xb1, 0x78); + n6_write_register(ViPipe, 0xb2, 0x17); + n6_write_register(ViPipe, 0xb3, 0xc1); + n6_write_register(ViPipe, 0xb4, 0x40); + n6_write_register(ViPipe, 0xb5, 0x00); + n6_write_register(ViPipe, 0xb6, 0xc3); + n6_write_register(ViPipe, 0xb7, 0x0a); + n6_write_register(ViPipe, 0xb8, 0x00); + n6_write_register(ViPipe, 0xb9, 0x02); + n6_write_register(ViPipe, 0xba, 0x00); + n6_write_register(ViPipe, 0xbb, 0xb2); + + n6_write_register(ViPipe, 0xff, 0x13); + n6_write_register(ViPipe, 0x05, 0xa0); + n6_write_register(ViPipe, 0x31, 0xff); + n6_write_register(ViPipe, 0x07, 0x47); + n6_write_register(ViPipe, 0x12, 0x04); + n6_write_register(ViPipe, 0x1e, 0x1f); + n6_write_register(ViPipe, 0x1f, 0x27); + n6_write_register(ViPipe, 0x2e, 0x10); + n6_write_register(ViPipe, 0x2f, 0xc8); + n6_write_register(ViPipe, 0x31, 0xff); + n6_write_register(ViPipe, 0x32, 0x00); + n6_write_register(ViPipe, 0x33, 0x00); + n6_write_register(ViPipe, 0x72, 0x05); + n6_write_register(ViPipe, 0x7a, 0xf0); + + n6_write_register(ViPipe, 0xff, _MAR_BANK_); + n6_write_register(ViPipe, 0x10, 0xff); + n6_write_register(ViPipe, 0x11, 0xff); + if (mclk == 1) { + n6_write_register(ViPipe, 0x30, 0x0f); + n6_write_register(ViPipe, 0x32, 0x92); + n6_write_register(ViPipe, 0x34, 0xcd); + n6_write_register(ViPipe, 0x36, 0x04); + n6_write_register(ViPipe, 0x38, 0x58); + } else { + n6_write_register(ViPipe, 0x30, 0x0f); + n6_write_register(ViPipe, 0x32, 0xff); + n6_write_register(ViPipe, 0x34, 0xcd); + n6_write_register(ViPipe, 0x36, 0x04); + n6_write_register(ViPipe, 0x38, 0xff); + } + n6_write_register(ViPipe, 0x3c, 0x01); + n6_write_register(ViPipe, 0x3d, 0x11); + n6_write_register(ViPipe, 0x3e, 0x11); + n6_write_register(ViPipe, 0x45, 0x60); + n6_write_register(ViPipe, 0x46, 0x49); + + n6_write_register(ViPipe, 0xff, _MTX_BANK_); + n6_write_register(ViPipe, 0xe9, 0x03); + n6_write_register(ViPipe, 0x03, 0x02); + n6_write_register(ViPipe, 0x01, 0xe4); + n6_write_register(ViPipe, 0x00, 0x7d); + n6_write_register(ViPipe, 0x01, 0xe0); + n6_write_register(ViPipe, 0x02, 0xa0); + n6_write_register(ViPipe, 0x20, 0x1e); + n6_write_register(ViPipe, 0x20, 0x1f); + + if (mclk == 1) { + n6_write_register(ViPipe, 0x04, 0x38); + n6_write_register(ViPipe, 0x45, 0xc4); + n6_write_register(ViPipe, 0x46, 0x01); + n6_write_register(ViPipe, 0x47, 0x1b); + n6_write_register(ViPipe, 0x48, 0x08); + n6_write_register(ViPipe, 0x65, 0xc4); + n6_write_register(ViPipe, 0x66, 0x01); + n6_write_register(ViPipe, 0x67, 0x1b); + n6_write_register(ViPipe, 0x68, 0x08); + n6_write_register(ViPipe, 0x85, 0xc4); + n6_write_register(ViPipe, 0x86, 0x01); + n6_write_register(ViPipe, 0x87, 0x1b); + n6_write_register(ViPipe, 0x88, 0x08); + n6_write_register(ViPipe, 0xa5, 0xc4); + n6_write_register(ViPipe, 0xa6, 0x01); + n6_write_register(ViPipe, 0xa7, 0x1b); + n6_write_register(ViPipe, 0xa8, 0x08); + n6_write_register(ViPipe, 0xc5, 0xc4); + n6_write_register(ViPipe, 0xc6, 0x01); + n6_write_register(ViPipe, 0xc7, 0x1b); + n6_write_register(ViPipe, 0xc8, 0x08); + } else { + n6_write_register(ViPipe, 0x04, 0x6c); + n6_write_register(ViPipe, 0x45, 0xcd); + n6_write_register(ViPipe, 0x46, 0x42); + n6_write_register(ViPipe, 0x47, 0x36); + n6_write_register(ViPipe, 0x48, 0x0f); + n6_write_register(ViPipe, 0x65, 0xcd); + n6_write_register(ViPipe, 0x66, 0x42); + n6_write_register(ViPipe, 0x67, 0x0e); + n6_write_register(ViPipe, 0x68, 0x0f); + n6_write_register(ViPipe, 0x85, 0xcd); + n6_write_register(ViPipe, 0x86, 0x42); + n6_write_register(ViPipe, 0x87, 0x0e); + n6_write_register(ViPipe, 0x88, 0x0f); + n6_write_register(ViPipe, 0xa5, 0xcd); + n6_write_register(ViPipe, 0xa6, 0x42); + n6_write_register(ViPipe, 0xa7, 0x0e); + n6_write_register(ViPipe, 0xa8, 0x0f); + n6_write_register(ViPipe, 0xc5, 0xcd); + n6_write_register(ViPipe, 0xc6, 0x42); + n6_write_register(ViPipe, 0xc7, 0x0e); + n6_write_register(ViPipe, 0xc8, 0x0f); + } + n6_write_register(ViPipe, 0xeb, 0x8d); + + n6_write_register(ViPipe, 0xff, _MAR_BANK_); + n6_write_register(ViPipe, 0x00, 0xff); + n6_write_register(ViPipe, 0x40, 0x01); + n6_write_register(ViPipe, 0x40, 0x00); + n6_write_register(ViPipe, 0xff, 0x01); + n6_write_register(ViPipe, 0x97, 0x00); + n6_write_register(ViPipe, 0x97, 0x0f); + + n6_write_register(ViPipe, 0xff, 0x00); //test pattern + n6_write_register(ViPipe, 0x78, 0xba); + n6_write_register(ViPipe, 0x79, 0xac); + n6_write_register(ViPipe, 0xff, 0x05); + n6_write_register(ViPipe, 0x2c, 0x08); + n6_write_register(ViPipe, 0x6a, 0x80); + n6_write_register(ViPipe, 0xff, 0x06); + n6_write_register(ViPipe, 0x2c, 0x08); + n6_write_register(ViPipe, 0x6a, 0x80); + n6_write_register(ViPipe, 0xff, 0x07); + n6_write_register(ViPipe, 0x2c, 0x08); + n6_write_register(ViPipe, 0x6a, 0x80); + n6_write_register(ViPipe, 0xff, 0x08); + n6_write_register(ViPipe, 0x2c, 0x08); + n6_write_register(ViPipe, 0x6a, 0x80); +} + +void n6_set_chn_960h(VI_PIPE ViPipe, CVI_U8 ch, CVI_U8 ntpal) +{ + CVI_U8 val_0x54, val_20x01; + + CVI_TRACE_SNS(CVI_DBG_INFO, "%s ch=%d\n", __func__, ch); + + n6_write_register(ViPipe, 0xff, 0x00); + n6_write_register(ViPipe, 0x08 + ch, ntpal ? 0xdd : 0xa0); + n6_write_register(ViPipe, 0x18 + ch, 0x08); + n6_write_register(ViPipe, 0x22 + ch * 4, 0x0b); + n6_write_register(ViPipe, 0x23 + ch * 4, 0x41); + n6_write_register(ViPipe, 0x30 + ch, 0x12); + n6_write_register(ViPipe, 0x34 + ch, 0x01); + val_0x54 = n6_read_register(ViPipe, 0x54); + if (ntpal) + val_0x54 &= ~(0x10 << ch); + else + val_0x54 |= (0x10 << ch); + n6_write_register(ViPipe, 0x54, val_0x54); + n6_write_register(ViPipe, 0x58 + ch, ntpal ? 0x80 : 0x90); + n6_write_register(ViPipe, 0x5c + ch, ntpal ? 0xbe : 0xbc); + n6_write_register(ViPipe, 0x64 + ch, ntpal ? 0xa0 : 0x81); + n6_write_register(ViPipe, 0x81 + ch, ntpal ? 0xf0 : 0xe0); + n6_write_register(ViPipe, 0x85 + ch, 0x00); + n6_write_register(ViPipe, 0x89 + ch, 0x00); + n6_write_register(ViPipe, 0x8e + ch, 0x00); + n6_write_register(ViPipe, 0xa0 + ch, 0x05); + + n6_write_register(ViPipe, 0xff, 0x01); + n6_write_register(ViPipe, 0x84 + ch, 0x02); + n6_write_register(ViPipe, 0x88 + ch, 0x00); + n6_write_register(ViPipe, 0x8c + ch, 0x40); + n6_write_register(ViPipe, 0xa0 + ch, 0x20); + n6_write_register(ViPipe, 0xed, 0x00); + + n6_write_register(ViPipe, 0xff, 0x05 + ch); + n6_write_register(ViPipe, 0x01, 0x22); + n6_write_register(ViPipe, 0x05, 0x00); + n6_write_register(ViPipe, 0x08, 0x55); + n6_write_register(ViPipe, 0x25, 0xdc); + n6_write_register(ViPipe, 0x28, 0x80); + n6_write_register(ViPipe, 0x2f, 0x00); + n6_write_register(ViPipe, 0x30, 0xe0); + n6_write_register(ViPipe, 0x31, 0x43); + n6_write_register(ViPipe, 0x32, 0xa2); + n6_write_register(ViPipe, 0x47, 0x04); + n6_write_register(ViPipe, 0x50, 0x84); + n6_write_register(ViPipe, 0x57, 0x00); + n6_write_register(ViPipe, 0x58, 0x77); + n6_write_register(ViPipe, 0x5b, 0x43); + n6_write_register(ViPipe, 0x5c, 0x78); + n6_write_register(ViPipe, 0x5f, 0x00); + n6_write_register(ViPipe, 0x62, 0x20); + n6_write_register(ViPipe, 0x7b, 0x00); + n6_write_register(ViPipe, 0x7c, 0x01); + n6_write_register(ViPipe, 0x7d, 0x80); + n6_write_register(ViPipe, 0x80, 0x00); + n6_write_register(ViPipe, 0x90, 0x01); + n6_write_register(ViPipe, 0xa9, 0x00); + n6_write_register(ViPipe, 0xb5, 0x00); + n6_write_register(ViPipe, 0xb8, 0xb9); + n6_write_register(ViPipe, 0xb9, 0x72); + n6_write_register(ViPipe, 0xd1, 0x00); + n6_write_register(ViPipe, 0xd5, 0x80); + + n6_write_register(ViPipe, 0xff, 0x09); + n6_write_register(ViPipe, 0x96 + ch * 0x20, 0x10); + n6_write_register(ViPipe, 0x98 + ch * 0x20, ntpal ? 0xc0 : 0xe0); + n6_write_register(ViPipe, 0x9e + ch * 0x20, 0x00); + + n6_write_register(ViPipe, 0xff, _MAR_BANK_); + val_20x01 = n6_read_register(ViPipe, 0x01); + val_20x01 &= (~(0x03 << (ch * 2))); + val_20x01 |= (0x02 << (ch * 2)); + n6_write_register(ViPipe, 0x01, val_20x01); + n6_write_register(ViPipe, 0x12 + ch * 2, 0xe0); + n6_write_register(ViPipe, 0x13 + ch * 2, 0x01); + +} + +void n6_set_chn_720p(VI_PIPE ViPipe, CVI_U8 ch, CVI_U8 ntpal) +{ + CVI_U8 val_0x54, val_20x01; + + CVI_TRACE_SNS(CVI_DBG_INFO, "%s ch=%d\n", __func__, ch); + + n6_write_register(ViPipe, 0xff, 0x00); + n6_write_register(ViPipe, 0x08 + ch, 0x00); + n6_write_register(ViPipe, 0x18 + ch, 0x3f); + n6_write_register(ViPipe, 0x30 + ch, 0x12); + n6_write_register(ViPipe, 0x34 + ch, 0x00); + val_0x54 = n6_read_register(ViPipe, 0x54); + val_0x54 &= ~(0x10 << ch); + n6_write_register(ViPipe, 0x54, val_0x54); + n6_write_register(ViPipe, 0x58 + ch, ntpal ? 0x80 : 0x80); + n6_write_register(ViPipe, 0x5c + ch, ntpal ? 0x00 : 0x00); + n6_write_register(ViPipe, 0x64 + ch, ntpal ? 0x01 : 0x01); + n6_write_register(ViPipe, 0x81 + ch, ntpal ? 0x0d : 0x0c); + n6_write_register(ViPipe, 0x85 + ch, 0x00); + n6_write_register(ViPipe, 0x89 + ch, 0x00); + n6_write_register(ViPipe, 0x8e + ch, 0x00); + n6_write_register(ViPipe, 0xa0 + ch, 0x05); + + n6_write_register(ViPipe, 0xff, 0x01); + n6_write_register(ViPipe, 0x84 + ch, 0x02); + n6_write_register(ViPipe, 0x88 + ch, 0x00); + n6_write_register(ViPipe, 0x8c + ch, 0x40); + n6_write_register(ViPipe, 0xa0 + ch, 0x20); + + n6_write_register(ViPipe, 0xff, 0x05 + ch); + n6_write_register(ViPipe, 0x01, 0x22); + n6_write_register(ViPipe, 0x05, 0x04); + n6_write_register(ViPipe, 0x08, 0x55); + n6_write_register(ViPipe, 0x25, 0xdc); + n6_write_register(ViPipe, 0x28, 0x80); + n6_write_register(ViPipe, 0x2f, 0x00); + n6_write_register(ViPipe, 0x30, 0xe0); + n6_write_register(ViPipe, 0x31, 0x43); + n6_write_register(ViPipe, 0x32, 0xa2); + n6_write_register(ViPipe, 0x47, 0xee); + n6_write_register(ViPipe, 0x50, 0xc6); + n6_write_register(ViPipe, 0x57, 0x00); + n6_write_register(ViPipe, 0x58, 0x77); + n6_write_register(ViPipe, 0x5b, 0x41); + n6_write_register(ViPipe, 0x5c, 0x7C); + n6_write_register(ViPipe, 0x5f, 0x00); + n6_write_register(ViPipe, 0x62, 0x20); + n6_write_register(ViPipe, 0x7b, 0x11); + n6_write_register(ViPipe, 0x7c, 0x01); + n6_write_register(ViPipe, 0x7d, 0x80); + n6_write_register(ViPipe, 0x80, 0x00); + n6_write_register(ViPipe, 0x90, 0x01); + n6_write_register(ViPipe, 0xa9, 0x00); + n6_write_register(ViPipe, 0xb5, 0x40); + n6_write_register(ViPipe, 0xb8, 0x39); + n6_write_register(ViPipe, 0xb9, 0x72); + n6_write_register(ViPipe, 0xd1, 0x00); + n6_write_register(ViPipe, 0xd5, 0x80); + + n6_write_register(ViPipe, 0xff, 0x09); + n6_write_register(ViPipe, 0x96 + ch * 0x20, 0x00); + n6_write_register(ViPipe, 0x98 + ch * 0x20, 0x00); + n6_write_register(ViPipe, 0x9e + ch * 0x20, 0x00); + + n6_write_register(ViPipe, 0xff, _MAR_BANK_); + val_20x01 = n6_read_register(ViPipe, 0x01); + val_20x01 &= (~(0x03 << (ch * 2))); + val_20x01 |= (0x01 << (ch * 2)); + n6_write_register(ViPipe, 0x01, val_20x01); + n6_write_register(ViPipe, 0x12 + ch * 2, 0x80); + n6_write_register(ViPipe, 0x13 + ch * 2, 0x02); + +} + +/* + * 1280x960p + * dev:0x60 / 0x62 / 0x64 / 0x66 + * ch : 0 ~ 3 + * ntpal: 1:25p, 0:30p + */ +void n6_set_chn_960p(VI_PIPE ViPipe, CVI_U8 ch, CVI_U8 ntpal) +{ + CVI_U8 val_0x54, val_20x01; + + CVI_TRACE_SNS(CVI_DBG_INFO, "%s ch=%d\n", __func__, ch); + + n6_write_register(ViPipe, 0xff, 0x00); + n6_write_register(ViPipe, 0x08 + ch, 0x00); + n6_write_register(ViPipe, 0x18 + ch, 0x0f); + n6_write_register(ViPipe, 0x30 + ch, 0x12); + n6_write_register(ViPipe, 0x34 + ch, 0x00); + val_0x54 = n6_read_register(ViPipe, 0x54); + val_0x54 &= ~(0x10 << ch); + n6_write_register(ViPipe, 0x54, val_0x54); + n6_write_register(ViPipe, 0x58 + ch, ntpal ? 0x40 : 0x48); + n6_write_register(ViPipe, 0x5c + ch, ntpal ? 0x80 : 0x80); + n6_write_register(ViPipe, 0x64 + ch, ntpal ? 0x28 : 0x28); + n6_write_register(ViPipe, 0x81 + ch, ntpal ? 0x07 : 0x06); + n6_write_register(ViPipe, 0x85 + ch, 0x0b); + n6_write_register(ViPipe, 0x89 + ch, 0x00); + n6_write_register(ViPipe, 0x8e + ch, 0x00); + n6_write_register(ViPipe, 0xa0 + ch, 0x05); + + n6_write_register(ViPipe, 0xff, 0x01); + n6_write_register(ViPipe, 0x84 + ch, 0x02); + n6_write_register(ViPipe, 0x88 + ch, 0x00); + n6_write_register(ViPipe, 0x8c + ch, 0x40); + n6_write_register(ViPipe, 0xa0 + ch, 0x20); + + n6_write_register(ViPipe, 0xff, 0x05 + ch); + n6_write_register(ViPipe, 0x01, 0x22); + n6_write_register(ViPipe, 0x05, 0x04); + n6_write_register(ViPipe, 0x08, 0x55); + n6_write_register(ViPipe, 0x25, 0xdc); + n6_write_register(ViPipe, 0x28, 0x80); + n6_write_register(ViPipe, 0x2f, 0x00); + n6_write_register(ViPipe, 0x30, 0xe0); + n6_write_register(ViPipe, 0x31, 0x43); + n6_write_register(ViPipe, 0x32, 0xa2); + n6_write_register(ViPipe, 0x47, 0xee); + n6_write_register(ViPipe, 0x50, 0xc6); + n6_write_register(ViPipe, 0x57, 0x00); + n6_write_register(ViPipe, 0x58, 0x77); + n6_write_register(ViPipe, 0x5b, 0x41); + n6_write_register(ViPipe, 0x5c, 0x7C); + n6_write_register(ViPipe, 0x5f, 0x00); + n6_write_register(ViPipe, 0x62, 0x20); + n6_write_register(ViPipe, 0x7b, 0x11); + n6_write_register(ViPipe, 0x7c, 0x01); + n6_write_register(ViPipe, 0x7d, 0x80); + n6_write_register(ViPipe, 0x80, 0x00); + n6_write_register(ViPipe, 0x90, 0x01); + n6_write_register(ViPipe, 0xa9, 0x00); + n6_write_register(ViPipe, 0xb5, 0x40); + n6_write_register(ViPipe, 0xb8, 0x39); + n6_write_register(ViPipe, 0xb9, 0x72); + n6_write_register(ViPipe, 0xd1, 0x00); + n6_write_register(ViPipe, 0xd5, 0x80); + + n6_write_register(ViPipe, 0xff, 0x09); + n6_write_register(ViPipe, 0x96 + ch * 0x20, 0x00); + n6_write_register(ViPipe, 0x98 + ch * 0x20, 0x00); + n6_write_register(ViPipe, 0x9e + ch * 0x20, 0x00); + + n6_write_register(ViPipe, 0xff, _MAR_BANK_); + val_20x01 = n6_read_register(ViPipe, 0x01); + val_20x01 &= (~(0x03 << (ch * 2))); + //val_20x01 |=(0x01<<(ch*2)); + n6_write_register(ViPipe, 0x01, val_20x01); + n6_write_register(ViPipe, 0x12 + ch * 2, 0x80); + n6_write_register(ViPipe, 0x13 + ch * 2, 0x02); + +} + +void n6_set_chn_1080p(VI_PIPE ViPipe, CVI_U8 ch, CVI_U8 ntpal) +{ + CVI_U8 val_0x54, val_20x01; + + CVI_TRACE_SNS(CVI_DBG_INFO, "%s ch=%d\n", __func__, ch); + + n6_write_register(ViPipe, 0xff, 0x00); + n6_write_register(ViPipe, 0x08 + ch, 0x00); + n6_write_register(ViPipe, 0x18 + ch, 0x3f); + n6_write_register(ViPipe, 0x30 + ch, 0x12); + n6_write_register(ViPipe, 0x34 + ch, 0x00); + val_0x54 = n6_read_register(ViPipe, 0x54); + val_0x54 &= ~(0x10 << ch); + n6_write_register(ViPipe, 0x54, val_0x54); + n6_write_register(ViPipe, 0x58 + ch, ntpal ? 0x80 : 0x80); + n6_write_register(ViPipe, 0x5c + ch, ntpal ? 0x00 : 0x00); + n6_write_register(ViPipe, 0x64 + ch, ntpal ? 0x01 : 0x01); + n6_write_register(ViPipe, 0x81 + ch, ntpal ? 0x03 : 0x02); + n6_write_register(ViPipe, 0x85 + ch, 0x00); + n6_write_register(ViPipe, 0x89 + ch, 0x10); + n6_write_register(ViPipe, 0x8e + ch, 0x00); + n6_write_register(ViPipe, 0xa0 + ch, 0x05); + + n6_write_register(ViPipe, 0xff, 0x01); + n6_write_register(ViPipe, 0x84 + ch, 0x02); + n6_write_register(ViPipe, 0x88 + ch, 0x00); + n6_write_register(ViPipe, 0x8c + ch, 0x40); + n6_write_register(ViPipe, 0xa0 + ch, 0x20); + + n6_write_register(ViPipe, 0xff, 0x05 + ch); + n6_write_register(ViPipe, 0x01, 0x22); + n6_write_register(ViPipe, 0x05, 0x04); + n6_write_register(ViPipe, 0x08, 0x55); + n6_write_register(ViPipe, 0x25, 0xdc); + n6_write_register(ViPipe, 0x28, 0x80); + n6_write_register(ViPipe, 0x2f, 0x00); + n6_write_register(ViPipe, 0x30, 0xe0); + n6_write_register(ViPipe, 0x31, 0x41); + n6_write_register(ViPipe, 0x32, 0xa2); + n6_write_register(ViPipe, 0x47, 0xee); + n6_write_register(ViPipe, 0x50, 0xc6); + n6_write_register(ViPipe, 0x57, 0x00); + n6_write_register(ViPipe, 0x58, 0x77); + n6_write_register(ViPipe, 0x5b, 0x41); + n6_write_register(ViPipe, 0x5c, 0x7C); + n6_write_register(ViPipe, 0x5f, 0x00); + n6_write_register(ViPipe, 0x62, 0x20); + n6_write_register(ViPipe, 0x7b, 0x11); + n6_write_register(ViPipe, 0x7c, 0x01); + n6_write_register(ViPipe, 0x7d, 0x80); + n6_write_register(ViPipe, 0x80, 0x00); + n6_write_register(ViPipe, 0x90, 0x01); + n6_write_register(ViPipe, 0xa9, 0x00); + n6_write_register(ViPipe, 0xb5, 0x40); + n6_write_register(ViPipe, 0xb8, 0x39); + n6_write_register(ViPipe, 0xb9, 0x72); + n6_write_register(ViPipe, 0xd1, 0x00); + n6_write_register(ViPipe, 0xd5, 0x80); + + n6_write_register(ViPipe, 0xff, 0x09); + n6_write_register(ViPipe, 0x96 + ch * 0x20, 0x00); + n6_write_register(ViPipe, 0x98 + ch * 0x20, 0x00); + n6_write_register(ViPipe, 0x9e + ch * 0x20, 0x00); + + n6_write_register(ViPipe, 0xff, _MAR_BANK_); + val_20x01 = n6_read_register(ViPipe, 0x01); + val_20x01 &= (~(0x03 << (ch * 2))); + n6_write_register(ViPipe, 0x01, val_20x01); + n6_write_register(ViPipe, 0x12 + ch*2, 0xc0); + n6_write_register(ViPipe, 0x13 + ch*2, 0x03); + +} + +unsigned char n6_read_vfc(VI_PIPE ViPipe, CVI_U8 ch) +{ + CVI_U8 ch_vfc = 0xff; + + n6_write_register(ViPipe, 0xff, 0x05 + ch); + ch_vfc = n6_read_register(ViPipe, 0xf0); + + return ch_vfc; +} + +void n6_device_auto_detect(VI_PIPE ViPipe) +{ + CVI_U8 ch_vfc[16] = {0xff, 0xff, 0xff, 0xff, 0xff}; + CVI_U8 val_13x70, val_13x71; + int check_cnt = 0; + CVI_U8 ch; + + CVI_TRACE_SNS(CVI_DBG_INFO, "%s auto detection routine\n", __func__); + + n6_write_register(ViPipe, 0xFF, 0x13); + n6_write_register(ViPipe, 0x30, 0x7f); + n6_write_register(ViPipe, 0x70, 0xf0); + n6_write_register(ViPipe, 0xFF, 0x00); + n6_write_register(ViPipe, 0x00, 0x18); + n6_write_register(ViPipe, 0x01, 0x18); + n6_write_register(ViPipe, 0x02, 0x18); + n6_write_register(ViPipe, 0x03, 0x18); + n6_write_register(ViPipe, 0x00, 0x10); + n6_write_register(ViPipe, 0x01, 0x10); + n6_write_register(ViPipe, 0x02, 0x10); + n6_write_register(ViPipe, 0x03, 0x10); + while ((check_cnt++) < 50) { + for (ch = 0; ch < 4; ch++) { + ch_vfc[ch] = n6_read_vfc(ViPipe, ch); + if (ch_vfc[ch] != 0xff) + syslog(LOG_DEBUG, "ch[%d] video vfc read value0 : %2x\n", ch, ch_vfc[ch]); + } + delay_ms(40); + } + for (ch = 0; ch < 4; ch++) { + n6_write_register(ViPipe, 0xFF, 0x13); + val_13x70 = n6_read_register(ViPipe, 0x70); + val_13x70 |= (0x01< +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "os04a10_cmos_ex.h" +#include "os04a10_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define OS04A10_ID 0x530441 +#define OS04A10_I2C_ADDR_1 0x10 +#define OS04A10_I2C_ADDR_2 0x36 +#define OS04A10_I2C_ADDR_IS_VALID(addr) ((addr) == OS04A10_I2C_ADDR_1 || (addr) == OS04A10_I2C_ADDR_2) +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastOs04a10[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define OS04A10_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastOs04a10[dev]) +#define OS04A10_SENSOR_SET_CTX(dev, pstCtx) (g_pastOs04a10[dev] = pstCtx) +#define OS04A10_SENSOR_RESET_CTX(dev) (g_pastOs04a10[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunOs04a10_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Os04a10_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Os04a10_UseHwSync[VI_MAX_PIPE_NUM] = {0}; + +OS04A10_STATE_S g_astOs04a10_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeOs04a10_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Os04a10 Lines Range*****/ +#define OS04A10_FULL_LINES_MAX (0xFFFF) +#define OS04A10_FULL_LINES_MAX_2TO1_WDR (0xFFFF) + +/*****Os04a10 Register Address*****/ +#define OS04A10_HOLD_3208 0x3208 +#define OS04A10_HOLD_320D 0x320D +#define OS04A10_EXP1_ADDR 0x3501 +#define OS04A10_EXP2_ADDR 0x3541 +#define OS04A10_AGAIN1_ADDR 0x3508 +#define OS04A10_DGAIN1_ADDR 0x350A +#define OS04A10_AGAIN2_ADDR 0x3548 +#define OS04A10_DGAIN2_ADDR 0x354A +#define OS04A10_VTS_ADDR 0x380E +#define OS04A10_TABLE_END 0xffff + +#define OS04A10_RES_IS_1520P(w, h) ((w) == 2688 && (h) == 1520) +#define OS04A10_RES_IS_1440P(w, h) ((w) == 2560 && (h) == 1440) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const OS04A10_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astOs04a10_mode[pstSnsState->u8ImgMode]; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = OS04A10_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + //pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + //pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ + + } + break; + } + CVI_TRACE_SNS(CVI_DBG_INFO, "again[%d, %d], dgain[%d, %d]\n", + pstAeSnsDft->u32MinAgain, pstAeSnsDft->u32MaxAgain, pstAeSnsDft->u32MinDgain, pstAeSnsDft->u32MaxDgain); + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX, l2s_offset, v_start, v_end, isp_res, max_l2s; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astOs04a10_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astOs04a10_mode[pstSnsState->u8ImgMode].f32MinFps; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OS04A10_FULL_LINES_MAX) ? OS04A10_FULL_LINES_MAX : u32VMAX; + + pstSnsRegsInfo->astI2cData[LINEAR_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_1].u32Data = (u32VMAX & 0xFF); + } else { + l2s_offset = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32L2S_offset; + v_start = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32VStart; + v_end = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32VEnd; + isp_res = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32IspResTime; + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OS04A10_FULL_LINES_MAX_2TO1_WDR) ? + OS04A10_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + + /* Short exposure < Long to Short Distance - 1 + * Max L-S Distance = VTS - (Yend + 1 - Ystart) - l2s_offset(40) + */ + max_l2s = u32VMAX - (v_end + 1 - v_start) - l2s_offset; + if (max_l2s > isp_res) + max_l2s -= isp_res; + else + CVI_TRACE_SNS(CVI_DBG_WARN, "cannot reserve 1ms for isp delay %d\n", max_l2s); + + g_astOs04a10_State[ViPipe].u32Sexp_MAX = max_l2s - 4; + pstSnsRegsInfo->astI2cData[WDR2_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_VTS_1].u32Data = (u32VMAX & 0xFF); + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32IntTime[0]; + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = u32IntTime[1]; + + pstSnsRegsInfo->astI2cData[WDR2_EXP1_0].u32Data = ((pstSnsState->au32WDRIntTime[1] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_EXP1_1].u32Data = (pstSnsState->au32WDRIntTime[1] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_EXP2_0].u32Data = ((pstSnsState->au32WDRIntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_EXP2_1].u32Data = (pstSnsState->au32WDRIntTime[0] & 0xFF); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + CVI_U32 u32TmpIntTime = u32IntTime[0]; + CVI_U32 maxExp = pstSnsState->au32FL[0] - 8; + /* linear exposure reg range: + * min : 2 + * max : vts - 8 + * step : 1 + */ + u32TmpIntTime = (u32TmpIntTime > maxExp) ? maxExp : u32TmpIntTime; + u32TmpIntTime = u32TmpIntTime >= 2 ? u32TmpIntTime : 2; + u32IntTime[0] = u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_0].u32Data = ((u32TmpIntTime & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_1].u32Data = (u32TmpIntTime & 0xFF); + } + + return CVI_SUCCESS; + +} + +typedef struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} gain_tbl_info_s; + +static struct gain_tbl_info_s AgainInfo[15] = { + { + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x01, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 2944, + .idxBase = 16, + .regGain = 0x02, + .regGainFineBase = 0x00, + .regGainFineStep = 2, + }, + { + .gainMax = 3968, + .idxBase = 24, + .regGain = 0x03, + .regGainFineBase = 0x00, + .regGainFineStep = 2, + }, + { + .gainMax = 4864, + .idxBase = 32, + .regGain = 0x04, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 5888, + .idxBase = 36, + .regGain = 0x05, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 6912, + .idxBase = 40, + .regGain = 0x06, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 7936, + .idxBase = 44, + .regGain = 0x07, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 8704, + .idxBase = 48, + .regGain = 0x08, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 9728, + .idxBase = 50, + .regGain = 0x09, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 10752, + .idxBase = 52, + .regGain = 0x0a, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 11776, + .idxBase = 54, + .regGain = 0x0b, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 12800, + .idxBase = 56, + .regGain = 0x0c, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 13824, + .idxBase = 58, + .regGain = 0x0d, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 14848, + .idxBase = 60, + .regGain = 0x0e, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 15872, + .idxBase = 62, + .regGain = 0x0f, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, +}; + +static CVI_U32 Again_table[65] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; + +static struct gain_tbl_info_s DgainInfo[15] = { + { + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x01, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 3008, + .idxBase = 16, + .regGain = 0x02, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 5056, + .idxBase = 48, + .regGain = 0x04, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 6080, + .idxBase = 64, + .regGain = 0x05, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 7104, + .idxBase = 80, + .regGain = 0x06, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 8128, + .idxBase = 96, + .regGain = 0x07, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 9152, + .idxBase = 112, + .regGain = 0x08, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 10176, + .idxBase = 128, + .regGain = 0x09, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 11200, + .idxBase = 144, + .regGain = 0x0a, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 12224, + .idxBase = 160, + .regGain = 0x0b, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 13248, + .idxBase = 176, + .regGain = 0x0c, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 14272, + .idxBase = 192, + .regGain = 0x0d, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 15296, + .idxBase = 208, + .regGain = 0x0e, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 16320, + .idxBase = 224, + .regGain = 0x0f, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, +}; + +static CVI_U32 Dgain_table[240] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, 1856, 1920, + 1984, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, + 2944, 3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, + 3904, 3968, 4032, 4096, 4160, 4224, 4288, 4352, 4416, 4480, 4544, 4608, 4672, 4736, 4800, + 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, 5504, 5568, 5632, 5696, 5760, + 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, 6464, 6528, 6592, 6656, 6720, + 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, 7424, 7488, 7552, 7616, 7680, + 7744, 7808, 7872, 7936, 8000, 8064, 8128, 8192, 8256, 8320, 8384, 8448, 8512, 8576, 8640, + 8704, 8768, 8832, 8896, 8960, 9024, 9088, 9152, 9216, 9280, 9344, 9408, 9472, 9536, 9600, + 9664, 9728, 9792, 9856, 9920, 9984, 10048, 10112, 10176, 10240, 10304, 10368, 10432, 10496, + 10560, 10624, 10688, 10752, 10816, 10880, 10944, 11008, 11072, 11136, 11200, 11264, 11328, + 11392, 11456, 11520, 11584, 11648, 11712, 11776, 11840, 11904, 11968, 12032, 12096, 12160, + 12224, 12288, 12352, 12416, 12480, 12544, 12608, 12672, 12736, 12800, 12864, 12928, 12992, + 13056, 13120, 13184, 13248, 13312, 13376, 13440, 13504, 13568, 13632, 13696, 13760, 13824, + 13888, 13952, 14016, 14080, 14144, 14208, 14272, 14336, 14400, 14464, 14528, 14592, 14656, + 14720, 14784, 14848, 14912, 14976, 15040, 15104, 15168, 15232, 15296, 15360, 15424, 15488, + 15552, 15616, 15680, 15744, 15808, 15872, 15936, 16000, 16064, 16128, 16192, 16256, 16320 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[63]) { + *pu32AgainLin = Again_table[63]; + *pu32AgainDb = 63; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[239]) { + *pu32DgainLin = Dgain_table[239]; + *pu32DgainDb = 239; + return CVI_SUCCESS; + } + + for (i = 1; i < 240; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_1].u32Data = (u32Again & 0xFF) << 4; + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1].u32Data = (u32Dgain & 0xFF) << 4; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_2].u32Data = 0x00; + } else { + /* DOL mode */ + if (g_au16Os04a10_GainMode[ViPipe] == SNS_GAIN_MODE_WDR_2F) { + //sef gain + /* find SEF Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_0].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_1].u32Data = (u32Again & 0xFF) << 4; + + /* find SEF Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_0].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_1].u32Data = (u32Dgain & 0xFF) << 4; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_2].u32Data = 0x00; + + u32Again = pu32Again[1]; //lef gain + u32Dgain = pu32Dgain[1]; + /* find LEF Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_0].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_1].u32Data = (u32Again & 0xFF) << 4; + + /* find LEF Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_0].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_1].u32Data = (u32Dgain & 0xFF) << 4; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_2].u32Data = 0x00; + } else if (g_au16Os04a10_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_0].u32Data = (info->regGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_0].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_1].u32Data = (u32Again & 0xFF) << 4; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_1].u32Data = (u32Again & 0xFF) << 4; + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_0].u32Data = (info->regGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_0].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_1].u32Data = (u32Dgain & 0xFF) << 4; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_1].u32Data = (u32Dgain & 0xFF) << 4; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_2].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_2].u32Data = 0x00; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = 2; + /* + * Long exp + Short exp < VTS - 8 + */ + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 8 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 8) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + + u32IntTimeMaxTmp = (g_astOs04a10_State[ViPipe].u32Sexp_MAX < u32IntTimeMaxTmp) ? + g_astOs04a10_State[ViPipe].u32Sexp_MAX : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? u32ShortTimeMinLimit : u32IntTimeMaxTmp; + syslog(LOG_DEBUG, "Max inttime0 = %u\n", u32IntTimeMaxTmp); + + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio is too large!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + CVI_TRACE_SNS(CVI_DBG_DEBUG, "sexp[%d, %d], lexp[%d, %d], ratio:%d, max_sexp:%d\n", + au32IntTimeMin[0], au32IntTimeMax[0], au32IntTimeMin[1], au32IntTimeMax[1], + au32Ratio[0], g_astOs04a10_State[ViPipe].u32Sexp_MAX); + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + else + memcpy(pstBlc, + &g_stIspBlcCalibratio10Bit, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const OS04A10_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astOs04a10_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == OS04A10_MODE_1440P30_WDR) + pstSnsState->u8ImgMode = OS04A10_MODE_1440P30_12BIT; + + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == OS04A10_MODE_1440P30_12BIT) { + pstSnsState->u8ImgMode = OS04A10_MODE_1440P30_WDR; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1440p mode(60fps->30fps)\n"); + } + + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32VtsDef; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunOs04a10_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = os04a10_i2c_addr; + pstI2c_data[i].u32AddrByteNum = os04a10_addr_byte; + pstI2c_data[i].u32DataByteNum = os04a10_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[WDR2_HOLD_START].u32RegAddr = OS04A10_HOLD_3208; + pstI2c_data[WDR2_HOLD_START].u32Data = 0x00; + pstI2c_data[WDR2_EXP1_0].u32RegAddr = OS04A10_EXP1_ADDR; + pstI2c_data[WDR2_EXP1_1].u32RegAddr = OS04A10_EXP1_ADDR + 1; + pstI2c_data[WDR2_EXP2_0].u32RegAddr = OS04A10_EXP2_ADDR; + pstI2c_data[WDR2_EXP2_1].u32RegAddr = OS04A10_EXP2_ADDR + 1; + pstI2c_data[WDR2_AGAIN1_0].u32RegAddr = OS04A10_AGAIN1_ADDR; + pstI2c_data[WDR2_AGAIN1_1].u32RegAddr = OS04A10_AGAIN1_ADDR + 1; + pstI2c_data[WDR2_AGAIN2_0].u32RegAddr = OS04A10_AGAIN2_ADDR; + pstI2c_data[WDR2_AGAIN2_1].u32RegAddr = OS04A10_AGAIN2_ADDR + 1; + pstI2c_data[WDR2_DGAIN1_0].u32RegAddr = OS04A10_DGAIN1_ADDR; + pstI2c_data[WDR2_DGAIN1_1].u32RegAddr = OS04A10_DGAIN1_ADDR + 1; + pstI2c_data[WDR2_DGAIN2_0].u32RegAddr = OS04A10_DGAIN2_ADDR; + pstI2c_data[WDR2_DGAIN2_1].u32RegAddr = OS04A10_DGAIN2_ADDR + 1; + pstI2c_data[WDR2_VTS_0].u32RegAddr = OS04A10_VTS_ADDR; + pstI2c_data[WDR2_VTS_1].u32RegAddr = OS04A10_VTS_ADDR + 1; + pstI2c_data[WDR2_HOLD_END].u32RegAddr = OS04A10_HOLD_3208; + pstI2c_data[WDR2_HOLD_END].u32Data = 0x10; + pstI2c_data[WDR2_LAUNCH_0].u32RegAddr = OS04A10_HOLD_320D; + pstI2c_data[WDR2_LAUNCH_0].u32Data = 0x00; + pstI2c_data[WDR2_LAUNCH_0].u8DelayFrmNum = 0; + pstI2c_data[WDR2_LAUNCH_1].u32RegAddr = OS04A10_HOLD_3208; + pstI2c_data[WDR2_LAUNCH_1].u32Data = 0xA0; + pstI2c_data[WDR2_LAUNCH_1].u8DelayFrmNum = 0; + break; + default: + pstI2c_data[LINEAR_HOLD_START].u32RegAddr = OS04A10_HOLD_3208; + pstI2c_data[LINEAR_HOLD_START].u32Data = 0x00; + pstI2c_data[LINEAR_EXP_0].u32RegAddr = OS04A10_EXP1_ADDR; + pstI2c_data[LINEAR_EXP_1].u32RegAddr = OS04A10_EXP1_ADDR + 1; + pstI2c_data[LINEAR_AGAIN_0].u32RegAddr = OS04A10_AGAIN1_ADDR; + pstI2c_data[LINEAR_AGAIN_1].u32RegAddr = OS04A10_AGAIN1_ADDR + 1; + pstI2c_data[LINEAR_DGAIN_0].u32RegAddr = OS04A10_DGAIN1_ADDR; + pstI2c_data[LINEAR_DGAIN_1].u32RegAddr = OS04A10_DGAIN1_ADDR + 1; + pstI2c_data[LINEAR_DGAIN_2].u32RegAddr = OS04A10_DGAIN1_ADDR + 2; + pstI2c_data[LINEAR_VTS_0].u32RegAddr = OS04A10_VTS_ADDR; + pstI2c_data[LINEAR_VTS_1].u32RegAddr = OS04A10_VTS_ADDR + 1; + pstI2c_data[LINEAR_HOLD_END].u32RegAddr = OS04A10_HOLD_3208; + pstI2c_data[LINEAR_HOLD_END].u32Data = 0x10; + pstI2c_data[LINEAR_LAUNCH_0].u32RegAddr = OS04A10_HOLD_320D; + pstI2c_data[LINEAR_LAUNCH_0].u32Data = 0x00; + pstI2c_data[LINEAR_LAUNCH_0].u8DelayFrmNum = 0; + pstI2c_data[LINEAR_LAUNCH_1].u32RegAddr = OS04A10_HOLD_3208; + pstI2c_data[LINEAR_LAUNCH_1].u32Data = 0xA0; + pstI2c_data[LINEAR_LAUNCH_1].u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[WDR2_HOLD_START].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_HOLD_END].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_LAUNCH_0].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_LAUNCH_1].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD_START].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_HOLD_END].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_LAUNCH_0].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_LAUNCH_1].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (OS04A10_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = OS04A10_MODE_1440P30_12BIT; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (OS04A10_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = OS04A10_MODE_1440P30_WDR; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeOs04a10_MirrorFip[ViPipe] != eSnsMirrorFlip) { + os04a10_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeOs04a10_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = OS04A10_MODE_1440P30_12BIT; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &os04a10_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astOs04a10_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astOs04a10_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } else { + pstRxAttr->mac_clk = RX_MAC_CLK_400M; + pstRxAttr->mipi_attr.raw_data_type = RAW_DATA_10BIT; + pstRxAttr->mclk.freq = CAMPLL_FREQ_24M; + } + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &os04a10_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = os04a10_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = os04a10_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (OS04A10_I2C_ADDR_IS_VALID(s32I2cAddr)) + os04a10_i2c_addr = s32I2cAddr; +} + +static CVI_S32 os04a10_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunOs04a10_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + OS04A10_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + OS04A10_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = OS04A10_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, OS04A10_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, OS04A10_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, OS04A10_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Os04a10_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Os04a10_UseHwSync[ViPipe] = pstInitAttr->u16UseHwSync; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsOs04a10_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = os04a10_standby, + .pfnRestart = os04a10_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = os04a10_write_register, + .pfnReadReg = os04a10_read_register, + .pfnSetBusInfo = os04a10_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_os04a10/os04a10_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/ov_os04a10/os04a10_cmos_ex.h new file mode 100644 index 000000000..5fb642510 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_os04a10/os04a10_cmos_ex.h @@ -0,0 +1,117 @@ +#ifndef __OS04A10_CMOS_EX_H_ +#define __OS04A10_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum os04a10_linear_regs_e { + LINEAR_HOLD_START = 0, + LINEAR_EXP_0, + LINEAR_EXP_1, + LINEAR_AGAIN_0, + LINEAR_AGAIN_1, + LINEAR_DGAIN_0, + LINEAR_DGAIN_1, + LINEAR_DGAIN_2, + LINEAR_VTS_0, + LINEAR_VTS_1, + LINEAR_HOLD_END, + LINEAR_LAUNCH_0, + LINEAR_LAUNCH_1, + LINEAR_REGS_NUM +}; + +enum os04a10_wdr2_regs_e { + WDR2_HOLD_START = 0, + WDR2_EXP1_0, + WDR2_EXP1_1, + WDR2_EXP2_0, + WDR2_EXP2_1, + WDR2_AGAIN1_0, + WDR2_AGAIN1_1, + WDR2_AGAIN2_0, + WDR2_AGAIN2_1, + WDR2_DGAIN1_0, + WDR2_DGAIN1_1, + WDR2_DGAIN1_2, + WDR2_DGAIN2_0, + WDR2_DGAIN2_1, + WDR2_DGAIN2_2, + WDR2_VTS_0, + WDR2_VTS_1, + WDR2_HOLD_END, + WDR2_LAUNCH_0, + WDR2_LAUNCH_1, + WDR2_REGS_NUM +}; + +typedef enum _OS04A10_MODE_E { + OS04A10_MODE_1440P30_12BIT = 0, + OS04A10_MODE_LINEAR_NUM, + OS04A10_MODE_1440P30_WDR = OS04A10_MODE_LINEAR_NUM, + OS04A10_MODE_NUM +} OS04A10_MODE_E; + +typedef struct _OS04A10_STATE_S { + CVI_U32 u32Sexp_MAX; +} OS04A10_STATE_S; + +typedef struct _OS04A10_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; + CVI_U32 u32L2S_offset; + CVI_U32 u32IspResTime; + CVI_U32 u32VStart; + CVI_U32 u32VEnd; +} OS04A10_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastOs04a10[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunOs04a10_BusInfo[]; +extern CVI_U16 g_au16Os04a10_GainMode[]; +extern CVI_U16 g_au16Os04a10_UseHwSync[VI_MAX_PIPE_NUM]; +extern CVI_U8 os04a10_i2c_addr; +extern const CVI_U32 os04a10_addr_byte; +extern const CVI_U32 os04a10_data_byte; +extern void os04a10_init(VI_PIPE ViPipe); +extern void os04a10_exit(VI_PIPE ViPipe); +extern void os04a10_standby(VI_PIPE ViPipe); +extern void os04a10_restart(VI_PIPE ViPipe); +extern void os04a10_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int os04a10_write_register(VI_PIPE ViPipe, int addr, int data); +extern int os04a10_read_register(VI_PIPE ViPipe, int addr); +extern int os04a10_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OS04A10_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_os04a10/os04a10_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/ov_os04a10/os04a10_cmos_param.h new file mode 100644 index 000000000..6cdd6294e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_os04a10/os04a10_cmos_param.h @@ -0,0 +1,237 @@ +#ifndef __OS04A10_CMOS_PARAM_H_ +#define __OS04A10_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "os04a10_cmos_ex.h" + +static const OS04A10_MODE_S g_astOs04a10_mode[OS04A10_MODE_NUM] = { + [OS04A10_MODE_1440P30_12BIT] = { + .name = "1440p30_12bit", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + .stWndRect = { + .s32X = 64, + .s32Y = 40, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.74, /* 0x658 * 30 / 0xFFFF */ + .u32HtsDef = 2688, + .u32VtsDef = 1624, + .stExp[0] = { + .u16Min = 2, + .u16Max = 1624 - 8, + .u16Def = 500, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16373, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [OS04A10_MODE_1440P30_WDR] = { + .name = "1440p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + .stWndRect = { + .s32X = 64, + .s32Y = 40, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + .stWndRect = { + .s32X = 64, + .s32Y = 40, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.74, /* 1624 * 30 / 0xFFFF */ + .u32HtsDef = 2972, + .u32VtsDef = 1624, + .u32L2S_offset = 40, + .u32IspResTime = 49, /* ceil((u32Vts * f32MaxFps) / 1000); about 1ms*/ + .u32VStart = 0, + .u32VEnd = 0x5ff, + .stExp[0] = { + .u16Min = 8, + .u16Max = 88, + .u16Def = 88, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 8, + .u16Max = 0x486 - 4 - 88, + .u16Def = 500, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16373, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 16373, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {128, 128, 128, 128, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1057, 1057, 1057, 1057 +#endif + }, + .stAuto = { + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, +#endif + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio10Bit = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, +#endif + }, + }, +}; + +struct combo_dev_attr_s os04a10_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_500M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {0, 1, 2, 3, 4}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + .dphy = { + .enable = 1, + .hs_settle = 8, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_25M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OS04A10_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_os04a10/os04a10_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/ov_os04a10/os04a10_sensor_ctl.c new file mode 100644 index 000000000..435483b32 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_os04a10/os04a10_sensor_ctl.c @@ -0,0 +1,893 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "os04a10_cmos_ex.h" + +static void os04a10_wdr_1520p30_2to1_init(VI_PIPE ViPipe); +static void os04a10_linear_1520p30_12BIT_init(VI_PIPE ViPipe); + +CVI_U8 os04a10_i2c_addr = 0x36; /* I2C Address of OS04A10 */ +const CVI_U32 os04a10_addr_byte = 2; +const CVI_U32 os04a10_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeOs04a10_MirrorFip_Initial[VI_MAX_PIPE_NUM] = { + ISP_SNS_MIRROR, ISP_SNS_MIRROR, ISP_SNS_MIRROR, ISP_SNS_MIRROR}; + +int os04a10_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunOs04a10_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, os04a10_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + return CVI_SUCCESS; +} + +int os04a10_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int os04a10_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (os04a10_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, os04a10_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, os04a10_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (os04a10_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int os04a10_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (os04a10_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (os04a10_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, os04a10_addr_byte + os04a10_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} +/* + *static void delay_ms(int ms) + *{ + * usleep(ms * 1000); + *} + */ +void os04a10_standby(VI_PIPE ViPipe) +{ + os04a10_write_register(ViPipe, 0x0100, 0x00); /* STANDBY */ +} + +void os04a10_restart(VI_PIPE ViPipe) +{ + os04a10_write_register(ViPipe, 0x0100, 0x01); /* resume */ +} + +void os04a10_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + CVI_U32 start = 1; + CVI_U32 end = g_pastOs04a10[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum - 3; + + for (i = start; i < end; i++) { + os04a10_write_register(ViPipe, + g_pastOs04a10[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastOs04a10[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + CVI_TRACE_SNS(CVI_DBG_INFO, "i2c_addr:%#x, i2c_data:%#x\n", + g_pastOs04a10[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastOs04a10[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +ISP_SNS_MIRRORFLIP_TYPE_E aeSnsMirrorFlipMap[ISP_SNS_BUTT][ISP_SNS_BUTT] = { + {ISP_SNS_NORMAL, ISP_SNS_MIRROR, ISP_SNS_FLIP, ISP_SNS_MIRROR_FLIP}, + {ISP_SNS_MIRROR, ISP_SNS_NORMAL, ISP_SNS_MIRROR_FLIP, ISP_SNS_FLIP}, + {ISP_SNS_FLIP, ISP_SNS_MIRROR_FLIP, ISP_SNS_NORMAL, ISP_SNS_MIRROR}, + {ISP_SNS_MIRROR_FLIP, ISP_SNS_FLIP, ISP_SNS_MIRROR, ISP_SNS_NORMAL} +}; + +#define OS04A10_ORIEN_ADDR (0x3820) +void os04a10_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + CVI_U32 i = 0; + + for (i = 0; i < ISP_SNS_BUTT; i++) { + if (g_aeOs04a10_MirrorFip_Initial[ViPipe] == aeSnsMirrorFlipMap[i][0]) { + eSnsMirrorFlip = aeSnsMirrorFlipMap[i][eSnsMirrorFlip]; + break; + } + } + + val = os04a10_read_register(ViPipe, OS04A10_ORIEN_ADDR); + val &= ~(0x3 << 1); + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x1<<1; + break; + case ISP_SNS_FLIP: + val |= 0x1<<2; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x1<<1; + val |= 0x1<<2; + break; + default: + return; + } + + os04a10_standby(ViPipe); + os04a10_write_register(ViPipe, OS04A10_ORIEN_ADDR, val); + usleep(1000*100); + os04a10_restart(ViPipe); +} + +#define OS04A10_CHIP_ID_ADDR_H 0x300A +#define OS04A10_CHIP_ID_ADDR_M 0x300B +#define OS04A10_CHIP_ID_ADDR_L 0x300C +#define OS04A10_CHIP_ID 0x530441 + +int os04a10_probe(VI_PIPE ViPipe) +{ + int nVal, nVal2, nVal3; + + usleep(500); + if (os04a10_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = os04a10_read_register(ViPipe, OS04A10_CHIP_ID_ADDR_H); + nVal2 = os04a10_read_register(ViPipe, OS04A10_CHIP_ID_ADDR_M); + nVal3 = os04a10_read_register(ViPipe, OS04A10_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0 || nVal3 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 16) | ((nVal2 & 0xFF) << 8) | (nVal3 & 0xFF)) != OS04A10_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void os04a10_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastOs04a10[ViPipe]->enWDRMode; + u8ImgMode = g_pastOs04a10[ViPipe]->u8ImgMode; + + os04a10_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == OS04A10_MODE_1440P30_WDR) + os04a10_wdr_1520p30_2to1_init(ViPipe); + } else { + if (u8ImgMode == OS04A10_MODE_1440P30_12BIT) + os04a10_linear_1520p30_12BIT_init(ViPipe); + } + g_pastOs04a10[ViPipe]->bInit = CVI_TRUE; +} + +void os04a10_exit(VI_PIPE ViPipe) +{ + os04a10_i2c_exit(ViPipe); +} + +static void os04a10_linear_1520p30_12BIT_init(VI_PIPE ViPipe) +{ + os04a10_write_register(ViPipe, 0x0103, 0x01); + os04a10_write_register(ViPipe, 0x0109, 0x01); + os04a10_write_register(ViPipe, 0x0104, 0x02); + os04a10_write_register(ViPipe, 0x0102, 0x00); + os04a10_write_register(ViPipe, 0x0305, 0x40); + os04a10_write_register(ViPipe, 0x0306, 0x00); + os04a10_write_register(ViPipe, 0x0307, 0x00); + os04a10_write_register(ViPipe, 0x0308, 0x05); + os04a10_write_register(ViPipe, 0x030a, 0x01); + os04a10_write_register(ViPipe, 0x0317, 0x0a); + os04a10_write_register(ViPipe, 0x0322, 0x01); + os04a10_write_register(ViPipe, 0x0323, 0x02); + os04a10_write_register(ViPipe, 0x0324, 0x00); + os04a10_write_register(ViPipe, 0x0325, 0x8b); + os04a10_write_register(ViPipe, 0x0327, 0x05); + os04a10_write_register(ViPipe, 0x0329, 0x02); + os04a10_write_register(ViPipe, 0x032c, 0x02); + os04a10_write_register(ViPipe, 0x032d, 0x02); + os04a10_write_register(ViPipe, 0x032e, 0x02); + os04a10_write_register(ViPipe, 0x300f, 0x11); + os04a10_write_register(ViPipe, 0x3012, 0x41); + os04a10_write_register(ViPipe, 0x3026, 0x10); + os04a10_write_register(ViPipe, 0x3027, 0x08); + os04a10_write_register(ViPipe, 0x302d, 0x24); + os04a10_write_register(ViPipe, 0x3104, 0x01); + os04a10_write_register(ViPipe, 0x3106, 0x11); + os04a10_write_register(ViPipe, 0x3400, 0x00); + os04a10_write_register(ViPipe, 0x3408, 0x05); + os04a10_write_register(ViPipe, 0x340c, 0x0c); + os04a10_write_register(ViPipe, 0x340d, 0xb0); + os04a10_write_register(ViPipe, 0x3425, 0x51); + os04a10_write_register(ViPipe, 0x3426, 0x10); + os04a10_write_register(ViPipe, 0x3427, 0x14); + os04a10_write_register(ViPipe, 0x3428, 0x10); + os04a10_write_register(ViPipe, 0x3429, 0x10); + os04a10_write_register(ViPipe, 0x342a, 0x10); + os04a10_write_register(ViPipe, 0x342b, 0x04); + os04a10_write_register(ViPipe, 0x3501, 0x02); + os04a10_write_register(ViPipe, 0x3504, 0x08); + os04a10_write_register(ViPipe, 0x3508, 0x01); + os04a10_write_register(ViPipe, 0x3509, 0x00); + os04a10_write_register(ViPipe, 0x350a, 0x01); + os04a10_write_register(ViPipe, 0x3544, 0x08); + os04a10_write_register(ViPipe, 0x3548, 0x01); + os04a10_write_register(ViPipe, 0x3549, 0x00); + os04a10_write_register(ViPipe, 0x3584, 0x08); + os04a10_write_register(ViPipe, 0x3588, 0x01); + os04a10_write_register(ViPipe, 0x3589, 0x00); + os04a10_write_register(ViPipe, 0x3601, 0x70); + os04a10_write_register(ViPipe, 0x3604, 0xe3); + os04a10_write_register(ViPipe, 0x3605, 0xff); + os04a10_write_register(ViPipe, 0x3606, 0x01); + os04a10_write_register(ViPipe, 0x3608, 0xa8); + os04a10_write_register(ViPipe, 0x360a, 0xd0); + os04a10_write_register(ViPipe, 0x360b, 0x08); + os04a10_write_register(ViPipe, 0x360e, 0xc8); + os04a10_write_register(ViPipe, 0x360f, 0x66); + os04a10_write_register(ViPipe, 0x3610, 0x89); + os04a10_write_register(ViPipe, 0x3611, 0x8a); + os04a10_write_register(ViPipe, 0x3612, 0x4e); + os04a10_write_register(ViPipe, 0x3613, 0xbd); + os04a10_write_register(ViPipe, 0x3614, 0x9b); + os04a10_write_register(ViPipe, 0x362a, 0x0e); + os04a10_write_register(ViPipe, 0x362b, 0x0e); + os04a10_write_register(ViPipe, 0x362c, 0x0e); + os04a10_write_register(ViPipe, 0x362d, 0x09); + os04a10_write_register(ViPipe, 0x362e, 0x1a); + os04a10_write_register(ViPipe, 0x362f, 0x34); + os04a10_write_register(ViPipe, 0x3630, 0x67); + os04a10_write_register(ViPipe, 0x3631, 0x7f); + os04a10_write_register(ViPipe, 0x3638, 0x00); + os04a10_write_register(ViPipe, 0x3643, 0x00); + os04a10_write_register(ViPipe, 0x3644, 0x00); + os04a10_write_register(ViPipe, 0x3645, 0x00); + os04a10_write_register(ViPipe, 0x3646, 0x00); + os04a10_write_register(ViPipe, 0x3647, 0x00); + os04a10_write_register(ViPipe, 0x3648, 0x00); + os04a10_write_register(ViPipe, 0x3649, 0x00); + os04a10_write_register(ViPipe, 0x364a, 0x04); + os04a10_write_register(ViPipe, 0x364c, 0x0e); + os04a10_write_register(ViPipe, 0x364d, 0x0e); + os04a10_write_register(ViPipe, 0x364e, 0x0e); + os04a10_write_register(ViPipe, 0x364f, 0x0e); + os04a10_write_register(ViPipe, 0x3650, 0xff); + os04a10_write_register(ViPipe, 0x3651, 0xff); + os04a10_write_register(ViPipe, 0x365a, 0x00); + os04a10_write_register(ViPipe, 0x365b, 0x00); + os04a10_write_register(ViPipe, 0x365c, 0x00); + os04a10_write_register(ViPipe, 0x365d, 0x00); + os04a10_write_register(ViPipe, 0x3661, 0x07); + os04a10_write_register(ViPipe, 0x3662, 0x00); + os04a10_write_register(ViPipe, 0x3663, 0x20); + os04a10_write_register(ViPipe, 0x3665, 0x12); + os04a10_write_register(ViPipe, 0x3667, 0xd4); + os04a10_write_register(ViPipe, 0x3668, 0x80); + os04a10_write_register(ViPipe, 0x366c, 0x00); + os04a10_write_register(ViPipe, 0x366d, 0x00); + os04a10_write_register(ViPipe, 0x366e, 0x00); + os04a10_write_register(ViPipe, 0x366f, 0x00); + os04a10_write_register(ViPipe, 0x3671, 0x08); + os04a10_write_register(ViPipe, 0x3673, 0x2a); + os04a10_write_register(ViPipe, 0x3681, 0x80); + os04a10_write_register(ViPipe, 0x3700, 0x2d); + os04a10_write_register(ViPipe, 0x3701, 0x22); + os04a10_write_register(ViPipe, 0x3702, 0x25); + os04a10_write_register(ViPipe, 0x3703, 0x28); + os04a10_write_register(ViPipe, 0x3705, 0x00); + os04a10_write_register(ViPipe, 0x3706, 0xf0); + os04a10_write_register(ViPipe, 0x3707, 0x0a); + os04a10_write_register(ViPipe, 0x3708, 0x36); + os04a10_write_register(ViPipe, 0x3709, 0x57); + os04a10_write_register(ViPipe, 0x370a, 0x03); + os04a10_write_register(ViPipe, 0x370b, 0x15); + os04a10_write_register(ViPipe, 0x3714, 0x01); + os04a10_write_register(ViPipe, 0x3719, 0x24); + os04a10_write_register(ViPipe, 0x371b, 0x1f); + os04a10_write_register(ViPipe, 0x371c, 0x00); + os04a10_write_register(ViPipe, 0x371d, 0x08); + os04a10_write_register(ViPipe, 0x373f, 0x63); + os04a10_write_register(ViPipe, 0x3740, 0x63); + os04a10_write_register(ViPipe, 0x3741, 0x63); + os04a10_write_register(ViPipe, 0x3742, 0x63); + os04a10_write_register(ViPipe, 0x3743, 0x01); + os04a10_write_register(ViPipe, 0x3756, 0xe7); + os04a10_write_register(ViPipe, 0x3757, 0xe7); + os04a10_write_register(ViPipe, 0x3762, 0x1c); + os04a10_write_register(ViPipe, 0x376c, 0x10); + os04a10_write_register(ViPipe, 0x3776, 0x05); + os04a10_write_register(ViPipe, 0x3777, 0x22); + os04a10_write_register(ViPipe, 0x3779, 0x60); + os04a10_write_register(ViPipe, 0x377c, 0x48); + os04a10_write_register(ViPipe, 0x3784, 0x06); + os04a10_write_register(ViPipe, 0x3785, 0x0a); + os04a10_write_register(ViPipe, 0x3790, 0x10); + os04a10_write_register(ViPipe, 0x3793, 0x04); + os04a10_write_register(ViPipe, 0x3794, 0x07); + os04a10_write_register(ViPipe, 0x3796, 0x00); + os04a10_write_register(ViPipe, 0x3797, 0x02); + os04a10_write_register(ViPipe, 0x379c, 0x4d); + os04a10_write_register(ViPipe, 0x37a1, 0x80); + os04a10_write_register(ViPipe, 0x37bb, 0x88); + os04a10_write_register(ViPipe, 0x37be, 0x48); + os04a10_write_register(ViPipe, 0x37bf, 0x01); + os04a10_write_register(ViPipe, 0x37c0, 0x01); + os04a10_write_register(ViPipe, 0x37c4, 0x72); + os04a10_write_register(ViPipe, 0x37c5, 0x72); + os04a10_write_register(ViPipe, 0x37c6, 0x72); + os04a10_write_register(ViPipe, 0x37ca, 0x21); + os04a10_write_register(ViPipe, 0x37cc, 0x15); + os04a10_write_register(ViPipe, 0x37cd, 0x90); + os04a10_write_register(ViPipe, 0x37cf, 0x02); + os04a10_write_register(ViPipe, 0x37d0, 0x00); + os04a10_write_register(ViPipe, 0x37d1, 0xf0); + os04a10_write_register(ViPipe, 0x37d2, 0x03); + os04a10_write_register(ViPipe, 0x37d3, 0x15); + os04a10_write_register(ViPipe, 0x37d4, 0x01); + os04a10_write_register(ViPipe, 0x37d5, 0x00); + os04a10_write_register(ViPipe, 0x37d6, 0x03); + os04a10_write_register(ViPipe, 0x37d7, 0x15); + os04a10_write_register(ViPipe, 0x37d8, 0x01); + os04a10_write_register(ViPipe, 0x37dc, 0x00); + os04a10_write_register(ViPipe, 0x37dd, 0x00); + os04a10_write_register(ViPipe, 0x37da, 0x00); + os04a10_write_register(ViPipe, 0x37db, 0x00); + os04a10_write_register(ViPipe, 0x3800, 0x00); + os04a10_write_register(ViPipe, 0x3801, 0x00); + os04a10_write_register(ViPipe, 0x3802, 0x00); + os04a10_write_register(ViPipe, 0x3803, 0x00); + os04a10_write_register(ViPipe, 0x3804, 0x0a); + os04a10_write_register(ViPipe, 0x3805, 0x8f); + os04a10_write_register(ViPipe, 0x3806, 0x05); + os04a10_write_register(ViPipe, 0x3807, 0xff); + os04a10_write_register(ViPipe, 0x3808, 0x0a); + os04a10_write_register(ViPipe, 0x3809, 0x80); + os04a10_write_register(ViPipe, 0x380a, 0x05); + os04a10_write_register(ViPipe, 0x380b, 0xf0); + os04a10_write_register(ViPipe, 0x380c, 0x05); + os04a10_write_register(ViPipe, 0x380d, 0xcc); + os04a10_write_register(ViPipe, 0x380e, 0x06); + os04a10_write_register(ViPipe, 0x380f, 0x58); + os04a10_write_register(ViPipe, 0x3811, 0x08); + os04a10_write_register(ViPipe, 0x3813, 0x08); + os04a10_write_register(ViPipe, 0x3814, 0x01); + os04a10_write_register(ViPipe, 0x3815, 0x01); + os04a10_write_register(ViPipe, 0x3816, 0x01); + os04a10_write_register(ViPipe, 0x3817, 0x01); + os04a10_write_register(ViPipe, 0x381c, 0x00); + os04a10_write_register(ViPipe, 0x3820, 0x02); + os04a10_write_register(ViPipe, 0x3821, 0x00); + os04a10_write_register(ViPipe, 0x3822, 0x14); + os04a10_write_register(ViPipe, 0x3823, 0x18); + os04a10_write_register(ViPipe, 0x3826, 0x00); + os04a10_write_register(ViPipe, 0x3827, 0x00); + os04a10_write_register(ViPipe, 0x3833, 0x40); + os04a10_write_register(ViPipe, 0x384c, 0x05); + os04a10_write_register(ViPipe, 0x384d, 0xc4); + os04a10_write_register(ViPipe, 0x3858, 0x3c); + os04a10_write_register(ViPipe, 0x3865, 0x02); + os04a10_write_register(ViPipe, 0x3866, 0x00); + os04a10_write_register(ViPipe, 0x3867, 0x00); + os04a10_write_register(ViPipe, 0x3868, 0x02); + os04a10_write_register(ViPipe, 0x3900, 0x13); + os04a10_write_register(ViPipe, 0x3940, 0x13); + os04a10_write_register(ViPipe, 0x3980, 0x13); + os04a10_write_register(ViPipe, 0x3c01, 0x11); + os04a10_write_register(ViPipe, 0x3c05, 0x00); + os04a10_write_register(ViPipe, 0x3c0f, 0x1c); + os04a10_write_register(ViPipe, 0x3c12, 0x0d); + os04a10_write_register(ViPipe, 0x3c19, 0x00); + os04a10_write_register(ViPipe, 0x3c21, 0x00); + os04a10_write_register(ViPipe, 0x3c3a, 0x10); + os04a10_write_register(ViPipe, 0x3c3b, 0x18); + os04a10_write_register(ViPipe, 0x3c3d, 0xc6); + os04a10_write_register(ViPipe, 0x3c55, 0x08); + os04a10_write_register(ViPipe, 0x3c5a, 0xe5); + os04a10_write_register(ViPipe, 0x3c5d, 0xcf); + os04a10_write_register(ViPipe, 0x3c5e, 0xcf); + os04a10_write_register(ViPipe, 0x3d8c, 0x70); + os04a10_write_register(ViPipe, 0x3d8d, 0x10); + os04a10_write_register(ViPipe, 0x4000, 0xf9); + os04a10_write_register(ViPipe, 0x4001, 0x2f); + os04a10_write_register(ViPipe, 0x4004, 0x00); + os04a10_write_register(ViPipe, 0x4005, 0x80); + os04a10_write_register(ViPipe, 0x4008, 0x02); + os04a10_write_register(ViPipe, 0x4009, 0x11); + os04a10_write_register(ViPipe, 0x400a, 0x03); + os04a10_write_register(ViPipe, 0x400b, 0x27); + os04a10_write_register(ViPipe, 0x400e, 0x40); + os04a10_write_register(ViPipe, 0x402e, 0x00); + os04a10_write_register(ViPipe, 0x402f, 0x80); + os04a10_write_register(ViPipe, 0x4030, 0x00); + os04a10_write_register(ViPipe, 0x4031, 0x80); + os04a10_write_register(ViPipe, 0x4032, 0x9f); + os04a10_write_register(ViPipe, 0x4033, 0x80); + os04a10_write_register(ViPipe, 0x4050, 0x00); + os04a10_write_register(ViPipe, 0x4051, 0x07); + os04a10_write_register(ViPipe, 0x4011, 0xbb); + os04a10_write_register(ViPipe, 0x410f, 0x01); + os04a10_write_register(ViPipe, 0x4288, 0xcf); + os04a10_write_register(ViPipe, 0x4289, 0x00); + os04a10_write_register(ViPipe, 0x428a, 0x46); + os04a10_write_register(ViPipe, 0x430b, 0xff); + os04a10_write_register(ViPipe, 0x430c, 0xff); + os04a10_write_register(ViPipe, 0x430d, 0x00); + os04a10_write_register(ViPipe, 0x430e, 0x00); + os04a10_write_register(ViPipe, 0x4314, 0x04); + os04a10_write_register(ViPipe, 0x4500, 0x18); + os04a10_write_register(ViPipe, 0x4501, 0x18); + os04a10_write_register(ViPipe, 0x4503, 0x10); + os04a10_write_register(ViPipe, 0x4504, 0x00); + os04a10_write_register(ViPipe, 0x4506, 0x32); + os04a10_write_register(ViPipe, 0x4507, 0x02); + os04a10_write_register(ViPipe, 0x4601, 0x30); + os04a10_write_register(ViPipe, 0x4603, 0x00); + os04a10_write_register(ViPipe, 0x460a, 0x50); + os04a10_write_register(ViPipe, 0x460c, 0x60); + os04a10_write_register(ViPipe, 0x4640, 0x62); + os04a10_write_register(ViPipe, 0x4646, 0xaa); + os04a10_write_register(ViPipe, 0x4647, 0x55); + os04a10_write_register(ViPipe, 0x4648, 0x99); + os04a10_write_register(ViPipe, 0x4649, 0x66); + os04a10_write_register(ViPipe, 0x464d, 0x00); + os04a10_write_register(ViPipe, 0x4654, 0x11); + os04a10_write_register(ViPipe, 0x4655, 0x22); + os04a10_write_register(ViPipe, 0x4800, 0x44); + os04a10_write_register(ViPipe, 0x480e, 0x00); + os04a10_write_register(ViPipe, 0x4810, 0xff); + os04a10_write_register(ViPipe, 0x4811, 0xff); + os04a10_write_register(ViPipe, 0x4813, 0x00); + os04a10_write_register(ViPipe, 0x481f, 0x30); + os04a10_write_register(ViPipe, 0x4837, 0x14); + os04a10_write_register(ViPipe, 0x484b, 0x27); + os04a10_write_register(ViPipe, 0x4d00, 0x4d); + os04a10_write_register(ViPipe, 0x4d01, 0x9d); + os04a10_write_register(ViPipe, 0x4d02, 0xb9); + os04a10_write_register(ViPipe, 0x4d03, 0x2e); + os04a10_write_register(ViPipe, 0x4d04, 0x4a); + os04a10_write_register(ViPipe, 0x4d05, 0x3d); + os04a10_write_register(ViPipe, 0x4d09, 0x4f); + os04a10_write_register(ViPipe, 0x5000, 0x7f); + os04a10_write_register(ViPipe, 0x5001, 0x0d); + os04a10_write_register(ViPipe, 0x5080, 0x00); + os04a10_write_register(ViPipe, 0x50c0, 0x00); + os04a10_write_register(ViPipe, 0x5100, 0x00); + os04a10_write_register(ViPipe, 0x5200, 0x00); + os04a10_write_register(ViPipe, 0x5201, 0x00); + os04a10_write_register(ViPipe, 0x5202, 0x03); + os04a10_write_register(ViPipe, 0x5203, 0xff); + os04a10_write_register(ViPipe, 0x5780, 0x53); + os04a10_write_register(ViPipe, 0x5782, 0x60); + os04a10_write_register(ViPipe, 0x5783, 0xf0); + os04a10_write_register(ViPipe, 0x5786, 0x01); + os04a10_write_register(ViPipe, 0x5788, 0x60); + os04a10_write_register(ViPipe, 0x5789, 0xf0); + os04a10_write_register(ViPipe, 0x5792, 0x11); + os04a10_write_register(ViPipe, 0x5793, 0x33); + os04a10_write_register(ViPipe, 0x5857, 0xff); + os04a10_write_register(ViPipe, 0x5858, 0xff); + os04a10_write_register(ViPipe, 0x5859, 0xff); + os04a10_write_register(ViPipe, 0x58d7, 0xff); + os04a10_write_register(ViPipe, 0x58d8, 0xff); + os04a10_write_register(ViPipe, 0x58d9, 0xff); + + os04a10_default_reg_init(ViPipe); + os04a10_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===OS04A10 1520P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void os04a10_wdr_1520p30_2to1_init(VI_PIPE ViPipe) +{ + os04a10_write_register(ViPipe, 0x0103, 0x01); + os04a10_write_register(ViPipe, 0x0109, 0x01); + os04a10_write_register(ViPipe, 0x0104, 0x02); + os04a10_write_register(ViPipe, 0x0102, 0x00); + os04a10_write_register(ViPipe, 0x0305, 0x3c); + os04a10_write_register(ViPipe, 0x0306, 0x00); + os04a10_write_register(ViPipe, 0x0307, 0x00); + os04a10_write_register(ViPipe, 0x0308, 0x04); + os04a10_write_register(ViPipe, 0x030a, 0x01); + os04a10_write_register(ViPipe, 0x0317, 0x09); + os04a10_write_register(ViPipe, 0x0322, 0x01); + os04a10_write_register(ViPipe, 0x0323, 0x02); + os04a10_write_register(ViPipe, 0x0324, 0x00); + os04a10_write_register(ViPipe, 0x0325, 0x90); + os04a10_write_register(ViPipe, 0x0327, 0x05); + os04a10_write_register(ViPipe, 0x0329, 0x02); + os04a10_write_register(ViPipe, 0x032c, 0x02); + os04a10_write_register(ViPipe, 0x032d, 0x02); + os04a10_write_register(ViPipe, 0x032e, 0x02); + os04a10_write_register(ViPipe, 0x300f, 0x11); + os04a10_write_register(ViPipe, 0x3012, 0x41); + os04a10_write_register(ViPipe, 0x3026, 0x10); + os04a10_write_register(ViPipe, 0x3027, 0x08); + os04a10_write_register(ViPipe, 0x302d, 0x24); + os04a10_write_register(ViPipe, 0x3104, 0x01); + os04a10_write_register(ViPipe, 0x3106, 0x11); + os04a10_write_register(ViPipe, 0x3400, 0x00); + os04a10_write_register(ViPipe, 0x3408, 0x05); + os04a10_write_register(ViPipe, 0x340c, 0x0c); + os04a10_write_register(ViPipe, 0x340d, 0xb0); + os04a10_write_register(ViPipe, 0x3425, 0x51); + os04a10_write_register(ViPipe, 0x3426, 0x10); + os04a10_write_register(ViPipe, 0x3427, 0x14); + os04a10_write_register(ViPipe, 0x3428, 0x10); + os04a10_write_register(ViPipe, 0x3429, 0x10); + os04a10_write_register(ViPipe, 0x342a, 0x10); + os04a10_write_register(ViPipe, 0x342b, 0x04); + os04a10_write_register(ViPipe, 0x3501, 0x02); + os04a10_write_register(ViPipe, 0x3504, 0x08); + os04a10_write_register(ViPipe, 0x3508, 0x01); + os04a10_write_register(ViPipe, 0x3509, 0x00); + os04a10_write_register(ViPipe, 0x350a, 0x01); + os04a10_write_register(ViPipe, 0x3544, 0x08); + os04a10_write_register(ViPipe, 0x3548, 0x01); + os04a10_write_register(ViPipe, 0x3549, 0x00); + os04a10_write_register(ViPipe, 0x3584, 0x08); + os04a10_write_register(ViPipe, 0x3588, 0x01); + os04a10_write_register(ViPipe, 0x3589, 0x00); + os04a10_write_register(ViPipe, 0x3601, 0x70); + os04a10_write_register(ViPipe, 0x3604, 0xe3); + os04a10_write_register(ViPipe, 0x3605, 0x7f); + os04a10_write_register(ViPipe, 0x3606, 0x80); + os04a10_write_register(ViPipe, 0x3608, 0xa8); + os04a10_write_register(ViPipe, 0x360a, 0xd0); + os04a10_write_register(ViPipe, 0x360b, 0x08); + os04a10_write_register(ViPipe, 0x360e, 0xc8); + os04a10_write_register(ViPipe, 0x360f, 0x66); + os04a10_write_register(ViPipe, 0x3610, 0x89); + os04a10_write_register(ViPipe, 0x3611, 0x8a); + os04a10_write_register(ViPipe, 0x3612, 0x4e); + os04a10_write_register(ViPipe, 0x3613, 0xbd); + os04a10_write_register(ViPipe, 0x3614, 0x9b); + os04a10_write_register(ViPipe, 0x362a, 0x0e); + os04a10_write_register(ViPipe, 0x362b, 0x0e); + os04a10_write_register(ViPipe, 0x362c, 0x0e); + os04a10_write_register(ViPipe, 0x362d, 0x0e); + os04a10_write_register(ViPipe, 0x362e, 0x1a); + os04a10_write_register(ViPipe, 0x362f, 0x34); + os04a10_write_register(ViPipe, 0x3630, 0x67); + os04a10_write_register(ViPipe, 0x3631, 0x7f); + os04a10_write_register(ViPipe, 0x3638, 0x00); + os04a10_write_register(ViPipe, 0x3643, 0x00); + os04a10_write_register(ViPipe, 0x3644, 0x00); + os04a10_write_register(ViPipe, 0x3645, 0x00); + os04a10_write_register(ViPipe, 0x3646, 0x00); + os04a10_write_register(ViPipe, 0x3647, 0x00); + os04a10_write_register(ViPipe, 0x3648, 0x00); + os04a10_write_register(ViPipe, 0x3649, 0x00); + os04a10_write_register(ViPipe, 0x364a, 0x04); + os04a10_write_register(ViPipe, 0x364c, 0x0e); + os04a10_write_register(ViPipe, 0x364d, 0x0e); + os04a10_write_register(ViPipe, 0x364e, 0x0e); + os04a10_write_register(ViPipe, 0x364f, 0x0e); + os04a10_write_register(ViPipe, 0x3650, 0xff); + os04a10_write_register(ViPipe, 0x3651, 0xff); + os04a10_write_register(ViPipe, 0x365a, 0x00); + os04a10_write_register(ViPipe, 0x365b, 0x00); + os04a10_write_register(ViPipe, 0x365c, 0x00); + os04a10_write_register(ViPipe, 0x365d, 0x00); + os04a10_write_register(ViPipe, 0x3661, 0x07); + os04a10_write_register(ViPipe, 0x3662, 0x02); + os04a10_write_register(ViPipe, 0x3663, 0x20); + os04a10_write_register(ViPipe, 0x3665, 0x12); + os04a10_write_register(ViPipe, 0x3667, 0x54); + os04a10_write_register(ViPipe, 0x3668, 0x80); + os04a10_write_register(ViPipe, 0x366c, 0x00); + os04a10_write_register(ViPipe, 0x366d, 0x00); + os04a10_write_register(ViPipe, 0x366e, 0x00); + os04a10_write_register(ViPipe, 0x366f, 0x00); + os04a10_write_register(ViPipe, 0x3671, 0x09); + os04a10_write_register(ViPipe, 0x3673, 0x2a); + os04a10_write_register(ViPipe, 0x3681, 0x80); + os04a10_write_register(ViPipe, 0x3700, 0x2d); + os04a10_write_register(ViPipe, 0x3701, 0x22); + os04a10_write_register(ViPipe, 0x3702, 0x25); + os04a10_write_register(ViPipe, 0x3703, 0x20); + os04a10_write_register(ViPipe, 0x3705, 0x00); + os04a10_write_register(ViPipe, 0x3706, 0x72); + os04a10_write_register(ViPipe, 0x3707, 0x0a); + os04a10_write_register(ViPipe, 0x3708, 0x36); + os04a10_write_register(ViPipe, 0x3709, 0x57); + os04a10_write_register(ViPipe, 0x370a, 0x01); + os04a10_write_register(ViPipe, 0x370b, 0x14); + os04a10_write_register(ViPipe, 0x3714, 0x01); + os04a10_write_register(ViPipe, 0x3719, 0x1f); + os04a10_write_register(ViPipe, 0x371b, 0x16); + os04a10_write_register(ViPipe, 0x371c, 0x00); + os04a10_write_register(ViPipe, 0x371d, 0x08); + os04a10_write_register(ViPipe, 0x373f, 0x63); + os04a10_write_register(ViPipe, 0x3740, 0x63); + os04a10_write_register(ViPipe, 0x3741, 0x63); + os04a10_write_register(ViPipe, 0x3742, 0x63); + os04a10_write_register(ViPipe, 0x3743, 0x01); + os04a10_write_register(ViPipe, 0x3756, 0x9d); + os04a10_write_register(ViPipe, 0x3757, 0x9d); + os04a10_write_register(ViPipe, 0x3762, 0x1c); + os04a10_write_register(ViPipe, 0x376c, 0x34); + os04a10_write_register(ViPipe, 0x3776, 0x05); + os04a10_write_register(ViPipe, 0x3777, 0x22); + os04a10_write_register(ViPipe, 0x3779, 0x60); + os04a10_write_register(ViPipe, 0x377c, 0x48); + os04a10_write_register(ViPipe, 0x3784, 0x06); + os04a10_write_register(ViPipe, 0x3785, 0x0a); + os04a10_write_register(ViPipe, 0x3790, 0x10); + os04a10_write_register(ViPipe, 0x3793, 0x04); + os04a10_write_register(ViPipe, 0x3794, 0x07); + os04a10_write_register(ViPipe, 0x3796, 0x00); + os04a10_write_register(ViPipe, 0x3797, 0x02); + os04a10_write_register(ViPipe, 0x379c, 0x4d); + os04a10_write_register(ViPipe, 0x37a1, 0x80); + os04a10_write_register(ViPipe, 0x37bb, 0x88); + os04a10_write_register(ViPipe, 0x37be, 0x48); + os04a10_write_register(ViPipe, 0x37bf, 0x01); + os04a10_write_register(ViPipe, 0x37c0, 0x01); + os04a10_write_register(ViPipe, 0x37c4, 0x72); + os04a10_write_register(ViPipe, 0x37c5, 0x72); + os04a10_write_register(ViPipe, 0x37c6, 0x72); + os04a10_write_register(ViPipe, 0x37ca, 0x21); + os04a10_write_register(ViPipe, 0x37cc, 0x13); + os04a10_write_register(ViPipe, 0x37cd, 0x90); + os04a10_write_register(ViPipe, 0x37cf, 0x02); + os04a10_write_register(ViPipe, 0x37d0, 0x00); + os04a10_write_register(ViPipe, 0x37d1, 0x72); + os04a10_write_register(ViPipe, 0x37d2, 0x01); + os04a10_write_register(ViPipe, 0x37d3, 0x14); + os04a10_write_register(ViPipe, 0x37d4, 0x00); + os04a10_write_register(ViPipe, 0x37d5, 0x6c); + os04a10_write_register(ViPipe, 0x37d6, 0x00); + os04a10_write_register(ViPipe, 0x37d7, 0xf7); + os04a10_write_register(ViPipe, 0x37d8, 0x01); + os04a10_write_register(ViPipe, 0x37dc, 0x00); + os04a10_write_register(ViPipe, 0x37dd, 0x00); + os04a10_write_register(ViPipe, 0x37da, 0x00); + os04a10_write_register(ViPipe, 0x37db, 0x00); + os04a10_write_register(ViPipe, 0x3800, 0x00); + os04a10_write_register(ViPipe, 0x3801, 0x00); + os04a10_write_register(ViPipe, 0x3802, 0x00); + os04a10_write_register(ViPipe, 0x3803, 0x00); + os04a10_write_register(ViPipe, 0x3804, 0x0a); + os04a10_write_register(ViPipe, 0x3805, 0x8f); + os04a10_write_register(ViPipe, 0x3806, 0x05); + os04a10_write_register(ViPipe, 0x3807, 0xff); + os04a10_write_register(ViPipe, 0x3808, 0x0a); + os04a10_write_register(ViPipe, 0x3809, 0x80); + os04a10_write_register(ViPipe, 0x380a, 0x05); + os04a10_write_register(ViPipe, 0x380b, 0xf0); + os04a10_write_register(ViPipe, 0x380c, 0x02); + os04a10_write_register(ViPipe, 0x380d, 0xdc); + os04a10_write_register(ViPipe, 0x380e, 0x06); + os04a10_write_register(ViPipe, 0x380f, 0x58); + os04a10_write_register(ViPipe, 0x3811, 0x08); + os04a10_write_register(ViPipe, 0x3813, 0x08); + os04a10_write_register(ViPipe, 0x3814, 0x01); + os04a10_write_register(ViPipe, 0x3815, 0x01); + os04a10_write_register(ViPipe, 0x3816, 0x01); + os04a10_write_register(ViPipe, 0x3817, 0x01); + os04a10_write_register(ViPipe, 0x381c, 0x08); + os04a10_write_register(ViPipe, 0x3820, 0x03); + os04a10_write_register(ViPipe, 0x3821, 0x00); + os04a10_write_register(ViPipe, 0x3822, 0x14); + os04a10_write_register(ViPipe, 0x3823, 0x18); + os04a10_write_register(ViPipe, 0x3826, 0x00); + os04a10_write_register(ViPipe, 0x3827, 0x00); + os04a10_write_register(ViPipe, 0x3833, 0x41); + os04a10_write_register(ViPipe, 0x384c, 0x02); + os04a10_write_register(ViPipe, 0x384d, 0xdc); + os04a10_write_register(ViPipe, 0x3858, 0x3c); + os04a10_write_register(ViPipe, 0x3865, 0x02); + os04a10_write_register(ViPipe, 0x3866, 0x00); + os04a10_write_register(ViPipe, 0x3867, 0x00); + os04a10_write_register(ViPipe, 0x3868, 0x02); + os04a10_write_register(ViPipe, 0x3900, 0x13); + os04a10_write_register(ViPipe, 0x3940, 0x13); + os04a10_write_register(ViPipe, 0x3980, 0x13); + os04a10_write_register(ViPipe, 0x3c01, 0x11); + os04a10_write_register(ViPipe, 0x3c05, 0x00); + os04a10_write_register(ViPipe, 0x3c0f, 0x1c); + os04a10_write_register(ViPipe, 0x3c12, 0x0d); + os04a10_write_register(ViPipe, 0x3c19, 0x00); + os04a10_write_register(ViPipe, 0x3c21, 0x00); + os04a10_write_register(ViPipe, 0x3c3a, 0x10); + os04a10_write_register(ViPipe, 0x3c3b, 0x18); + os04a10_write_register(ViPipe, 0x3c3d, 0xc6); + os04a10_write_register(ViPipe, 0x3c55, 0x08); + os04a10_write_register(ViPipe, 0x3c5a, 0x55); + os04a10_write_register(ViPipe, 0x3c5d, 0xcf); + os04a10_write_register(ViPipe, 0x3c5e, 0xcf); + os04a10_write_register(ViPipe, 0x3d8c, 0x70); + os04a10_write_register(ViPipe, 0x3d8d, 0x10); + os04a10_write_register(ViPipe, 0x4000, 0xf9); + os04a10_write_register(ViPipe, 0x4001, 0xef); + os04a10_write_register(ViPipe, 0x4004, 0x00); + os04a10_write_register(ViPipe, 0x4005, 0x40); + os04a10_write_register(ViPipe, 0x4008, 0x02); + os04a10_write_register(ViPipe, 0x4009, 0x11); + os04a10_write_register(ViPipe, 0x400a, 0x06); + os04a10_write_register(ViPipe, 0x400b, 0x40); + os04a10_write_register(ViPipe, 0x400e, 0x40); + os04a10_write_register(ViPipe, 0x402e, 0x00); + os04a10_write_register(ViPipe, 0x402f, 0x40); + os04a10_write_register(ViPipe, 0x4030, 0x00); + os04a10_write_register(ViPipe, 0x4031, 0x40); + os04a10_write_register(ViPipe, 0x4032, 0x0f); + os04a10_write_register(ViPipe, 0x4033, 0x80); + os04a10_write_register(ViPipe, 0x4050, 0x00); + os04a10_write_register(ViPipe, 0x4051, 0x07); + os04a10_write_register(ViPipe, 0x4011, 0xbb); + os04a10_write_register(ViPipe, 0x410f, 0x01); + os04a10_write_register(ViPipe, 0x4288, 0xce); + os04a10_write_register(ViPipe, 0x4289, 0x00); + os04a10_write_register(ViPipe, 0x428a, 0x46); + os04a10_write_register(ViPipe, 0x430b, 0x0f); + os04a10_write_register(ViPipe, 0x430c, 0xfc); + os04a10_write_register(ViPipe, 0x430d, 0x00); + os04a10_write_register(ViPipe, 0x430e, 0x00); + os04a10_write_register(ViPipe, 0x4314, 0x04); + os04a10_write_register(ViPipe, 0x4500, 0x18); + os04a10_write_register(ViPipe, 0x4501, 0x18); + os04a10_write_register(ViPipe, 0x4503, 0x10); + os04a10_write_register(ViPipe, 0x4504, 0x00); + os04a10_write_register(ViPipe, 0x4506, 0x32); + os04a10_write_register(ViPipe, 0x4507, 0x03); + os04a10_write_register(ViPipe, 0x4601, 0x30); + os04a10_write_register(ViPipe, 0x4603, 0x00); + os04a10_write_register(ViPipe, 0x460a, 0x50); + os04a10_write_register(ViPipe, 0x460c, 0x60); + os04a10_write_register(ViPipe, 0x4640, 0x62); + os04a10_write_register(ViPipe, 0x4646, 0xaa); + os04a10_write_register(ViPipe, 0x4647, 0x55); + os04a10_write_register(ViPipe, 0x4648, 0x99); + os04a10_write_register(ViPipe, 0x4649, 0x66); + os04a10_write_register(ViPipe, 0x464d, 0x00); + os04a10_write_register(ViPipe, 0x4654, 0x11); + os04a10_write_register(ViPipe, 0x4655, 0x22); + os04a10_write_register(ViPipe, 0x4800, 0x44); + os04a10_write_register(ViPipe, 0x480e, 0x04); + os04a10_write_register(ViPipe, 0x4810, 0xff); + os04a10_write_register(ViPipe, 0x4811, 0xff); + os04a10_write_register(ViPipe, 0x4813, 0x84); + os04a10_write_register(ViPipe, 0x481f, 0x30); + os04a10_write_register(ViPipe, 0x4837, 0x0e); + os04a10_write_register(ViPipe, 0x484b, 0x67); + os04a10_write_register(ViPipe, 0x4d00, 0x4d); + os04a10_write_register(ViPipe, 0x4d01, 0x9d); + os04a10_write_register(ViPipe, 0x4d02, 0xb9); + os04a10_write_register(ViPipe, 0x4d03, 0x2e); + os04a10_write_register(ViPipe, 0x4d04, 0x4a); + os04a10_write_register(ViPipe, 0x4d05, 0x3d); + os04a10_write_register(ViPipe, 0x4d09, 0x4f); + os04a10_write_register(ViPipe, 0x5000, 0x1f); + os04a10_write_register(ViPipe, 0x5001, 0x0c); + os04a10_write_register(ViPipe, 0x5080, 0x00); + os04a10_write_register(ViPipe, 0x50c0, 0x00); + os04a10_write_register(ViPipe, 0x5100, 0x00); + os04a10_write_register(ViPipe, 0x5200, 0x00); + os04a10_write_register(ViPipe, 0x5201, 0x00); + os04a10_write_register(ViPipe, 0x5202, 0x03); + os04a10_write_register(ViPipe, 0x5203, 0xff); + os04a10_write_register(ViPipe, 0x5780, 0x53); + os04a10_write_register(ViPipe, 0x5782, 0x18); + os04a10_write_register(ViPipe, 0x5783, 0x3c); + os04a10_write_register(ViPipe, 0x5786, 0x01); + os04a10_write_register(ViPipe, 0x5788, 0x18); + os04a10_write_register(ViPipe, 0x5789, 0x3c); + os04a10_write_register(ViPipe, 0x5792, 0x11); + os04a10_write_register(ViPipe, 0x5793, 0x33); + os04a10_write_register(ViPipe, 0x5857, 0xff); + os04a10_write_register(ViPipe, 0x5858, 0xff); + os04a10_write_register(ViPipe, 0x5859, 0xff); + os04a10_write_register(ViPipe, 0x58d7, 0xff); + os04a10_write_register(ViPipe, 0x58d8, 0xff); + os04a10_write_register(ViPipe, 0x58d9, 0xff); + + os04a10_default_reg_init(ViPipe); + os04a10_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===OS04A10 1520P 30fps 10bit 2to1 WDR Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_os04c10/Makefile b/middleware/v2/component/isp/sensor/cv180x/ov_os04c10/Makefile new file mode 100644 index 000000000..f9ec29965 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_os04c10/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_os04c10.a +TARGET_SO = $(MW_LIB)/libsns_os04c10.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_os04c10/os04c10_cmos.c b/middleware/v2/component/isp/sensor/cv180x/ov_os04c10/os04c10_cmos.c new file mode 100644 index 000000000..06321a7fa --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_os04c10/os04c10_cmos.c @@ -0,0 +1,1133 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "os04c10_cmos_ex.h" +#include "os04c10_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define OS04C10_ID 0x530443 +#define OS04C10_I2C_ADDR_1 0x10 +#define OS04C10_I2C_ADDR_2 0x36 +#define OS04C10_I2C_ADDR_IS_VALID(addr) ((addr) == OS04C10_I2C_ADDR_1 || (addr) == OS04C10_I2C_ADDR_2) +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastOs04c10[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define OS04C10_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastOs04c10[dev]) +#define OS04C10_SENSOR_SET_CTX(dev, pstCtx) (g_pastOs04c10[dev] = pstCtx) +#define OS04C10_SENSOR_RESET_CTX(dev) (g_pastOs04c10[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunOs04c10_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Os04c10_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Os04c10_UseHwSync[VI_MAX_PIPE_NUM] = {0}; + +OS04C10_STATE_S g_astOs04c10_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeOs04c10_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Os04c10 Lines Range*****/ +#define OS04C10_FULL_LINES_MAX (0xFFFF) +#define OS04C10_FULL_LINES_MAX_2TO1_WDR (0xFFFF) + +/*****Os04c10 Register Address*****/ +#define OS04C10_HOLD_3208 0x3208 +#define OS04C10_HOLD_320D 0x320D +#define OS04C10_EXP1_ADDR 0x3501 +#define OS04C10_EXP2_ADDR 0x3511 +#define OS04C10_AGAIN1_ADDR 0x3508 +#define OS04C10_DGAIN1_ADDR 0x350A +#define OS04C10_AGAIN2_ADDR 0x350C +#define OS04C10_DGAIN2_ADDR 0x350E +#define OS04C10_L2S_ADDR 0x3798 +#define OS04C10_VTS_ADDR 0x380E +#define OS04C10_GGAIN_ADDR 0x5142 +#define OS04C10_TABLE_END 0xffff + +#define OS04C10_RES_IS_1520P(w, h) ((w) == 2688 && (h) == 1520) +#define OS04C10_RES_IS_1440P(w, h) ((w) == 2560 && (h) == 1440) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const OS04C10_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astOs04c10_mode[pstSnsState->u8ImgMode]; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = OS04C10_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + /* OV sensor cannot update new setting before the old setting takes effect */ + pstAeSnsDft->u8AERunInterval = 4; + + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + } + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astOs04c10_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astOs04c10_mode[pstSnsState->u8ImgMode].f32MinFps; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OS04C10_FULL_LINES_MAX) ? OS04C10_FULL_LINES_MAX : u32VMAX; + + pstSnsRegsInfo->astI2cData[LINEAR_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_1].u32Data = (u32VMAX & 0xFF); + } else { + CVI_U32 isp_res = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32IspResTime; + CVI_U32 l2s_offset = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32L2S_offset; + CVI_U32 margin = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32HdrMargin; + CVI_U32 vblank = 0; + + /* In auto mode, + * L2S_distane = Sexp_max + L2S offset + * Vblank = Vtotal - Vactive - margin + * if Vblank > isp_res + * Sexp_max + L2S offset <= Vblank - isp_res + * else if Vblank < isp_res + * Sexp_max + L2S offset = Vblank + */ + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OS04C10_FULL_LINES_MAX_2TO1_WDR) ? + OS04C10_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + + vblank = u32VMAX - g_astOs04c10_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height + - margin; + if (vblank > isp_res) + vblank -= isp_res; + else + CVI_TRACE_SNS(CVI_DBG_WARN, "cannot reserve 1ms for isp delay %d\n", vblank); + + g_astOs04c10_State[ViPipe].u32Sexp_MAX = vblank - l2s_offset; + pstSnsRegsInfo->astI2cData[WDR2_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_VTS_1].u32Data = (u32VMAX & 0xFF); + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32IntTime[0]; + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = u32IntTime[1]; + + pstSnsRegsInfo->astI2cData[WDR2_EXP1_0].u32Data = ((pstSnsState->au32WDRIntTime[1] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_EXP1_1].u32Data = (pstSnsState->au32WDRIntTime[1] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_EXP2_0].u32Data = ((pstSnsState->au32WDRIntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_EXP2_1].u32Data = (pstSnsState->au32WDRIntTime[0] & 0xFF); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + + //When the expLine is very small, the exposure time of R G B has a great error + //use sensor internal Ggain to fix the gap + //sync patch from ov fae: clyde.liu + CVI_FLOAT ratio1 = (CVI_FLOAT)((u32IntTime[1] + 0.25) * (u32IntTime[0] + 0.75)); + CVI_FLOAT ratio2 = (CVI_FLOAT)((u32IntTime[1] + 0.75) * (u32IntTime[0] + 0.25)); + CVI_FLOAT ratio = ratio1 / ratio2; + CVI_U16 fixGGain = (CVI_U16)(ratio * 1024); + + pstSnsRegsInfo->astI2cData[WDR2_GGAIN_0].u32Data = (fixGGain & 0xFF00) >> 8; + pstSnsRegsInfo->astI2cData[WDR2_GGAIN_1].u32Data = (fixGGain & 0xFF); + + } else { + pstSnsRegsInfo->astI2cData[LINEAR_EXP_0].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_1].u32Data = (u32IntTime[0] & 0xFF); + } + + return CVI_SUCCESS; + +} + +/* + * GainReg {0x3508, 0x3509} Real Gain + * 0x0080~0x00FF INT(GainReg/8)/16 + * 0x0100~0x01FF INT(GainReg/16)/8 + * 0x0200~0x03FF INT(GainReg/32)/4 + * 0x0400~0x07FF INT(GainReg/64)/2 + */ + +static CVI_U32 gain_table[64] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[63]) { + *pu32AgainLin = gain_table[63]; + *pu32AgainDb = (63 - 48) * 64 + 1024; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + i--; + if (i < 16) + *pu32AgainDb = i * 8 + 128; + else if (i < 32) + *pu32AgainDb = (i - 16) * 16 + 256; + else if (i < 48) + *pu32AgainDb = (i - 32) * 32 + 512; + else + *pu32AgainDb = (i - 48) * 64 + 1024; + + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin <= 1024) { + *pu32DgainLin = 1024; + } else if (*pu32DgainLin > 16383) { + *pu32DgainLin = 16383; + } + *pu32DgainDb = *pu32DgainLin; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0].u32Data = ((u32Again & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_1].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0].u32Data = ((u32Dgain & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1].u32Data = (u32Dgain & 0xFF); + } else { + /* DOL mode */ + u32Again = pu32Again[1]; + u32Dgain = pu32Dgain[1]; + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_0].u32Data = ((u32Again & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_1].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_0].u32Data = ((u32Dgain & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_1].u32Data = (u32Dgain & 0xFF); + + if (g_au16Os04c10_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[1]; + u32Dgain = pu32Dgain[1]; + } else if (g_au16Os04c10_GainMode[ViPipe] == SNS_GAIN_MODE_WDR_2F) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + } else { + return CVI_SUCCESS; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_0].u32Data = ((u32Again & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_1].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_0].u32Data = ((u32Dgain & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_1].u32Data = (u32Dgain & 0xFF); + + } + + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = 2; + /* + * Max Lexp = VTS - 8 + * Max Sexp = VTS - Lexp - 12 + * Long exp + Short exp < VTS - 12 + */ + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 12 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 12) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + + u32IntTimeMaxTmp = (g_astOs04c10_State[ViPipe].u32Sexp_MAX < u32IntTimeMaxTmp) ? + g_astOs04c10_State[ViPipe].u32Sexp_MAX : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + syslog(LOG_DEBUG, "Max inttime0 = %u\n", u32IntTimeMaxTmp); + + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio is too large!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + else + memcpy(pstBlc, + &g_stIspBlcCalibratio10Bit, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const OS04C10_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astOs04c10_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == OS04C10_MODE_2688X1520P30_WDR) + pstSnsState->u8ImgMode = OS04C10_MODE_2688X1520P30; + else if (pstSnsState->u8ImgMode == OS04C10_MODE_2560X1440P30_WDR) + pstSnsState->u8ImgMode = OS04C10_MODE_2560X1440P30; + else { + } + + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == OS04C10_MODE_2688X1520P30) { + pstSnsState->u8ImgMode = OS04C10_MODE_2688X1520P30_WDR; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1520p mode(60fps->30fps)\n"); + } else if (pstSnsState->u8ImgMode == OS04C10_MODE_2560X1440P30) { + pstSnsState->u8ImgMode = OS04C10_MODE_2560X1440P30_WDR; + } else { + } + + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32VtsDef; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunOs04c10_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = os04c10_i2c_addr; + pstI2c_data[i].u32AddrByteNum = os04c10_addr_byte; + pstI2c_data[i].u32DataByteNum = os04c10_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[WDR2_HOLD_START].u32RegAddr = OS04C10_HOLD_3208; + pstI2c_data[WDR2_HOLD_START].u32Data = 0x00; + pstI2c_data[WDR2_EXP1_0].u32RegAddr = OS04C10_EXP1_ADDR; + pstI2c_data[WDR2_EXP1_1].u32RegAddr = OS04C10_EXP1_ADDR + 1; + pstI2c_data[WDR2_EXP2_0].u32RegAddr = OS04C10_EXP2_ADDR; + pstI2c_data[WDR2_EXP2_1].u32RegAddr = OS04C10_EXP2_ADDR + 1; + pstI2c_data[WDR2_AGAIN1_0].u32RegAddr = OS04C10_AGAIN1_ADDR; + pstI2c_data[WDR2_AGAIN1_1].u32RegAddr = OS04C10_AGAIN1_ADDR + 1; + pstI2c_data[WDR2_AGAIN2_0].u32RegAddr = OS04C10_AGAIN2_ADDR; + pstI2c_data[WDR2_AGAIN2_1].u32RegAddr = OS04C10_AGAIN2_ADDR + 1; + pstI2c_data[WDR2_DGAIN1_0].u32RegAddr = OS04C10_DGAIN1_ADDR; + pstI2c_data[WDR2_DGAIN1_1].u32RegAddr = OS04C10_DGAIN1_ADDR + 1; + pstI2c_data[WDR2_DGAIN2_0].u32RegAddr = OS04C10_DGAIN2_ADDR; + pstI2c_data[WDR2_DGAIN2_1].u32RegAddr = OS04C10_DGAIN2_ADDR + 1; + pstI2c_data[WDR2_VTS_0].u32RegAddr = OS04C10_VTS_ADDR; + pstI2c_data[WDR2_VTS_1].u32RegAddr = OS04C10_VTS_ADDR + 1; + pstI2c_data[WDR2_HOLD_END].u32RegAddr = OS04C10_HOLD_3208; + pstI2c_data[WDR2_HOLD_END].u32Data = 0x10; + pstI2c_data[WDR2_LAUNCH_0].u32RegAddr = OS04C10_HOLD_320D; + pstI2c_data[WDR2_LAUNCH_0].u32Data = 0x00; + pstI2c_data[WDR2_LAUNCH_0].u8DelayFrmNum = 0; + pstI2c_data[WDR2_LAUNCH_1].u32RegAddr = OS04C10_HOLD_3208; + pstI2c_data[WDR2_LAUNCH_1].u32Data = 0xA0; + pstI2c_data[WDR2_LAUNCH_1].u8DelayFrmNum = 0; + pstI2c_data[WDR2_GGAIN_0].u32RegAddr = OS04C10_GGAIN_ADDR; + pstI2c_data[WDR2_GGAIN_1].u32RegAddr = OS04C10_GGAIN_ADDR + 1; + break; + default: + pstI2c_data[LINEAR_HOLD_START].u32RegAddr = OS04C10_HOLD_3208; + pstI2c_data[LINEAR_HOLD_START].u32Data = 0x00; + pstI2c_data[LINEAR_EXP_0].u32RegAddr = OS04C10_EXP1_ADDR; + pstI2c_data[LINEAR_EXP_1].u32RegAddr = OS04C10_EXP1_ADDR + 1; + pstI2c_data[LINEAR_AGAIN_0].u32RegAddr = OS04C10_AGAIN1_ADDR; + pstI2c_data[LINEAR_AGAIN_1].u32RegAddr = OS04C10_AGAIN1_ADDR + 1; + pstI2c_data[LINEAR_DGAIN_0].u32RegAddr = OS04C10_DGAIN1_ADDR; + pstI2c_data[LINEAR_DGAIN_1].u32RegAddr = OS04C10_DGAIN1_ADDR + 1; + pstI2c_data[LINEAR_VTS_0].u32RegAddr = OS04C10_VTS_ADDR; + pstI2c_data[LINEAR_VTS_1].u32RegAddr = OS04C10_VTS_ADDR + 1; + pstI2c_data[LINEAR_HOLD_END].u32RegAddr = OS04C10_HOLD_3208; + pstI2c_data[LINEAR_HOLD_END].u32Data = 0x10; + pstI2c_data[LINEAR_LAUNCH_0].u32RegAddr = OS04C10_HOLD_320D; + pstI2c_data[LINEAR_LAUNCH_0].u32Data = 0x00; + pstI2c_data[LINEAR_LAUNCH_0].u8DelayFrmNum = 0; + pstI2c_data[LINEAR_LAUNCH_1].u32RegAddr = OS04C10_HOLD_3208; + pstI2c_data[LINEAR_LAUNCH_1].u32Data = 0xA0; + pstI2c_data[LINEAR_LAUNCH_1].u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[WDR2_HOLD_START].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_HOLD_END].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_LAUNCH_0].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_LAUNCH_1].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD_START].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_HOLD_END].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_LAUNCH_0].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_LAUNCH_1].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (OS04C10_RES_IS_1520P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OS04C10_MODE_2688X1520P30; + else if (OS04C10_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OS04C10_MODE_2560X1440P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (OS04C10_RES_IS_1520P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OS04C10_MODE_2688X1520P30_WDR; + else if (OS04C10_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OS04C10_MODE_2560X1440P30_WDR; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeOs04c10_MirrorFip[ViPipe] != eSnsMirrorFlip) { + os04c10_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeOs04c10_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = OS04C10_MODE_2560X1440P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &os04c10_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astOs04c10_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astOs04c10_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } else { + pstRxAttr->mac_clk = RX_MAC_CLK_400M; + pstRxAttr->mipi_attr.raw_data_type = RAW_DATA_10BIT; + } + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &os04c10_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = os04c10_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = os04c10_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (OS04C10_I2C_ADDR_IS_VALID(s32I2cAddr)) + os04c10_i2c_addr = s32I2cAddr; +} + +static CVI_S32 os04c10_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunOs04c10_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + OS04C10_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + OS04C10_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = OS04C10_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, OS04C10_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, OS04C10_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, OS04C10_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Os04c10_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Os04c10_UseHwSync[ViPipe] = pstInitAttr->u16UseHwSync; + + return CVI_SUCCESS; +} +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return os04c10_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsOs04c10_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = os04c10_standby, + .pfnRestart = os04c10_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = os04c10_write_register, + .pfnReadReg = os04c10_read_register, + .pfnSetBusInfo = os04c10_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_os04c10/os04c10_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/ov_os04c10/os04c10_cmos_ex.h new file mode 100644 index 000000000..6245ff339 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_os04c10/os04c10_cmos_ex.h @@ -0,0 +1,121 @@ +#ifndef __OS04C10_CMOS_EX_H_ +#define __OS04C10_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum os04c10_linear_regs_e { + LINEAR_HOLD_START = 0, + LINEAR_EXP_0, + LINEAR_EXP_1, + LINEAR_AGAIN_0, + LINEAR_AGAIN_1, + LINEAR_DGAIN_0, + LINEAR_DGAIN_1, + LINEAR_VTS_0, + LINEAR_VTS_1, + LINEAR_HOLD_END, + LINEAR_LAUNCH_0, + LINEAR_LAUNCH_1, + LINEAR_REGS_NUM +}; + +enum os04c10_wdr2_regs_e { + WDR2_HOLD_START = 0, + WDR2_EXP1_0, + WDR2_EXP1_1, + WDR2_EXP2_0, + WDR2_EXP2_1, + WDR2_AGAIN1_0, + WDR2_AGAIN1_1, + WDR2_AGAIN2_0, + WDR2_AGAIN2_1, + WDR2_DGAIN1_0, + WDR2_DGAIN1_1, + WDR2_DGAIN2_0, + WDR2_DGAIN2_1, + WDR2_VTS_0, + WDR2_VTS_1, + WDR2_HOLD_END, + WDR2_LAUNCH_0, + WDR2_LAUNCH_1, + WDR2_GGAIN_0, + WDR2_GGAIN_1, + WDR2_REGS_NUM +}; + +typedef enum _OS04C10_MODE_E { + OS04C10_MODE_2688X1520P30 = 0, + OS04C10_MODE_2560X1440P30, + OS04C10_MODE_LINEAR_NUM, + OS04C10_MODE_2688X1520P30_WDR = OS04C10_MODE_LINEAR_NUM, + OS04C10_MODE_2560X1440P30_WDR, + OS04C10_MODE_NUM +} OS04C10_MODE_E; + +typedef struct _OS04C10_STATE_S { + CVI_U32 u32Sexp_MAX; +} OS04C10_STATE_S; + +typedef struct _OS04C10_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + CVI_U16 u16L2sOffset; + CVI_U16 u16TopBoundary; + CVI_U16 u16BotBoundary; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + CVI_U32 u32L2S_offset; + CVI_U32 u32IspResTime; + CVI_U32 u32HdrMargin; + char name[64]; +} OS04C10_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastOs04c10[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunOs04c10_BusInfo[]; +extern CVI_U16 g_au16Os04c10_GainMode[]; +extern CVI_U16 g_au16Os04c10_UseHwSync[VI_MAX_PIPE_NUM]; +extern CVI_U8 os04c10_i2c_addr; +extern const CVI_U32 os04c10_addr_byte; +extern const CVI_U32 os04c10_data_byte; +extern void os04c10_init(VI_PIPE ViPipe); +extern void os04c10_exit(VI_PIPE ViPipe); +extern void os04c10_standby(VI_PIPE ViPipe); +extern void os04c10_restart(VI_PIPE ViPipe); +extern int os04c10_write_register(VI_PIPE ViPipe, int addr, int data); +extern int os04c10_read_register(VI_PIPE ViPipe, int addr); +extern void os04c10_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int os04c10_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OS04C10_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_os04c10/os04c10_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/ov_os04c10/os04c10_cmos_param.h new file mode 100644 index 000000000..015eda30c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_os04c10/os04c10_cmos_param.h @@ -0,0 +1,359 @@ +#ifndef __OS04C10_CMOS_PARAM_H_ +#define __OS04C10_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "os04c10_cmos_ex.h" + +static const OS04C10_MODE_S g_astOs04c10_mode[OS04C10_MODE_NUM] = { + [OS04C10_MODE_2688X1520P30] = { + .name = "2688x1520p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2688, + .u32Height = 1520, + }, + .stMaxSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.73, /* 0x626 * 30 / 0xFFFF */ + .u32HtsDef = 3116, + .u32VtsDef = 1574, + .stExp[0] = { + .u16Min = 2, + .u16Max = 1574 - 8, + .u16Def = 500, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [OS04C10_MODE_2560X1440P30] = { + .name = "2560x1440p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.73, /* 0x626 * 30 / 0xFFFF */ + .u32HtsDef = 3116, + .u32VtsDef = 1574, + .stExp[0] = { + .u16Min = 2, + .u16Max = 1574 - 8, + .u16Def = 500, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [OS04C10_MODE_2688X1520P30_WDR] = { + .name = "2688x1520p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2688, + .u32Height = 1520, + }, + .stMaxSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2688, + .u32Height = 1520, + }, + .stMaxSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.77, /* 1682 * 30 / 0xFFFF */ + .u32HtsDef = 2972, + .u32VtsDef = 1682, + .u16L2sOffset = 4, + .u16TopBoundary = 24, + .u16BotBoundary = 244, + .stExp[0] = { + .u16Min = 8, + .u16Max = 88, + .u16Def = 88, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 8, + .u16Max = 0x486 - 4 - 88, + .u16Def = 500, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 1, + }, + .u32L2S_offset = 4, + .u32IspResTime = 50, /* about 1ms * line rate */ + .u32HdrMargin = 40, /* black_line + zero_line + ISP_offset * 2 */ + }, + [OS04C10_MODE_2560X1440P30_WDR] = { + .name = "2560x1440p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.77, /* 1682 * 30 / 0xFFFF */ + .u32HtsDef = 2972, + .u32VtsDef = 1682, + .u16L2sOffset = 4, + .u16TopBoundary = 24, + .u16BotBoundary = 244, + .stExp[0] = { + .u16Min = 8, + .u16Max = 88, + .u16Def = 88, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 8, + .u16Max = 0x486 - 4 - 88, + .u16Def = 500, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 1, + }, + .u32L2S_offset = 4, + .u32IspResTime = 50, /* about 1ms * line rate */ + .u32HdrMargin = 40, /* black_line + zero_line + ISP_offset * 2 */ + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {128, 128, 128, 128, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1057, 1057, 1057, 1057 +#endif + }, + .stAuto = { + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, +#endif + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio10Bit = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, +#endif + }, + }, +}; + +struct combo_dev_attr_s os04c10_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {0, 1, 2, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_25M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OS04C10_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_os04c10/os04c10_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/ov_os04c10/os04c10_sensor_ctl.c new file mode 100644 index 000000000..2cc6f6674 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_os04c10/os04c10_sensor_ctl.c @@ -0,0 +1,1627 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "os04c10_cmos_ex.h" + +#define HW_SYNC_AUTO 1 + +static void os04c10_wdr_1520p30_2to1_init(VI_PIPE ViPipe); +static void os04c10_linear_1520p30_init(VI_PIPE ViPipe); +static void os04c10_wdr_1440p30_2to1_init(VI_PIPE ViPipe); +static void os04c10_linear_1440p30_init(VI_PIPE ViPipe); + + +CVI_U8 os04c10_i2c_addr = 0x10; /* I2C Address of OS04C10 */ +const CVI_U32 os04c10_addr_byte = 2; +const CVI_U32 os04c10_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int os04c10_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunOs04c10_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, os04c10_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int os04c10_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int os04c10_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (os04c10_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, os04c10_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, os04c10_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (os04c10_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int os04c10_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (os04c10_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (os04c10_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, os04c10_addr_byte + os04c10_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void os04c10_prog(VI_PIPE ViPipe, int *rom) +{ + int i = 0; + + while (1) { + int lookup = rom[i++]; + int addr = (lookup >> 16) & 0xFFFF; + int data = lookup & 0xFFFF; + + if (addr == 0xFFFE) + delay_ms(data); + else if (addr != 0xFFFF) + os04c10_write_register(ViPipe, addr, data); + } +} + +void os04c10_standby(VI_PIPE ViPipe) +{ + os04c10_write_register(ViPipe, 0x0100, 0x00); /* STANDBY */ +} + +void os04c10_restart(VI_PIPE ViPipe) +{ + os04c10_write_register(ViPipe, 0x0100, 0x01); /* standby */ +} + +void os04c10_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + CVI_U32 start = 1; + CVI_U32 end = g_pastOs04c10[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum - 3; + + for (i = start; i < end; i++) { + os04c10_write_register(ViPipe, + g_pastOs04c10[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastOs04c10[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void os04c10_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 orien1, orien2; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + orien1 = 0x80; + orien2 = 0x24; + break; + case ISP_SNS_MIRROR: + orien1 = 0x88; + orien2 = 0x24; + break; + case ISP_SNS_FLIP: + orien1 = 0xB0; + orien2 = 0x04; + break; + case ISP_SNS_MIRROR_FLIP: + orien1 = 0xB8; + orien2 = 0x04; + break; + default: + return; + } + + os04c10_write_register(ViPipe, 0x3820, orien1); + os04c10_write_register(ViPipe, 0x3716, orien2); +} +#define OS04C10_CHIP_ID_ADDR_H 0x300A +#define OS04C10_CHIP_ID_ADDR_M 0x300B +#define OS04C10_CHIP_ID_ADDR_L 0x300C +#define OS04C10_CHIP_ID 0x530443 + +int os04c10_probe(VI_PIPE ViPipe) +{ + int nVal, nVal2, nVal3; + + usleep(500); + if (os04c10_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = os04c10_read_register(ViPipe, OS04C10_CHIP_ID_ADDR_H); + nVal2 = os04c10_read_register(ViPipe, OS04C10_CHIP_ID_ADDR_M); + nVal3 = os04c10_read_register(ViPipe, OS04C10_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0 || nVal3 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 16) | ((nVal2 & 0xFF) << 8) | (nVal3 & 0xFF)) != OS04C10_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void os04c10_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastOs04c10[ViPipe]->enWDRMode; + u8ImgMode = g_pastOs04c10[ViPipe]->u8ImgMode; + + os04c10_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == OS04C10_MODE_2688X1520P30_WDR) + os04c10_wdr_1520p30_2to1_init(ViPipe); + else if (u8ImgMode == OS04C10_MODE_2560X1440P30_WDR) + os04c10_wdr_1440p30_2to1_init(ViPipe); + else { + } + } else { + if (u8ImgMode == OS04C10_MODE_2688X1520P30) + os04c10_linear_1520p30_init(ViPipe); + else if (u8ImgMode == OS04C10_MODE_2560X1440P30) + os04c10_linear_1440p30_init(ViPipe); + else { + } + } + g_pastOs04c10[ViPipe]->bInit = CVI_TRUE; +} + +void os04c10_exit(VI_PIPE ViPipe) +{ + os04c10_i2c_exit(ViPipe); +} + +/* 1520P30 and 1520P25 */ +static void os04c10_linear_1520p30_init(VI_PIPE ViPipe) +{ + os04c10_write_register(ViPipe, 0x0100, 0x00); + os04c10_write_register(ViPipe, 0x0103, 0x01); + os04c10_write_register(ViPipe, 0x0301, 0xe4); + os04c10_write_register(ViPipe, 0x0303, 0x01); + os04c10_write_register(ViPipe, 0x0305, 0x6e); + os04c10_write_register(ViPipe, 0x0306, 0x01); + os04c10_write_register(ViPipe, 0x0307, 0x17); + os04c10_write_register(ViPipe, 0x0323, 0x04); + os04c10_write_register(ViPipe, 0x0324, 0x01); + os04c10_write_register(ViPipe, 0x0325, 0x62); + os04c10_write_register(ViPipe, 0x3012, 0x06); + os04c10_write_register(ViPipe, 0x3013, 0x02); + os04c10_write_register(ViPipe, 0x3016, 0x72); + os04c10_write_register(ViPipe, 0x3021, 0x03); + os04c10_write_register(ViPipe, 0x3106, 0x21); + os04c10_write_register(ViPipe, 0x3107, 0xa1); + os04c10_write_register(ViPipe, 0x3500, 0x00); + os04c10_write_register(ViPipe, 0x3501, 0x06); + os04c10_write_register(ViPipe, 0x3502, 0x1e); + os04c10_write_register(ViPipe, 0x3503, 0x88); + os04c10_write_register(ViPipe, 0x3508, 0x00); + os04c10_write_register(ViPipe, 0x3509, 0x80); + os04c10_write_register(ViPipe, 0x350a, 0x04); + os04c10_write_register(ViPipe, 0x350b, 0x00); + os04c10_write_register(ViPipe, 0x350c, 0x00); + os04c10_write_register(ViPipe, 0x350d, 0x80); + os04c10_write_register(ViPipe, 0x350e, 0x04); + os04c10_write_register(ViPipe, 0x350f, 0x00); + os04c10_write_register(ViPipe, 0x3510, 0x00); + os04c10_write_register(ViPipe, 0x3511, 0x00); + os04c10_write_register(ViPipe, 0x3512, 0x20); + os04c10_write_register(ViPipe, 0x3624, 0x02); + os04c10_write_register(ViPipe, 0x3625, 0x4c); + os04c10_write_register(ViPipe, 0x3660, 0x00); + os04c10_write_register(ViPipe, 0x3666, 0xa5); + os04c10_write_register(ViPipe, 0x3667, 0xa5); + os04c10_write_register(ViPipe, 0x366a, 0x60); + os04c10_write_register(ViPipe, 0x3673, 0x0d); + os04c10_write_register(ViPipe, 0x3672, 0x0d); + os04c10_write_register(ViPipe, 0x3671, 0x0d); + os04c10_write_register(ViPipe, 0x3670, 0x0d); + os04c10_write_register(ViPipe, 0x3685, 0x00); + os04c10_write_register(ViPipe, 0x3694, 0x0d); + os04c10_write_register(ViPipe, 0x3693, 0x0d); + os04c10_write_register(ViPipe, 0x3692, 0x0d); + os04c10_write_register(ViPipe, 0x3691, 0x0d); + os04c10_write_register(ViPipe, 0x3696, 0x4c); + os04c10_write_register(ViPipe, 0x3697, 0x4c); + os04c10_write_register(ViPipe, 0x3698, 0x40); + os04c10_write_register(ViPipe, 0x3699, 0x80); + os04c10_write_register(ViPipe, 0x369a, 0x18); + os04c10_write_register(ViPipe, 0x369b, 0x1f); + os04c10_write_register(ViPipe, 0x369c, 0x14); + os04c10_write_register(ViPipe, 0x369d, 0x80); + os04c10_write_register(ViPipe, 0x369e, 0x40); + os04c10_write_register(ViPipe, 0x369f, 0x21); + os04c10_write_register(ViPipe, 0x36a0, 0x12); + os04c10_write_register(ViPipe, 0x36a1, 0x5d); + os04c10_write_register(ViPipe, 0x36a2, 0x66); + os04c10_write_register(ViPipe, 0x370a, 0x02); + os04c10_write_register(ViPipe, 0x370e, 0x0c); + os04c10_write_register(ViPipe, 0x3710, 0x00); + os04c10_write_register(ViPipe, 0x3713, 0x00); + os04c10_write_register(ViPipe, 0x3725, 0x02); + os04c10_write_register(ViPipe, 0x372a, 0x03); + os04c10_write_register(ViPipe, 0x3738, 0xce); + os04c10_write_register(ViPipe, 0x3739, 0x10); + os04c10_write_register(ViPipe, 0x3748, 0x02); + os04c10_write_register(ViPipe, 0x374a, 0x02); + os04c10_write_register(ViPipe, 0x374c, 0x02); + os04c10_write_register(ViPipe, 0x374e, 0x02); + os04c10_write_register(ViPipe, 0x3756, 0x00); + os04c10_write_register(ViPipe, 0x3757, 0x0e); + os04c10_write_register(ViPipe, 0x3767, 0x00); + os04c10_write_register(ViPipe, 0x3771, 0x00); + os04c10_write_register(ViPipe, 0x377b, 0x20); + os04c10_write_register(ViPipe, 0x377c, 0x00); + os04c10_write_register(ViPipe, 0x377d, 0x0c); + os04c10_write_register(ViPipe, 0x3781, 0x03); + os04c10_write_register(ViPipe, 0x3782, 0x00); + os04c10_write_register(ViPipe, 0x3789, 0x14); + os04c10_write_register(ViPipe, 0x3795, 0x02); + os04c10_write_register(ViPipe, 0x379c, 0x00); + os04c10_write_register(ViPipe, 0x379d, 0x00); + os04c10_write_register(ViPipe, 0x37b8, 0x04); + os04c10_write_register(ViPipe, 0x37ba, 0x03); + os04c10_write_register(ViPipe, 0x37bb, 0x00); + os04c10_write_register(ViPipe, 0x37bc, 0x04); + os04c10_write_register(ViPipe, 0x37be, 0x08); + os04c10_write_register(ViPipe, 0x37c4, 0x11); + os04c10_write_register(ViPipe, 0x37c5, 0x80); + os04c10_write_register(ViPipe, 0x37c6, 0x14); + os04c10_write_register(ViPipe, 0x37c7, 0x08); + os04c10_write_register(ViPipe, 0x37da, 0x11); + os04c10_write_register(ViPipe, 0x381f, 0x08); + os04c10_write_register(ViPipe, 0x3829, 0x03); + os04c10_write_register(ViPipe, 0x3832, 0x00); + os04c10_write_register(ViPipe, 0x3881, 0x00); + os04c10_write_register(ViPipe, 0x3888, 0x04); + os04c10_write_register(ViPipe, 0x388b, 0x00); + os04c10_write_register(ViPipe, 0x3c80, 0x10); + os04c10_write_register(ViPipe, 0x3c86, 0x00); + os04c10_write_register(ViPipe, 0x3c9f, 0x01); + os04c10_write_register(ViPipe, 0x3d85, 0x1b); + os04c10_write_register(ViPipe, 0x3d8c, 0x71); + os04c10_write_register(ViPipe, 0x3d8d, 0xe2); + os04c10_write_register(ViPipe, 0x3f00, 0x0b); + os04c10_write_register(ViPipe, 0x3f06, 0x04); + os04c10_write_register(ViPipe, 0x400a, 0x01); + os04c10_write_register(ViPipe, 0x400b, 0x50); + os04c10_write_register(ViPipe, 0x400e, 0x08); + os04c10_write_register(ViPipe, 0x4040, 0x00); + os04c10_write_register(ViPipe, 0x4041, 0x07); + os04c10_write_register(ViPipe, 0x4043, 0x7e); + os04c10_write_register(ViPipe, 0x4045, 0x7e); + os04c10_write_register(ViPipe, 0x4047, 0x7e); + os04c10_write_register(ViPipe, 0x4049, 0x7e); + os04c10_write_register(ViPipe, 0x4090, 0x04); + os04c10_write_register(ViPipe, 0x40b0, 0x00); + os04c10_write_register(ViPipe, 0x40b1, 0x00); + os04c10_write_register(ViPipe, 0x40b2, 0x00); + os04c10_write_register(ViPipe, 0x40b3, 0x00); + os04c10_write_register(ViPipe, 0x40b4, 0x00); + os04c10_write_register(ViPipe, 0x40b5, 0x00); + os04c10_write_register(ViPipe, 0x40b7, 0x00); + os04c10_write_register(ViPipe, 0x40b8, 0x00); + os04c10_write_register(ViPipe, 0x40b9, 0x00); + os04c10_write_register(ViPipe, 0x40ba, 0x00); + os04c10_write_register(ViPipe, 0x4301, 0x00); + os04c10_write_register(ViPipe, 0x4303, 0x00); + os04c10_write_register(ViPipe, 0x4502, 0x04); + os04c10_write_register(ViPipe, 0x4503, 0x00); + os04c10_write_register(ViPipe, 0x4504, 0x06); + os04c10_write_register(ViPipe, 0x4506, 0x00); + os04c10_write_register(ViPipe, 0x4507, 0x64); + os04c10_write_register(ViPipe, 0x4803, 0x00); + os04c10_write_register(ViPipe, 0x480c, 0x32); + os04c10_write_register(ViPipe, 0x480e, 0x00); + os04c10_write_register(ViPipe, 0x4813, 0x00); + os04c10_write_register(ViPipe, 0x4819, 0x70); + os04c10_write_register(ViPipe, 0x481f, 0x30); + os04c10_write_register(ViPipe, 0x4823, 0x3f); + os04c10_write_register(ViPipe, 0x4825, 0x30); + os04c10_write_register(ViPipe, 0x4833, 0x10); + os04c10_write_register(ViPipe, 0x484b, 0x07); + os04c10_write_register(ViPipe, 0x488b, 0x00); + os04c10_write_register(ViPipe, 0x4d00, 0x04); + os04c10_write_register(ViPipe, 0x4d01, 0xad); + os04c10_write_register(ViPipe, 0x4d02, 0xbc); + os04c10_write_register(ViPipe, 0x4d03, 0xa1); + os04c10_write_register(ViPipe, 0x4d04, 0x1f); + os04c10_write_register(ViPipe, 0x4d05, 0x4c); + os04c10_write_register(ViPipe, 0x4d0b, 0x01); + os04c10_write_register(ViPipe, 0x4e00, 0x2a); + os04c10_write_register(ViPipe, 0x4e0d, 0x00); + os04c10_write_register(ViPipe, 0x5001, 0x09); + os04c10_write_register(ViPipe, 0x5004, 0x00); + os04c10_write_register(ViPipe, 0x5080, 0x04); + os04c10_write_register(ViPipe, 0x5036, 0x00); + os04c10_write_register(ViPipe, 0x5180, 0x70); + os04c10_write_register(ViPipe, 0x5181, 0x10); + os04c10_write_register(ViPipe, 0x520a, 0x03); + os04c10_write_register(ViPipe, 0x520b, 0x06); + os04c10_write_register(ViPipe, 0x520c, 0x0c); + os04c10_write_register(ViPipe, 0x580b, 0x0f); + os04c10_write_register(ViPipe, 0x580d, 0x00); + os04c10_write_register(ViPipe, 0x580f, 0x00); + os04c10_write_register(ViPipe, 0x5820, 0x00); + os04c10_write_register(ViPipe, 0x5821, 0x00); + os04c10_write_register(ViPipe, 0x301c, 0xf8); + os04c10_write_register(ViPipe, 0x301e, 0xb4); + os04c10_write_register(ViPipe, 0x301f, 0xd0); + os04c10_write_register(ViPipe, 0x3022, 0x61); + os04c10_write_register(ViPipe, 0x3109, 0xe7); + os04c10_write_register(ViPipe, 0x3600, 0x00); + os04c10_write_register(ViPipe, 0x3610, 0x95); + os04c10_write_register(ViPipe, 0x3611, 0x85); + os04c10_write_register(ViPipe, 0x3613, 0x3a); + os04c10_write_register(ViPipe, 0x3615, 0x60); + os04c10_write_register(ViPipe, 0x3621, 0xb0); + os04c10_write_register(ViPipe, 0x3620, 0x0c); + os04c10_write_register(ViPipe, 0x3629, 0x00); + os04c10_write_register(ViPipe, 0x3661, 0x04); + os04c10_write_register(ViPipe, 0x3662, 0x10); + os04c10_write_register(ViPipe, 0x3664, 0x70); + os04c10_write_register(ViPipe, 0x3665, 0x00); + os04c10_write_register(ViPipe, 0x3681, 0xa6); + os04c10_write_register(ViPipe, 0x3682, 0x53); + os04c10_write_register(ViPipe, 0x3683, 0x2a); + os04c10_write_register(ViPipe, 0x3684, 0x15); + os04c10_write_register(ViPipe, 0x3700, 0x2a); + os04c10_write_register(ViPipe, 0x3701, 0x12); + os04c10_write_register(ViPipe, 0x3703, 0x28); + os04c10_write_register(ViPipe, 0x3704, 0x0e); + os04c10_write_register(ViPipe, 0x3706, 0x9d); + os04c10_write_register(ViPipe, 0x3709, 0x4a); + os04c10_write_register(ViPipe, 0x370b, 0x48); + os04c10_write_register(ViPipe, 0x370c, 0x01); + os04c10_write_register(ViPipe, 0x370f, 0x04); + os04c10_write_register(ViPipe, 0x3714, 0x24); + os04c10_write_register(ViPipe, 0x3716, 0x24); + os04c10_write_register(ViPipe, 0x3719, 0x11); + os04c10_write_register(ViPipe, 0x371a, 0x1e); + os04c10_write_register(ViPipe, 0x3720, 0x00); + os04c10_write_register(ViPipe, 0x3724, 0x13); + os04c10_write_register(ViPipe, 0x373f, 0xb0); + os04c10_write_register(ViPipe, 0x3741, 0x9d); + os04c10_write_register(ViPipe, 0x3743, 0x9d); + os04c10_write_register(ViPipe, 0x3745, 0x9d); + os04c10_write_register(ViPipe, 0x3747, 0x9d); + os04c10_write_register(ViPipe, 0x3749, 0x48); + os04c10_write_register(ViPipe, 0x374b, 0x48); + os04c10_write_register(ViPipe, 0x374d, 0x48); + os04c10_write_register(ViPipe, 0x374f, 0x48); + os04c10_write_register(ViPipe, 0x3755, 0x10); + os04c10_write_register(ViPipe, 0x376c, 0x00); + os04c10_write_register(ViPipe, 0x378d, 0x3c); + os04c10_write_register(ViPipe, 0x3790, 0x01); + os04c10_write_register(ViPipe, 0x3791, 0x01); + os04c10_write_register(ViPipe, 0x3798, 0x40); + os04c10_write_register(ViPipe, 0x379e, 0x00); + os04c10_write_register(ViPipe, 0x379f, 0x04); + os04c10_write_register(ViPipe, 0x37a1, 0x10); + os04c10_write_register(ViPipe, 0x37a2, 0x1e); + os04c10_write_register(ViPipe, 0x37a8, 0x10); + os04c10_write_register(ViPipe, 0x37a9, 0x1e); + os04c10_write_register(ViPipe, 0x37ac, 0xa0); + os04c10_write_register(ViPipe, 0x37b9, 0x01); + os04c10_write_register(ViPipe, 0x37bd, 0x01); + os04c10_write_register(ViPipe, 0x37bf, 0x26); + os04c10_write_register(ViPipe, 0x37c0, 0x11); + os04c10_write_register(ViPipe, 0x37c2, 0x04); + os04c10_write_register(ViPipe, 0x37cd, 0x19); + os04c10_write_register(ViPipe, 0x37d8, 0x02); + os04c10_write_register(ViPipe, 0x37d9, 0x08); + os04c10_write_register(ViPipe, 0x37e5, 0x02); + os04c10_write_register(ViPipe, 0x3800, 0x00); + os04c10_write_register(ViPipe, 0x3801, 0x00); + os04c10_write_register(ViPipe, 0x3802, 0x00); + os04c10_write_register(ViPipe, 0x3803, 0x00); + os04c10_write_register(ViPipe, 0x3804, 0x0a); + os04c10_write_register(ViPipe, 0x3805, 0x8f); + os04c10_write_register(ViPipe, 0x3806, 0x05); + os04c10_write_register(ViPipe, 0x3807, 0xff); + os04c10_write_register(ViPipe, 0x3808, 0x0a); + os04c10_write_register(ViPipe, 0x3809, 0x80); + os04c10_write_register(ViPipe, 0x380a, 0x05); + os04c10_write_register(ViPipe, 0x380b, 0xf0); + os04c10_write_register(ViPipe, 0x380c, 0x08); + os04c10_write_register(ViPipe, 0x380d, 0x5c); + os04c10_write_register(ViPipe, 0x380e, 0x06); + os04c10_write_register(ViPipe, 0x380f, 0x26); + os04c10_write_register(ViPipe, 0x3811, 0x08); + os04c10_write_register(ViPipe, 0x3813, 0x08); + os04c10_write_register(ViPipe, 0x3814, 0x01); + os04c10_write_register(ViPipe, 0x3815, 0x01); + os04c10_write_register(ViPipe, 0x3816, 0x01); + os04c10_write_register(ViPipe, 0x3817, 0x01); + os04c10_write_register(ViPipe, 0x3820, 0x88); + os04c10_write_register(ViPipe, 0x3821, 0x00); + os04c10_write_register(ViPipe, 0x3880, 0x25); + os04c10_write_register(ViPipe, 0x3882, 0x20); + os04c10_write_register(ViPipe, 0x3c91, 0x0b); + os04c10_write_register(ViPipe, 0x3c94, 0x45); + os04c10_write_register(ViPipe, 0x4000, 0xf3); + os04c10_write_register(ViPipe, 0x4001, 0x60); + os04c10_write_register(ViPipe, 0x4003, 0x80); + os04c10_write_register(ViPipe, 0x4008, 0x02); + os04c10_write_register(ViPipe, 0x4009, 0x0d); + os04c10_write_register(ViPipe, 0x4300, 0xff); + os04c10_write_register(ViPipe, 0x4302, 0x0f); + os04c10_write_register(ViPipe, 0x4305, 0x83); + os04c10_write_register(ViPipe, 0x4505, 0x84); + os04c10_write_register(ViPipe, 0x4809, 0x1e); + os04c10_write_register(ViPipe, 0x480a, 0x04); + os04c10_write_register(ViPipe, 0x4837, 0x23); + os04c10_write_register(ViPipe, 0x4c00, 0x08); + os04c10_write_register(ViPipe, 0x4c01, 0x08); + os04c10_write_register(ViPipe, 0x4c04, 0x00); + os04c10_write_register(ViPipe, 0x4c05, 0x00); + os04c10_write_register(ViPipe, 0x5000, 0xf9); + os04c10_write_register(ViPipe, 0x3624, 0x00); + os04c10_write_register(ViPipe, 0x3016, 0x32); + os04c10_write_register(ViPipe, 0x0306, 0x00); + os04c10_write_register(ViPipe, 0x4837, 0x12); + os04c10_write_register(ViPipe, 0x0305, 0x6a); + os04c10_write_register(ViPipe, 0x0325, 0x54); + os04c10_write_register(ViPipe, 0x3106, 0x25); + os04c10_default_reg_init(ViPipe); + + if (!g_au16Os04c10_UseHwSync[ViPipe]) { + /* freerun */ + os04c10_write_register(ViPipe, 0x3002, 0x21); + } else { + /* auto master */ +#if HW_SYNC_AUTO + os04c10_write_register(ViPipe, 0x3002, 0x22); // [1] vsync_oen, [0]: fsin_oen + os04c10_write_register(ViPipe, 0x3690, 0x00); // [4]: 1'b0, 1st set vsync pulse + os04c10_write_register(ViPipe, 0x383e, 0x00); // vscyn_rise_rcnt_pt[23:16] + os04c10_write_register(ViPipe, 0x3818, 0x00); // Slave vsync pulse position cs [15:8] + os04c10_write_register(ViPipe, 0x3819, 0x00); // Slave vsync pulse position cs [7:0], + // max is HTS/4 + os04c10_write_register(ViPipe, 0x381a, 0x00); // vscyn_rise_rcnt_pt[15:8] + os04c10_write_register(ViPipe, 0x381b, 0x00); // vscyn_rise_rcnt_pt[7:0], max: + // VTS-12 for AHBIN 720p, (VTS -12)*2 for + // other formats + os04c10_write_register(ViPipe, 0x3832, 0xf8); // default, 8'h08, [7:4] vsync pulse width + os04c10_write_register(ViPipe, 0x368a, 0x04); // GPIO enable +#else + /* manual master */ + os04c10_write_register(ViPipe, 0x3002, 0x22); // [1] vsync_oen, [0]: fsin_oen + os04c10_write_register(ViPipe, 0x3690, 0x00); // [4]: 1'b0, 1st set vsync pulse + os04c10_write_register(ViPipe, 0x383e, 0x00); // vscyn_rise_rcnt_pt[23:16] + os04c10_write_register(ViPipe, 0x3818, 0x00); // Slave vsync pulse position cs [15:8] + os04c10_write_register(ViPipe, 0x3819, 0x00); // Slave vsync pulse position cs [7:0], + // max is HTS/4 + os04c10_write_register(ViPipe, 0x381a, 0x00); // vscyn_rise_rcnt_pt[15:8] + os04c10_write_register(ViPipe, 0x381b, 0x18); // vscyn_rise_rcnt_pt[7:0], max: + // VTS-12 for AHBIN 720p, (VTS -12)*2 for + // other formats + os04c10_write_register(ViPipe, 0x3832, 0xf8); // default, 8'h08, [7:4] vsync pulse width + os04c10_write_register(ViPipe, 0x368a, 0x04); // GPIO enable +#endif + } + os04c10_write_register(ViPipe, 0x0100, 0x01); + + usleep(50*1000); + + printf("ViPipe:%d,===OS04C10 1520P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void os04c10_linear_1440p30_init(VI_PIPE ViPipe) +{ + os04c10_write_register(ViPipe, 0x0100, 0x00); + os04c10_write_register(ViPipe, 0x0103, 0x01); + os04c10_write_register(ViPipe, 0x0301, 0xe4); + os04c10_write_register(ViPipe, 0x0303, 0x01); + os04c10_write_register(ViPipe, 0x0305, 0x6e); + os04c10_write_register(ViPipe, 0x0306, 0x01); + os04c10_write_register(ViPipe, 0x0307, 0x17); + os04c10_write_register(ViPipe, 0x0323, 0x04); + os04c10_write_register(ViPipe, 0x0324, 0x01); + os04c10_write_register(ViPipe, 0x0325, 0x62); + os04c10_write_register(ViPipe, 0x3012, 0x06); + os04c10_write_register(ViPipe, 0x3013, 0x02); + os04c10_write_register(ViPipe, 0x3016, 0x72); + os04c10_write_register(ViPipe, 0x3021, 0x03); + os04c10_write_register(ViPipe, 0x3106, 0x21); + os04c10_write_register(ViPipe, 0x3107, 0xa1); + os04c10_write_register(ViPipe, 0x3500, 0x00); + os04c10_write_register(ViPipe, 0x3501, 0x06); + os04c10_write_register(ViPipe, 0x3502, 0x1e); + os04c10_write_register(ViPipe, 0x3503, 0x88); + os04c10_write_register(ViPipe, 0x3508, 0x00); + os04c10_write_register(ViPipe, 0x3509, 0x80); + os04c10_write_register(ViPipe, 0x350a, 0x04); + os04c10_write_register(ViPipe, 0x350b, 0x00); + os04c10_write_register(ViPipe, 0x350c, 0x00); + os04c10_write_register(ViPipe, 0x350d, 0x80); + os04c10_write_register(ViPipe, 0x350e, 0x04); + os04c10_write_register(ViPipe, 0x350f, 0x00); + os04c10_write_register(ViPipe, 0x3510, 0x00); + os04c10_write_register(ViPipe, 0x3511, 0x00); + os04c10_write_register(ViPipe, 0x3512, 0x20); + os04c10_write_register(ViPipe, 0x3624, 0x02); + os04c10_write_register(ViPipe, 0x3625, 0x4c); + os04c10_write_register(ViPipe, 0x3660, 0x00); + os04c10_write_register(ViPipe, 0x3666, 0xa5); + os04c10_write_register(ViPipe, 0x3667, 0xa5); + os04c10_write_register(ViPipe, 0x366a, 0x60); + os04c10_write_register(ViPipe, 0x3673, 0x0d); + os04c10_write_register(ViPipe, 0x3672, 0x0d); + os04c10_write_register(ViPipe, 0x3671, 0x0d); + os04c10_write_register(ViPipe, 0x3670, 0x0d); + os04c10_write_register(ViPipe, 0x3685, 0x00); + os04c10_write_register(ViPipe, 0x3694, 0x0d); + os04c10_write_register(ViPipe, 0x3693, 0x0d); + os04c10_write_register(ViPipe, 0x3692, 0x0d); + os04c10_write_register(ViPipe, 0x3691, 0x0d); + os04c10_write_register(ViPipe, 0x3696, 0x4c); + os04c10_write_register(ViPipe, 0x3697, 0x4c); + os04c10_write_register(ViPipe, 0x3698, 0x40); + os04c10_write_register(ViPipe, 0x3699, 0x80); + os04c10_write_register(ViPipe, 0x369a, 0x18); + os04c10_write_register(ViPipe, 0x369b, 0x1f); + os04c10_write_register(ViPipe, 0x369c, 0x14); + os04c10_write_register(ViPipe, 0x369d, 0x80); + os04c10_write_register(ViPipe, 0x369e, 0x40); + os04c10_write_register(ViPipe, 0x369f, 0x21); + os04c10_write_register(ViPipe, 0x36a0, 0x12); + os04c10_write_register(ViPipe, 0x36a1, 0x5d); + os04c10_write_register(ViPipe, 0x36a2, 0x66); + os04c10_write_register(ViPipe, 0x370a, 0x02); + os04c10_write_register(ViPipe, 0x370e, 0x0c); + os04c10_write_register(ViPipe, 0x3710, 0x00); + os04c10_write_register(ViPipe, 0x3713, 0x00); + os04c10_write_register(ViPipe, 0x3725, 0x02); + os04c10_write_register(ViPipe, 0x372a, 0x03); + os04c10_write_register(ViPipe, 0x3738, 0xce); + os04c10_write_register(ViPipe, 0x3739, 0x10); + os04c10_write_register(ViPipe, 0x3748, 0x02); + os04c10_write_register(ViPipe, 0x374a, 0x02); + os04c10_write_register(ViPipe, 0x374c, 0x02); + os04c10_write_register(ViPipe, 0x374e, 0x02); + os04c10_write_register(ViPipe, 0x3756, 0x00); + os04c10_write_register(ViPipe, 0x3757, 0x0e); + os04c10_write_register(ViPipe, 0x3767, 0x00); + os04c10_write_register(ViPipe, 0x3771, 0x00); + os04c10_write_register(ViPipe, 0x377b, 0x20); + os04c10_write_register(ViPipe, 0x377c, 0x00); + os04c10_write_register(ViPipe, 0x377d, 0x0c); + os04c10_write_register(ViPipe, 0x3781, 0x03); + os04c10_write_register(ViPipe, 0x3782, 0x00); + os04c10_write_register(ViPipe, 0x3789, 0x14); + os04c10_write_register(ViPipe, 0x3795, 0x02); + os04c10_write_register(ViPipe, 0x379c, 0x00); + os04c10_write_register(ViPipe, 0x379d, 0x00); + os04c10_write_register(ViPipe, 0x37b8, 0x04); + os04c10_write_register(ViPipe, 0x37ba, 0x03); + os04c10_write_register(ViPipe, 0x37bb, 0x00); + os04c10_write_register(ViPipe, 0x37bc, 0x04); + os04c10_write_register(ViPipe, 0x37be, 0x08); + os04c10_write_register(ViPipe, 0x37c4, 0x11); + os04c10_write_register(ViPipe, 0x37c5, 0x80); + os04c10_write_register(ViPipe, 0x37c6, 0x14); + os04c10_write_register(ViPipe, 0x37c7, 0x08); + os04c10_write_register(ViPipe, 0x37da, 0x11); + os04c10_write_register(ViPipe, 0x381f, 0x08); + os04c10_write_register(ViPipe, 0x3829, 0x03); + os04c10_write_register(ViPipe, 0x3832, 0x00); + os04c10_write_register(ViPipe, 0x3881, 0x00); + os04c10_write_register(ViPipe, 0x3888, 0x04); + os04c10_write_register(ViPipe, 0x388b, 0x00); + os04c10_write_register(ViPipe, 0x3c80, 0x10); + os04c10_write_register(ViPipe, 0x3c86, 0x00); + os04c10_write_register(ViPipe, 0x3c9f, 0x01); + os04c10_write_register(ViPipe, 0x3d85, 0x1b); + os04c10_write_register(ViPipe, 0x3d8c, 0x71); + os04c10_write_register(ViPipe, 0x3d8d, 0xe2); + os04c10_write_register(ViPipe, 0x3f00, 0x0b); + os04c10_write_register(ViPipe, 0x3f06, 0x04); + os04c10_write_register(ViPipe, 0x400a, 0x01); + os04c10_write_register(ViPipe, 0x400b, 0x50); + os04c10_write_register(ViPipe, 0x400e, 0x08); + os04c10_write_register(ViPipe, 0x4040, 0x00); + os04c10_write_register(ViPipe, 0x4041, 0x07); + os04c10_write_register(ViPipe, 0x4043, 0x7e); + os04c10_write_register(ViPipe, 0x4045, 0x7e); + os04c10_write_register(ViPipe, 0x4047, 0x7e); + os04c10_write_register(ViPipe, 0x4049, 0x7e); + os04c10_write_register(ViPipe, 0x4090, 0x04); + os04c10_write_register(ViPipe, 0x40b0, 0x00); + os04c10_write_register(ViPipe, 0x40b1, 0x00); + os04c10_write_register(ViPipe, 0x40b2, 0x00); + os04c10_write_register(ViPipe, 0x40b3, 0x00); + os04c10_write_register(ViPipe, 0x40b4, 0x00); + os04c10_write_register(ViPipe, 0x40b5, 0x00); + os04c10_write_register(ViPipe, 0x40b7, 0x00); + os04c10_write_register(ViPipe, 0x40b8, 0x00); + os04c10_write_register(ViPipe, 0x40b9, 0x00); + os04c10_write_register(ViPipe, 0x40ba, 0x00); + os04c10_write_register(ViPipe, 0x4301, 0x00); + os04c10_write_register(ViPipe, 0x4303, 0x00); + os04c10_write_register(ViPipe, 0x4502, 0x04); + os04c10_write_register(ViPipe, 0x4503, 0x00); + os04c10_write_register(ViPipe, 0x4504, 0x06); + os04c10_write_register(ViPipe, 0x4506, 0x00); + os04c10_write_register(ViPipe, 0x4507, 0x64); + os04c10_write_register(ViPipe, 0x4803, 0x00); + os04c10_write_register(ViPipe, 0x480c, 0x32); + os04c10_write_register(ViPipe, 0x480e, 0x00); + os04c10_write_register(ViPipe, 0x4813, 0x00); + os04c10_write_register(ViPipe, 0x4819, 0x70); + os04c10_write_register(ViPipe, 0x481f, 0x30); + os04c10_write_register(ViPipe, 0x4823, 0x3f); + os04c10_write_register(ViPipe, 0x4825, 0x30); + os04c10_write_register(ViPipe, 0x4833, 0x10); + os04c10_write_register(ViPipe, 0x484b, 0x07); + os04c10_write_register(ViPipe, 0x488b, 0x00); + os04c10_write_register(ViPipe, 0x4d00, 0x04); + os04c10_write_register(ViPipe, 0x4d01, 0xad); + os04c10_write_register(ViPipe, 0x4d02, 0xbc); + os04c10_write_register(ViPipe, 0x4d03, 0xa1); + os04c10_write_register(ViPipe, 0x4d04, 0x1f); + os04c10_write_register(ViPipe, 0x4d05, 0x4c); + os04c10_write_register(ViPipe, 0x4d0b, 0x01); + os04c10_write_register(ViPipe, 0x4e00, 0x2a); + os04c10_write_register(ViPipe, 0x4e0d, 0x00); + os04c10_write_register(ViPipe, 0x5001, 0x09); + os04c10_write_register(ViPipe, 0x5004, 0x00); + os04c10_write_register(ViPipe, 0x5080, 0x04); + os04c10_write_register(ViPipe, 0x5036, 0x00); + os04c10_write_register(ViPipe, 0x5180, 0x70); + os04c10_write_register(ViPipe, 0x5181, 0x10); + os04c10_write_register(ViPipe, 0x520a, 0x03); + os04c10_write_register(ViPipe, 0x520b, 0x06); + os04c10_write_register(ViPipe, 0x520c, 0x0c); + os04c10_write_register(ViPipe, 0x580b, 0x0f); + os04c10_write_register(ViPipe, 0x580d, 0x00); + os04c10_write_register(ViPipe, 0x580f, 0x00); + os04c10_write_register(ViPipe, 0x5820, 0x00); + os04c10_write_register(ViPipe, 0x5821, 0x00); + os04c10_write_register(ViPipe, 0x301c, 0xf8); + os04c10_write_register(ViPipe, 0x301e, 0xb4); + os04c10_write_register(ViPipe, 0x301f, 0xd0); + os04c10_write_register(ViPipe, 0x3022, 0x61); + os04c10_write_register(ViPipe, 0x3109, 0xe7); + os04c10_write_register(ViPipe, 0x3600, 0x00); + os04c10_write_register(ViPipe, 0x3610, 0x95); + os04c10_write_register(ViPipe, 0x3611, 0x85); + os04c10_write_register(ViPipe, 0x3613, 0x3a); + os04c10_write_register(ViPipe, 0x3615, 0x60); + os04c10_write_register(ViPipe, 0x3621, 0xb0); + os04c10_write_register(ViPipe, 0x3620, 0x0c); + os04c10_write_register(ViPipe, 0x3629, 0x00); + os04c10_write_register(ViPipe, 0x3661, 0x04); + os04c10_write_register(ViPipe, 0x3662, 0x10); + os04c10_write_register(ViPipe, 0x3664, 0x70); + os04c10_write_register(ViPipe, 0x3665, 0x00); + os04c10_write_register(ViPipe, 0x3681, 0xa6); + os04c10_write_register(ViPipe, 0x3682, 0x53); + os04c10_write_register(ViPipe, 0x3683, 0x2a); + os04c10_write_register(ViPipe, 0x3684, 0x15); + os04c10_write_register(ViPipe, 0x3700, 0x2a); + os04c10_write_register(ViPipe, 0x3701, 0x12); + os04c10_write_register(ViPipe, 0x3703, 0x28); + os04c10_write_register(ViPipe, 0x3704, 0x0e); + os04c10_write_register(ViPipe, 0x3706, 0x9d); + os04c10_write_register(ViPipe, 0x3709, 0x4a); + os04c10_write_register(ViPipe, 0x370b, 0x48); + os04c10_write_register(ViPipe, 0x370c, 0x01); + os04c10_write_register(ViPipe, 0x370f, 0x04); + os04c10_write_register(ViPipe, 0x3714, 0x24); + os04c10_write_register(ViPipe, 0x3716, 0x24); + os04c10_write_register(ViPipe, 0x3719, 0x11); + os04c10_write_register(ViPipe, 0x371a, 0x1e); + os04c10_write_register(ViPipe, 0x3720, 0x00); + os04c10_write_register(ViPipe, 0x3724, 0x13); + os04c10_write_register(ViPipe, 0x373f, 0xb0); + os04c10_write_register(ViPipe, 0x3741, 0x9d); + os04c10_write_register(ViPipe, 0x3743, 0x9d); + os04c10_write_register(ViPipe, 0x3745, 0x9d); + os04c10_write_register(ViPipe, 0x3747, 0x9d); + os04c10_write_register(ViPipe, 0x3749, 0x48); + os04c10_write_register(ViPipe, 0x374b, 0x48); + os04c10_write_register(ViPipe, 0x374d, 0x48); + os04c10_write_register(ViPipe, 0x374f, 0x48); + os04c10_write_register(ViPipe, 0x3755, 0x10); + os04c10_write_register(ViPipe, 0x376c, 0x00); + os04c10_write_register(ViPipe, 0x378d, 0x3c); + os04c10_write_register(ViPipe, 0x3790, 0x01); + os04c10_write_register(ViPipe, 0x3791, 0x01); + os04c10_write_register(ViPipe, 0x3798, 0x40); + os04c10_write_register(ViPipe, 0x379e, 0x00); + os04c10_write_register(ViPipe, 0x379f, 0x04); + os04c10_write_register(ViPipe, 0x37a1, 0x10); + os04c10_write_register(ViPipe, 0x37a2, 0x1e); + os04c10_write_register(ViPipe, 0x37a8, 0x10); + os04c10_write_register(ViPipe, 0x37a9, 0x1e); + os04c10_write_register(ViPipe, 0x37ac, 0xa0); + os04c10_write_register(ViPipe, 0x37b9, 0x01); + os04c10_write_register(ViPipe, 0x37bd, 0x01); + os04c10_write_register(ViPipe, 0x37bf, 0x26); + os04c10_write_register(ViPipe, 0x37c0, 0x11); + os04c10_write_register(ViPipe, 0x37c2, 0x04); + os04c10_write_register(ViPipe, 0x37cd, 0x19); + os04c10_write_register(ViPipe, 0x37d8, 0x02); + os04c10_write_register(ViPipe, 0x37d9, 0x08); + os04c10_write_register(ViPipe, 0x37e5, 0x02); + os04c10_write_register(ViPipe, 0x3800, 0x00); + os04c10_write_register(ViPipe, 0x3801, 0x40); + os04c10_write_register(ViPipe, 0x3802, 0x00); + os04c10_write_register(ViPipe, 0x3803, 0x28); + os04c10_write_register(ViPipe, 0x3804, 0x0a); + os04c10_write_register(ViPipe, 0x3805, 0x4f); + os04c10_write_register(ViPipe, 0x3806, 0x05); + os04c10_write_register(ViPipe, 0x3807, 0xd7); + os04c10_write_register(ViPipe, 0x3808, 0x0a); + os04c10_write_register(ViPipe, 0x3809, 0x00); + os04c10_write_register(ViPipe, 0x380a, 0x05); + os04c10_write_register(ViPipe, 0x380b, 0xa0); + os04c10_write_register(ViPipe, 0x380c, 0x08); + os04c10_write_register(ViPipe, 0x380d, 0x5c); + os04c10_write_register(ViPipe, 0x380e, 0x06); + os04c10_write_register(ViPipe, 0x380f, 0x26); + os04c10_write_register(ViPipe, 0x3811, 0x08); + os04c10_write_register(ViPipe, 0x3813, 0x08); + os04c10_write_register(ViPipe, 0x3814, 0x01); + os04c10_write_register(ViPipe, 0x3815, 0x01); + os04c10_write_register(ViPipe, 0x3816, 0x01); + os04c10_write_register(ViPipe, 0x3817, 0x01); + os04c10_write_register(ViPipe, 0x3820, 0x88); + os04c10_write_register(ViPipe, 0x3821, 0x00); + os04c10_write_register(ViPipe, 0x3880, 0x25); + os04c10_write_register(ViPipe, 0x3882, 0x20); + os04c10_write_register(ViPipe, 0x3c91, 0x0b); + os04c10_write_register(ViPipe, 0x3c94, 0x45); + os04c10_write_register(ViPipe, 0x4000, 0xf3); + os04c10_write_register(ViPipe, 0x4001, 0x60); + os04c10_write_register(ViPipe, 0x4003, 0x80); + os04c10_write_register(ViPipe, 0x4008, 0x02); + os04c10_write_register(ViPipe, 0x4009, 0x0d); + os04c10_write_register(ViPipe, 0x4300, 0xff); + os04c10_write_register(ViPipe, 0x4302, 0x0f); + os04c10_write_register(ViPipe, 0x4305, 0x83); + os04c10_write_register(ViPipe, 0x4505, 0x84); + os04c10_write_register(ViPipe, 0x4809, 0x1e); + os04c10_write_register(ViPipe, 0x480a, 0x04); + os04c10_write_register(ViPipe, 0x4837, 0x23); + os04c10_write_register(ViPipe, 0x4c00, 0x08); + os04c10_write_register(ViPipe, 0x4c01, 0x08); + os04c10_write_register(ViPipe, 0x4c04, 0x00); + os04c10_write_register(ViPipe, 0x4c05, 0x00); + os04c10_write_register(ViPipe, 0x5000, 0xe9); + os04c10_write_register(ViPipe, 0x3624, 0x00); + os04c10_write_register(ViPipe, 0x3016, 0x32); + os04c10_write_register(ViPipe, 0x0306, 0x00); + os04c10_write_register(ViPipe, 0x4837, 0x12); + os04c10_write_register(ViPipe, 0x0305, 0x6a); + os04c10_write_register(ViPipe, 0x0325, 0x54); + os04c10_write_register(ViPipe, 0x3106, 0x25); + os04c10_default_reg_init(ViPipe); + + if (!g_au16Os04c10_UseHwSync[ViPipe]) { + /* freerun */ + os04c10_write_register(ViPipe, 0x3002, 0x21); + } else { + /* auto master */ + os04c10_write_register(ViPipe, 0x3002, 0x23); // [1] vsync_oen, [0]: fsin_oen + os04c10_write_register(ViPipe, 0x3690, 0x00); // [4]: 1'b0, 1st set vsync pulse + os04c10_write_register(ViPipe, 0x383e, 0x00); // vscyn_rise_rcnt_pt[23:16] + os04c10_write_register(ViPipe, 0x3818, 0x00); // Slave vsync pulse position cs [15:8] + os04c10_write_register(ViPipe, 0x3819, 0x00); // Slave vsync pulse position cs [7:0], + // max is HTS/4 + os04c10_write_register(ViPipe, 0x381a, 0x00); // vscyn_rise_rcnt_pt[15:8] + os04c10_write_register(ViPipe, 0x381b, 0x18); // vscyn_rise_rcnt_pt[7:0], max: + // VTS-12 for AHBIN 720p, (VTS -12)*2 for + // other formats + os04c10_write_register(ViPipe, 0x3832, 0xf8); // default, 8'h08, [7:4] vsync pulse width + os04c10_write_register(ViPipe, 0x368a, 0x04); // GPIO enable + } + os04c10_write_register(ViPipe, 0x0100, 0x01); + + usleep(50*1000); + + printf("ViPipe:%d,===OS04C10 1440P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +static void os04c10_wdr_1520p30_2to1_init(VI_PIPE ViPipe) +{ + os04c10_write_register(ViPipe, 0x0100, 0x00); + os04c10_write_register(ViPipe, 0x0103, 0x01); + os04c10_write_register(ViPipe, 0x0301, 0x84); + os04c10_write_register(ViPipe, 0x0303, 0x01); + os04c10_write_register(ViPipe, 0x0305, 0x61); + os04c10_write_register(ViPipe, 0x0306, 0x01); + os04c10_write_register(ViPipe, 0x0307, 0x17); + os04c10_write_register(ViPipe, 0x0323, 0x04); + os04c10_write_register(ViPipe, 0x0324, 0x01); + os04c10_write_register(ViPipe, 0x0325, 0x7a); + os04c10_write_register(ViPipe, 0x3012, 0x06); + os04c10_write_register(ViPipe, 0x3013, 0x02); + os04c10_write_register(ViPipe, 0x3016, 0x72); + os04c10_write_register(ViPipe, 0x3021, 0x03); + os04c10_write_register(ViPipe, 0x3106, 0x21); + os04c10_write_register(ViPipe, 0x3107, 0xa1); + os04c10_write_register(ViPipe, 0x3500, 0x00); + os04c10_write_register(ViPipe, 0x3501, 0x03); + os04c10_write_register(ViPipe, 0x3502, 0x08); + os04c10_write_register(ViPipe, 0x3503, 0x88); + os04c10_write_register(ViPipe, 0x3508, 0x00); + os04c10_write_register(ViPipe, 0x3509, 0x80); + os04c10_write_register(ViPipe, 0x350a, 0x04); + os04c10_write_register(ViPipe, 0x350b, 0x00); + os04c10_write_register(ViPipe, 0x350c, 0x00); + os04c10_write_register(ViPipe, 0x350d, 0x80); + os04c10_write_register(ViPipe, 0x350e, 0x04); + os04c10_write_register(ViPipe, 0x350f, 0x00); + os04c10_write_register(ViPipe, 0x3510, 0x00); + os04c10_write_register(ViPipe, 0x3511, 0x01); + os04c10_write_register(ViPipe, 0x3512, 0x08); + os04c10_write_register(ViPipe, 0x3624, 0x02); + os04c10_write_register(ViPipe, 0x3625, 0x4c); + os04c10_write_register(ViPipe, 0x3660, 0x04); + os04c10_write_register(ViPipe, 0x3666, 0xa5); + os04c10_write_register(ViPipe, 0x3667, 0xa5); + os04c10_write_register(ViPipe, 0x366a, 0x54); + os04c10_write_register(ViPipe, 0x3673, 0x0d); + os04c10_write_register(ViPipe, 0x3672, 0x0d); + os04c10_write_register(ViPipe, 0x3671, 0x0d); + os04c10_write_register(ViPipe, 0x3670, 0x0d); + os04c10_write_register(ViPipe, 0x3685, 0x00); + os04c10_write_register(ViPipe, 0x3694, 0x0d); + os04c10_write_register(ViPipe, 0x3693, 0x0d); + os04c10_write_register(ViPipe, 0x3692, 0x0d); + os04c10_write_register(ViPipe, 0x3691, 0x0d); + os04c10_write_register(ViPipe, 0x3696, 0x4c); + os04c10_write_register(ViPipe, 0x3697, 0x4c); + os04c10_write_register(ViPipe, 0x3698, 0x40); + os04c10_write_register(ViPipe, 0x3699, 0x80); + os04c10_write_register(ViPipe, 0x369a, 0x18); + os04c10_write_register(ViPipe, 0x369b, 0x1f); + os04c10_write_register(ViPipe, 0x369c, 0x14); + os04c10_write_register(ViPipe, 0x369d, 0x80); + os04c10_write_register(ViPipe, 0x369e, 0x40); + os04c10_write_register(ViPipe, 0x369f, 0x21); + os04c10_write_register(ViPipe, 0x36a0, 0x12); + os04c10_write_register(ViPipe, 0x36a1, 0x5d); + os04c10_write_register(ViPipe, 0x36a2, 0x66); + os04c10_write_register(ViPipe, 0x370a, 0x00); + os04c10_write_register(ViPipe, 0x370e, 0x0c); + os04c10_write_register(ViPipe, 0x3710, 0x00); + os04c10_write_register(ViPipe, 0x3713, 0x00); + os04c10_write_register(ViPipe, 0x3725, 0x02); + os04c10_write_register(ViPipe, 0x372a, 0x03); + os04c10_write_register(ViPipe, 0x3738, 0xce); + os04c10_write_register(ViPipe, 0x3748, 0x00); + os04c10_write_register(ViPipe, 0x374a, 0x00); + os04c10_write_register(ViPipe, 0x374c, 0x00); + os04c10_write_register(ViPipe, 0x374e, 0x00); + os04c10_write_register(ViPipe, 0x3756, 0x00); + os04c10_write_register(ViPipe, 0x3757, 0x00); + os04c10_write_register(ViPipe, 0x3767, 0x00); + os04c10_write_register(ViPipe, 0x3771, 0x00); + os04c10_write_register(ViPipe, 0x377b, 0x28); + os04c10_write_register(ViPipe, 0x377c, 0x00); + os04c10_write_register(ViPipe, 0x377d, 0x0c); + os04c10_write_register(ViPipe, 0x3781, 0x03); + os04c10_write_register(ViPipe, 0x3782, 0x00); + os04c10_write_register(ViPipe, 0x3789, 0x14); + os04c10_write_register(ViPipe, 0x3795, 0x02); + os04c10_write_register(ViPipe, 0x379c, 0x00); + os04c10_write_register(ViPipe, 0x379d, 0x00); + os04c10_write_register(ViPipe, 0x37b8, 0x04); + os04c10_write_register(ViPipe, 0x37ba, 0x03); + os04c10_write_register(ViPipe, 0x37bb, 0x00); + os04c10_write_register(ViPipe, 0x37bc, 0x04); + os04c10_write_register(ViPipe, 0x37be, 0x08); + os04c10_write_register(ViPipe, 0x37c4, 0x11); + os04c10_write_register(ViPipe, 0x37c5, 0x80); + os04c10_write_register(ViPipe, 0x37c6, 0x14); + os04c10_write_register(ViPipe, 0x37c7, 0x08); + os04c10_write_register(ViPipe, 0x37da, 0x11); + os04c10_write_register(ViPipe, 0x381f, 0x08); + os04c10_write_register(ViPipe, 0x3829, 0x03); + os04c10_write_register(ViPipe, 0x3881, 0x00); + os04c10_write_register(ViPipe, 0x3888, 0x04); + os04c10_write_register(ViPipe, 0x388b, 0x00); + os04c10_write_register(ViPipe, 0x3c80, 0x10); + os04c10_write_register(ViPipe, 0x3c86, 0x00); + os04c10_write_register(ViPipe, 0x3c8c, 0x20); + os04c10_write_register(ViPipe, 0x3c9f, 0x01); + os04c10_write_register(ViPipe, 0x3d85, 0x1b); + os04c10_write_register(ViPipe, 0x3d8c, 0x71); + os04c10_write_register(ViPipe, 0x3d8d, 0xe2); + os04c10_write_register(ViPipe, 0x3f00, 0x0b); + os04c10_write_register(ViPipe, 0x3f06, 0x04); + os04c10_write_register(ViPipe, 0x400a, 0x01); + os04c10_write_register(ViPipe, 0x400b, 0x50); + os04c10_write_register(ViPipe, 0x400e, 0x08); + os04c10_write_register(ViPipe, 0x4043, 0x7e); + os04c10_write_register(ViPipe, 0x4045, 0x7e); + os04c10_write_register(ViPipe, 0x4047, 0x7e); + os04c10_write_register(ViPipe, 0x4049, 0x7e); + os04c10_write_register(ViPipe, 0x4090, 0x14); + os04c10_write_register(ViPipe, 0x40b0, 0x00); + os04c10_write_register(ViPipe, 0x40b1, 0x00); + os04c10_write_register(ViPipe, 0x40b2, 0x00); + os04c10_write_register(ViPipe, 0x40b3, 0x00); + os04c10_write_register(ViPipe, 0x40b4, 0x00); + os04c10_write_register(ViPipe, 0x40b5, 0x00); + os04c10_write_register(ViPipe, 0x40b7, 0x00); + os04c10_write_register(ViPipe, 0x40b8, 0x00); + os04c10_write_register(ViPipe, 0x40b9, 0x00); + os04c10_write_register(ViPipe, 0x40ba, 0x01); + os04c10_write_register(ViPipe, 0x4301, 0x00); + os04c10_write_register(ViPipe, 0x4303, 0x00); + os04c10_write_register(ViPipe, 0x4502, 0x04); + os04c10_write_register(ViPipe, 0x4503, 0x00); + os04c10_write_register(ViPipe, 0x4504, 0x06); + os04c10_write_register(ViPipe, 0x4506, 0x00); + os04c10_write_register(ViPipe, 0x4507, 0x47); + os04c10_write_register(ViPipe, 0x4803, 0x00); + os04c10_write_register(ViPipe, 0x480c, 0x32); + os04c10_write_register(ViPipe, 0x480e, 0x04); + os04c10_write_register(ViPipe, 0x4813, 0xe4); + os04c10_write_register(ViPipe, 0x4819, 0x70); + os04c10_write_register(ViPipe, 0x481f, 0x30); + os04c10_write_register(ViPipe, 0x4823, 0x3f); + os04c10_write_register(ViPipe, 0x4825, 0x30); + os04c10_write_register(ViPipe, 0x4833, 0x10); + os04c10_write_register(ViPipe, 0x484b, 0x27); + os04c10_write_register(ViPipe, 0x488b, 0x00); + os04c10_write_register(ViPipe, 0x4d00, 0x04); + os04c10_write_register(ViPipe, 0x4d01, 0xad); + os04c10_write_register(ViPipe, 0x4d02, 0xbc); + os04c10_write_register(ViPipe, 0x4d03, 0xa1); + os04c10_write_register(ViPipe, 0x4d04, 0x1f); + os04c10_write_register(ViPipe, 0x4d05, 0x4c); + os04c10_write_register(ViPipe, 0x4d0b, 0x01); + os04c10_write_register(ViPipe, 0x4e00, 0x2a); + os04c10_write_register(ViPipe, 0x4e0d, 0x00); + os04c10_write_register(ViPipe, 0x5001, 0x09); + os04c10_write_register(ViPipe, 0x5004, 0x00); + os04c10_write_register(ViPipe, 0x5080, 0x04); + os04c10_write_register(ViPipe, 0x5036, 0x80); + os04c10_write_register(ViPipe, 0x5180, 0x70); + os04c10_write_register(ViPipe, 0x5181, 0x10); + os04c10_write_register(ViPipe, 0x520a, 0x03); + os04c10_write_register(ViPipe, 0x520b, 0x06); + os04c10_write_register(ViPipe, 0x520c, 0x0c); + os04c10_write_register(ViPipe, 0x580b, 0x0f); + os04c10_write_register(ViPipe, 0x580d, 0x00); + os04c10_write_register(ViPipe, 0x580f, 0x00); + os04c10_write_register(ViPipe, 0x5820, 0x00); + os04c10_write_register(ViPipe, 0x5821, 0x00); + os04c10_write_register(ViPipe, 0x301c, 0xf8); + os04c10_write_register(ViPipe, 0x301e, 0xb4); + os04c10_write_register(ViPipe, 0x301f, 0xf0); + os04c10_write_register(ViPipe, 0x3022, 0x01); + os04c10_write_register(ViPipe, 0x3109, 0xe7); + os04c10_write_register(ViPipe, 0x3600, 0x00); + os04c10_write_register(ViPipe, 0x3610, 0x75); + os04c10_write_register(ViPipe, 0x3611, 0x85); + os04c10_write_register(ViPipe, 0x3613, 0x3a); + os04c10_write_register(ViPipe, 0x3615, 0x60); + os04c10_write_register(ViPipe, 0x3621, 0x90); + os04c10_write_register(ViPipe, 0x3620, 0x0c); + os04c10_write_register(ViPipe, 0x3629, 0x00); + os04c10_write_register(ViPipe, 0x3661, 0x04); + os04c10_write_register(ViPipe, 0x3664, 0x70); + os04c10_write_register(ViPipe, 0x3665, 0x00); + os04c10_write_register(ViPipe, 0x3681, 0xa6); + os04c10_write_register(ViPipe, 0x3682, 0x53); + os04c10_write_register(ViPipe, 0x3683, 0x2a); + os04c10_write_register(ViPipe, 0x3684, 0x15); + os04c10_write_register(ViPipe, 0x3700, 0x2a); + os04c10_write_register(ViPipe, 0x3701, 0x12); + os04c10_write_register(ViPipe, 0x3703, 0x28); + os04c10_write_register(ViPipe, 0x3704, 0x0e); + os04c10_write_register(ViPipe, 0x3706, 0x4a); + os04c10_write_register(ViPipe, 0x3709, 0x4a); + os04c10_write_register(ViPipe, 0x370b, 0xa2); + os04c10_write_register(ViPipe, 0x370c, 0x01); + os04c10_write_register(ViPipe, 0x370f, 0x04); + os04c10_write_register(ViPipe, 0x3714, 0x24); + os04c10_write_register(ViPipe, 0x3716, 0x24); + os04c10_write_register(ViPipe, 0x3719, 0x11); + os04c10_write_register(ViPipe, 0x371a, 0x1e); + os04c10_write_register(ViPipe, 0x3720, 0x00); + os04c10_write_register(ViPipe, 0x3724, 0x13); + os04c10_write_register(ViPipe, 0x373f, 0xb0); + os04c10_write_register(ViPipe, 0x3741, 0x4a); + os04c10_write_register(ViPipe, 0x3743, 0x4a); + os04c10_write_register(ViPipe, 0x3745, 0x4a); + os04c10_write_register(ViPipe, 0x3747, 0x4a); + os04c10_write_register(ViPipe, 0x3749, 0xa2); + os04c10_write_register(ViPipe, 0x374b, 0xa2); + os04c10_write_register(ViPipe, 0x374d, 0xa2); + os04c10_write_register(ViPipe, 0x374f, 0xa2); + os04c10_write_register(ViPipe, 0x3755, 0x10); + os04c10_write_register(ViPipe, 0x376c, 0x00); + os04c10_write_register(ViPipe, 0x378d, 0x30); + os04c10_write_register(ViPipe, 0x3790, 0x4a); + os04c10_write_register(ViPipe, 0x3791, 0xa2); + os04c10_write_register(ViPipe, 0x3798, 0x40); + os04c10_write_register(ViPipe, 0x379e, 0x00); + os04c10_write_register(ViPipe, 0x379f, 0x04); + os04c10_write_register(ViPipe, 0x37a1, 0x10); + os04c10_write_register(ViPipe, 0x37a2, 0x1e); + os04c10_write_register(ViPipe, 0x37a8, 0x10); + os04c10_write_register(ViPipe, 0x37a9, 0x1e); + os04c10_write_register(ViPipe, 0x37ac, 0xa0); + os04c10_write_register(ViPipe, 0x37b9, 0x01); + os04c10_write_register(ViPipe, 0x37bd, 0x01); + os04c10_write_register(ViPipe, 0x37bf, 0x26); + os04c10_write_register(ViPipe, 0x37c0, 0x11); + os04c10_write_register(ViPipe, 0x37c2, 0x04); + os04c10_write_register(ViPipe, 0x37cd, 0x19); + os04c10_write_register(ViPipe, 0x37e0, 0x08); + os04c10_write_register(ViPipe, 0x37e6, 0x04); + os04c10_write_register(ViPipe, 0x37e5, 0x02); + os04c10_write_register(ViPipe, 0x37e1, 0x0c); + os04c10_write_register(ViPipe, 0x3737, 0x04); + os04c10_write_register(ViPipe, 0x37d8, 0x02); + os04c10_write_register(ViPipe, 0x37e2, 0x10); + os04c10_write_register(ViPipe, 0x3739, 0x10); + os04c10_write_register(ViPipe, 0x3662, 0x10); + os04c10_write_register(ViPipe, 0x37e4, 0x20); + os04c10_write_register(ViPipe, 0x37e3, 0x08); + os04c10_write_register(ViPipe, 0x37d9, 0x08); + os04c10_write_register(ViPipe, 0x4040, 0x00); + os04c10_write_register(ViPipe, 0x4041, 0x07); + os04c10_write_register(ViPipe, 0x4008, 0x02); + os04c10_write_register(ViPipe, 0x4009, 0x0d); + os04c10_write_register(ViPipe, 0x3800, 0x00); + os04c10_write_register(ViPipe, 0x3801, 0x00); + os04c10_write_register(ViPipe, 0x3802, 0x00); + os04c10_write_register(ViPipe, 0x3803, 0x00); + os04c10_write_register(ViPipe, 0x3804, 0x0a); + os04c10_write_register(ViPipe, 0x3805, 0x8f); + os04c10_write_register(ViPipe, 0x3806, 0x05); + os04c10_write_register(ViPipe, 0x3807, 0xff); + os04c10_write_register(ViPipe, 0x3808, 0x0a); + os04c10_write_register(ViPipe, 0x3809, 0x80); + os04c10_write_register(ViPipe, 0x380a, 0x05); + os04c10_write_register(ViPipe, 0x380b, 0xf0); + os04c10_write_register(ViPipe, 0x380c, 0x04); + os04c10_write_register(ViPipe, 0x380d, 0x2e); + os04c10_write_register(ViPipe, 0x380e, 0x06); + os04c10_write_register(ViPipe, 0x380f, 0x92); + os04c10_write_register(ViPipe, 0x3811, 0x08); + os04c10_write_register(ViPipe, 0x3813, 0x08); + os04c10_write_register(ViPipe, 0x3814, 0x01); + os04c10_write_register(ViPipe, 0x3815, 0x01); + os04c10_write_register(ViPipe, 0x3816, 0x01); + os04c10_write_register(ViPipe, 0x3817, 0x01); + os04c10_write_register(ViPipe, 0x3820, 0x88); + os04c10_write_register(ViPipe, 0x3821, 0x04); + os04c10_write_register(ViPipe, 0x3880, 0x25); + os04c10_write_register(ViPipe, 0x3882, 0x20); + os04c10_write_register(ViPipe, 0x3c91, 0x0b); + os04c10_write_register(ViPipe, 0x3c94, 0x45); + os04c10_write_register(ViPipe, 0x4000, 0xf3); + os04c10_write_register(ViPipe, 0x4001, 0x60); + os04c10_write_register(ViPipe, 0x4003, 0x40); + os04c10_write_register(ViPipe, 0x4300, 0xff); + os04c10_write_register(ViPipe, 0x4302, 0x0f); + os04c10_write_register(ViPipe, 0x4305, 0x83); + os04c10_write_register(ViPipe, 0x4505, 0x84); + os04c10_write_register(ViPipe, 0x4809, 0x0e); + os04c10_write_register(ViPipe, 0x480a, 0x04); + os04c10_write_register(ViPipe, 0x4837, 0x14); + os04c10_write_register(ViPipe, 0x4c00, 0x08); + os04c10_write_register(ViPipe, 0x4c01, 0x08); + os04c10_write_register(ViPipe, 0x4c04, 0x00); + os04c10_write_register(ViPipe, 0x4c05, 0x00); + os04c10_write_register(ViPipe, 0x5000, 0xf9); + os04c10_write_register(ViPipe, 0x3624, 0x00); + os04c10_write_register(ViPipe, 0x3016, 0x32); + os04c10_write_register(ViPipe, 0x0306, 0x00); + os04c10_write_register(ViPipe, 0x4837, 0x0a); + os04c10_write_register(ViPipe, 0x0305, 0x5a); + os04c10_write_register(ViPipe, 0x0325, 0x6b); + os04c10_write_register(ViPipe, 0x3106, 0x25); + /* LCG-LCG */ + os04c10_write_register(ViPipe, 0x320d, 0x00); + os04c10_write_register(ViPipe, 0x3208, 0x00); + os04c10_write_register(ViPipe, 0x3698, 0x00); + os04c10_write_register(ViPipe, 0x3699, 0x80); + os04c10_write_register(ViPipe, 0x369a, 0x80); + os04c10_write_register(ViPipe, 0x369b, 0x1f); + os04c10_write_register(ViPipe, 0x369c, 0x1f); + os04c10_write_register(ViPipe, 0x369d, 0x80); + os04c10_write_register(ViPipe, 0x369e, 0x40); + os04c10_write_register(ViPipe, 0x369f, 0x21); + os04c10_write_register(ViPipe, 0x36a0, 0x12); + os04c10_write_register(ViPipe, 0x36a1, 0xdd); + os04c10_write_register(ViPipe, 0x370e, 0x00); + os04c10_write_register(ViPipe, 0x3713, 0x04); + os04c10_write_register(ViPipe, 0x379c, 0x00); + os04c10_write_register(ViPipe, 0x379d, 0x00); + os04c10_write_register(ViPipe, 0x37be, 0x26); + os04c10_write_register(ViPipe, 0x37c7, 0xa8); + os04c10_write_register(ViPipe, 0x3881, 0x00); + os04c10_write_register(ViPipe, 0x3681, 0x80); + os04c10_write_register(ViPipe, 0x3682, 0x40); + os04c10_write_register(ViPipe, 0x3683, 0x21); + os04c10_write_register(ViPipe, 0x3684, 0x12); + os04c10_write_register(ViPipe, 0x370f, 0x00); + os04c10_write_register(ViPipe, 0x379f, 0x04); + os04c10_write_register(ViPipe, 0x37ac, 0xa0); + os04c10_write_register(ViPipe, 0x37bf, 0x26); + os04c10_write_register(ViPipe, 0x3880, 0x00); + os04c10_write_register(ViPipe, 0x3208, 0x10); + os04c10_write_register(ViPipe, 0x320d, 0x00); + os04c10_write_register(ViPipe, 0x3208, 0xa0); + + os04c10_default_reg_init(ViPipe); + + if (!g_au16Os04c10_UseHwSync[ViPipe]) { + /* freerun */ + os04c10_write_register(ViPipe, 0x3002, 0x21); + } else { + /* auto master */ +#if HW_SYNC_AUTO + os04c10_write_register(ViPipe, 0x3002, 0x22); // [1] vsync_oen, [0]: fsin_oen + os04c10_write_register(ViPipe, 0x3690, 0x00); // [4]: 1'b0, 1st set vsync pulse + os04c10_write_register(ViPipe, 0x383e, 0x00); // vscyn_rise_rcnt_pt[23:16] + os04c10_write_register(ViPipe, 0x3818, 0x00); // Slave vsync pulse position cs [15:8] + os04c10_write_register(ViPipe, 0x3819, 0x00); // Slave vsync pulse position cs [7:0], + // max is HTS/4 + os04c10_write_register(ViPipe, 0x381a, 0x00); // vscyn_rise_rcnt_pt[15:8] + os04c10_write_register(ViPipe, 0x381b, 0x00); // vscyn_rise_rcnt_pt[7:0], max: + // VTS-12 for AHBIN 720p, (VTS -12)*2 for + // other formats + os04c10_write_register(ViPipe, 0x3832, 0xf8); // default, 8'h08, [7:4] vsync pulse width + os04c10_write_register(ViPipe, 0x368a, 0x04); // GPIO enable +#else + /* manual master */ + os04c10_write_register(ViPipe, 0x3002, 0x22); // [1] vsync_oen, [0]: fsin_oen + os04c10_write_register(ViPipe, 0x3690, 0x00); // [4]: 1'b0, 1st set vsync pulse + os04c10_write_register(ViPipe, 0x383e, 0x00); // vscyn_rise_rcnt_pt[23:16] + os04c10_write_register(ViPipe, 0x3818, 0x00); // Slave vsync pulse position cs [15:8] + os04c10_write_register(ViPipe, 0x3819, 0x00); // Slave vsync pulse position cs [7:0], + // max is HTS/4 + os04c10_write_register(ViPipe, 0x381a, 0x00); // vscyn_rise_rcnt_pt[15:8] + os04c10_write_register(ViPipe, 0x381b, 0x18); // vscyn_rise_rcnt_pt[7:0], max: + // VTS-12 for AHBIN 720p, (VTS -12)*2 for + // other formats + os04c10_write_register(ViPipe, 0x3832, 0xf8); // default, 8'h08, [7:4] vsync pulse width + os04c10_write_register(ViPipe, 0x368a, 0x04); // GPIO enable +#endif + } + + os04c10_write_register(ViPipe, 0x0100, 0x01); + + usleep(50*1000); + + printf("===Os04c10 sensor 1520P30fps 10bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} + +static void os04c10_wdr_1440p30_2to1_init(VI_PIPE ViPipe) +{ + os04c10_write_register(ViPipe, 0x0100, 0x00); + os04c10_write_register(ViPipe, 0x0103, 0x01); + os04c10_write_register(ViPipe, 0x0301, 0x84); + os04c10_write_register(ViPipe, 0x0303, 0x01); + os04c10_write_register(ViPipe, 0x0305, 0x61); + os04c10_write_register(ViPipe, 0x0306, 0x01); + os04c10_write_register(ViPipe, 0x0307, 0x17); + os04c10_write_register(ViPipe, 0x0323, 0x04); + os04c10_write_register(ViPipe, 0x0324, 0x01); + os04c10_write_register(ViPipe, 0x0325, 0x7a); + os04c10_write_register(ViPipe, 0x3012, 0x06); + os04c10_write_register(ViPipe, 0x3013, 0x02); + os04c10_write_register(ViPipe, 0x3016, 0x72); + os04c10_write_register(ViPipe, 0x3021, 0x03); + os04c10_write_register(ViPipe, 0x3106, 0x21); + os04c10_write_register(ViPipe, 0x3107, 0xa1); + os04c10_write_register(ViPipe, 0x3500, 0x00); + os04c10_write_register(ViPipe, 0x3501, 0x03); + os04c10_write_register(ViPipe, 0x3502, 0x08); + os04c10_write_register(ViPipe, 0x3503, 0x88); + os04c10_write_register(ViPipe, 0x3508, 0x00); + os04c10_write_register(ViPipe, 0x3509, 0x80); + os04c10_write_register(ViPipe, 0x350a, 0x04); + os04c10_write_register(ViPipe, 0x350b, 0x00); + os04c10_write_register(ViPipe, 0x350c, 0x00); + os04c10_write_register(ViPipe, 0x350d, 0x80); + os04c10_write_register(ViPipe, 0x350e, 0x04); + os04c10_write_register(ViPipe, 0x350f, 0x00); + os04c10_write_register(ViPipe, 0x3510, 0x00); + os04c10_write_register(ViPipe, 0x3511, 0x01); + os04c10_write_register(ViPipe, 0x3512, 0x08); + os04c10_write_register(ViPipe, 0x3624, 0x02); + os04c10_write_register(ViPipe, 0x3625, 0x4c); + os04c10_write_register(ViPipe, 0x3660, 0x04); + os04c10_write_register(ViPipe, 0x3666, 0xa5); + os04c10_write_register(ViPipe, 0x3667, 0xa5); + os04c10_write_register(ViPipe, 0x366a, 0x54); + os04c10_write_register(ViPipe, 0x3673, 0x0d); + os04c10_write_register(ViPipe, 0x3672, 0x0d); + os04c10_write_register(ViPipe, 0x3671, 0x0d); + os04c10_write_register(ViPipe, 0x3670, 0x0d); + os04c10_write_register(ViPipe, 0x3685, 0x00); + os04c10_write_register(ViPipe, 0x3694, 0x0d); + os04c10_write_register(ViPipe, 0x3693, 0x0d); + os04c10_write_register(ViPipe, 0x3692, 0x0d); + os04c10_write_register(ViPipe, 0x3691, 0x0d); + os04c10_write_register(ViPipe, 0x3696, 0x4c); + os04c10_write_register(ViPipe, 0x3697, 0x4c); + os04c10_write_register(ViPipe, 0x3698, 0x40); + os04c10_write_register(ViPipe, 0x3699, 0x80); + os04c10_write_register(ViPipe, 0x369a, 0x18); + os04c10_write_register(ViPipe, 0x369b, 0x1f); + os04c10_write_register(ViPipe, 0x369c, 0x14); + os04c10_write_register(ViPipe, 0x369d, 0x80); + os04c10_write_register(ViPipe, 0x369e, 0x40); + os04c10_write_register(ViPipe, 0x369f, 0x21); + os04c10_write_register(ViPipe, 0x36a0, 0x12); + os04c10_write_register(ViPipe, 0x36a1, 0x5d); + os04c10_write_register(ViPipe, 0x36a2, 0x66); + os04c10_write_register(ViPipe, 0x370a, 0x00); + os04c10_write_register(ViPipe, 0x370e, 0x0c); + os04c10_write_register(ViPipe, 0x3710, 0x00); + os04c10_write_register(ViPipe, 0x3713, 0x00); + os04c10_write_register(ViPipe, 0x3725, 0x02); + os04c10_write_register(ViPipe, 0x372a, 0x03); + os04c10_write_register(ViPipe, 0x3738, 0xce); + os04c10_write_register(ViPipe, 0x3748, 0x00); + os04c10_write_register(ViPipe, 0x374a, 0x00); + os04c10_write_register(ViPipe, 0x374c, 0x00); + os04c10_write_register(ViPipe, 0x374e, 0x00); + os04c10_write_register(ViPipe, 0x3756, 0x00); + os04c10_write_register(ViPipe, 0x3757, 0x00); + os04c10_write_register(ViPipe, 0x3767, 0x00); + os04c10_write_register(ViPipe, 0x3771, 0x00); + os04c10_write_register(ViPipe, 0x377b, 0x28); + os04c10_write_register(ViPipe, 0x377c, 0x00); + os04c10_write_register(ViPipe, 0x377d, 0x0c); + os04c10_write_register(ViPipe, 0x3781, 0x03); + os04c10_write_register(ViPipe, 0x3782, 0x00); + os04c10_write_register(ViPipe, 0x3789, 0x14); + os04c10_write_register(ViPipe, 0x3795, 0x02); + os04c10_write_register(ViPipe, 0x379c, 0x00); + os04c10_write_register(ViPipe, 0x379d, 0x00); + os04c10_write_register(ViPipe, 0x37b8, 0x04); + os04c10_write_register(ViPipe, 0x37ba, 0x03); + os04c10_write_register(ViPipe, 0x37bb, 0x00); + os04c10_write_register(ViPipe, 0x37bc, 0x04); + os04c10_write_register(ViPipe, 0x37be, 0x08); + os04c10_write_register(ViPipe, 0x37c4, 0x11); + os04c10_write_register(ViPipe, 0x37c5, 0x80); + os04c10_write_register(ViPipe, 0x37c6, 0x14); + os04c10_write_register(ViPipe, 0x37c7, 0x08); + os04c10_write_register(ViPipe, 0x37da, 0x11); + os04c10_write_register(ViPipe, 0x381f, 0x08); + os04c10_write_register(ViPipe, 0x3829, 0x03); + os04c10_write_register(ViPipe, 0x3881, 0x00); + os04c10_write_register(ViPipe, 0x3888, 0x04); + os04c10_write_register(ViPipe, 0x388b, 0x00); + os04c10_write_register(ViPipe, 0x3c80, 0x10); + os04c10_write_register(ViPipe, 0x3c86, 0x00); + os04c10_write_register(ViPipe, 0x3c8c, 0x20); + os04c10_write_register(ViPipe, 0x3c9f, 0x01); + os04c10_write_register(ViPipe, 0x3d85, 0x1b); + os04c10_write_register(ViPipe, 0x3d8c, 0x71); + os04c10_write_register(ViPipe, 0x3d8d, 0xe2); + os04c10_write_register(ViPipe, 0x3f00, 0x0b); + os04c10_write_register(ViPipe, 0x3f06, 0x04); + os04c10_write_register(ViPipe, 0x400a, 0x01); + os04c10_write_register(ViPipe, 0x400b, 0x50); + os04c10_write_register(ViPipe, 0x400e, 0x08); + os04c10_write_register(ViPipe, 0x4043, 0x7e); + os04c10_write_register(ViPipe, 0x4045, 0x7e); + os04c10_write_register(ViPipe, 0x4047, 0x7e); + os04c10_write_register(ViPipe, 0x4049, 0x7e); + os04c10_write_register(ViPipe, 0x4090, 0x14); + os04c10_write_register(ViPipe, 0x40b0, 0x00); + os04c10_write_register(ViPipe, 0x40b1, 0x00); + os04c10_write_register(ViPipe, 0x40b2, 0x00); + os04c10_write_register(ViPipe, 0x40b3, 0x00); + os04c10_write_register(ViPipe, 0x40b4, 0x00); + os04c10_write_register(ViPipe, 0x40b5, 0x00); + os04c10_write_register(ViPipe, 0x40b7, 0x00); + os04c10_write_register(ViPipe, 0x40b8, 0x00); + os04c10_write_register(ViPipe, 0x40b9, 0x00); + os04c10_write_register(ViPipe, 0x40ba, 0x01); + os04c10_write_register(ViPipe, 0x4301, 0x00); + os04c10_write_register(ViPipe, 0x4303, 0x00); + os04c10_write_register(ViPipe, 0x4502, 0x04); + os04c10_write_register(ViPipe, 0x4503, 0x00); + os04c10_write_register(ViPipe, 0x4504, 0x06); + os04c10_write_register(ViPipe, 0x4506, 0x00); + os04c10_write_register(ViPipe, 0x4507, 0x47); + os04c10_write_register(ViPipe, 0x4803, 0x00); + os04c10_write_register(ViPipe, 0x480c, 0x32); + os04c10_write_register(ViPipe, 0x480e, 0x04); + os04c10_write_register(ViPipe, 0x4813, 0xe4); + os04c10_write_register(ViPipe, 0x4819, 0x70); + os04c10_write_register(ViPipe, 0x481f, 0x30); + os04c10_write_register(ViPipe, 0x4823, 0x3f); + os04c10_write_register(ViPipe, 0x4825, 0x30); + os04c10_write_register(ViPipe, 0x4833, 0x10); + os04c10_write_register(ViPipe, 0x484b, 0x27); + os04c10_write_register(ViPipe, 0x488b, 0x00); + os04c10_write_register(ViPipe, 0x4d00, 0x04); + os04c10_write_register(ViPipe, 0x4d01, 0xad); + os04c10_write_register(ViPipe, 0x4d02, 0xbc); + os04c10_write_register(ViPipe, 0x4d03, 0xa1); + os04c10_write_register(ViPipe, 0x4d04, 0x1f); + os04c10_write_register(ViPipe, 0x4d05, 0x4c); + os04c10_write_register(ViPipe, 0x4d0b, 0x01); + os04c10_write_register(ViPipe, 0x4e00, 0x2a); + os04c10_write_register(ViPipe, 0x4e0d, 0x00); + os04c10_write_register(ViPipe, 0x5001, 0x09); + os04c10_write_register(ViPipe, 0x5004, 0x00); + os04c10_write_register(ViPipe, 0x5080, 0x04); + os04c10_write_register(ViPipe, 0x5036, 0x80); + os04c10_write_register(ViPipe, 0x5180, 0x70); + os04c10_write_register(ViPipe, 0x5181, 0x10); + os04c10_write_register(ViPipe, 0x520a, 0x03); + os04c10_write_register(ViPipe, 0x520b, 0x06); + os04c10_write_register(ViPipe, 0x520c, 0x0c); + os04c10_write_register(ViPipe, 0x580b, 0x0f); + os04c10_write_register(ViPipe, 0x580d, 0x00); + os04c10_write_register(ViPipe, 0x580f, 0x00); + os04c10_write_register(ViPipe, 0x5820, 0x00); + os04c10_write_register(ViPipe, 0x5821, 0x00); + os04c10_write_register(ViPipe, 0x301c, 0xf8); + os04c10_write_register(ViPipe, 0x301e, 0xb4); + os04c10_write_register(ViPipe, 0x301f, 0xf0); + os04c10_write_register(ViPipe, 0x3022, 0x01); + os04c10_write_register(ViPipe, 0x3109, 0xe7); + os04c10_write_register(ViPipe, 0x3600, 0x00); + os04c10_write_register(ViPipe, 0x3610, 0x75); + os04c10_write_register(ViPipe, 0x3611, 0x85); + os04c10_write_register(ViPipe, 0x3613, 0x3a); + os04c10_write_register(ViPipe, 0x3615, 0x60); + os04c10_write_register(ViPipe, 0x3621, 0x90); + os04c10_write_register(ViPipe, 0x3620, 0x0c); + os04c10_write_register(ViPipe, 0x3629, 0x00); + os04c10_write_register(ViPipe, 0x3661, 0x04); + os04c10_write_register(ViPipe, 0x3664, 0x70); + os04c10_write_register(ViPipe, 0x3665, 0x00); + os04c10_write_register(ViPipe, 0x3681, 0xa6); + os04c10_write_register(ViPipe, 0x3682, 0x53); + os04c10_write_register(ViPipe, 0x3683, 0x2a); + os04c10_write_register(ViPipe, 0x3684, 0x15); + os04c10_write_register(ViPipe, 0x3700, 0x2a); + os04c10_write_register(ViPipe, 0x3701, 0x12); + os04c10_write_register(ViPipe, 0x3703, 0x28); + os04c10_write_register(ViPipe, 0x3704, 0x0e); + os04c10_write_register(ViPipe, 0x3706, 0x4a); + os04c10_write_register(ViPipe, 0x3709, 0x4a); + os04c10_write_register(ViPipe, 0x370b, 0xa2); + os04c10_write_register(ViPipe, 0x370c, 0x01); + os04c10_write_register(ViPipe, 0x370f, 0x04); + os04c10_write_register(ViPipe, 0x3714, 0x24); + os04c10_write_register(ViPipe, 0x3716, 0x24); + os04c10_write_register(ViPipe, 0x3719, 0x11); + os04c10_write_register(ViPipe, 0x371a, 0x1e); + os04c10_write_register(ViPipe, 0x3720, 0x00); + os04c10_write_register(ViPipe, 0x3724, 0x13); + os04c10_write_register(ViPipe, 0x373f, 0xb0); + os04c10_write_register(ViPipe, 0x3741, 0x4a); + os04c10_write_register(ViPipe, 0x3743, 0x4a); + os04c10_write_register(ViPipe, 0x3745, 0x4a); + os04c10_write_register(ViPipe, 0x3747, 0x4a); + os04c10_write_register(ViPipe, 0x3749, 0xa2); + os04c10_write_register(ViPipe, 0x374b, 0xa2); + os04c10_write_register(ViPipe, 0x374d, 0xa2); + os04c10_write_register(ViPipe, 0x374f, 0xa2); + os04c10_write_register(ViPipe, 0x3755, 0x10); + os04c10_write_register(ViPipe, 0x376c, 0x00); + os04c10_write_register(ViPipe, 0x378d, 0x30); + os04c10_write_register(ViPipe, 0x3790, 0x4a); + os04c10_write_register(ViPipe, 0x3791, 0xa2); + os04c10_write_register(ViPipe, 0x3798, 0x40); + os04c10_write_register(ViPipe, 0x379e, 0x00); + os04c10_write_register(ViPipe, 0x379f, 0x04); + os04c10_write_register(ViPipe, 0x37a1, 0x10); + os04c10_write_register(ViPipe, 0x37a2, 0x1e); + os04c10_write_register(ViPipe, 0x37a8, 0x10); + os04c10_write_register(ViPipe, 0x37a9, 0x1e); + os04c10_write_register(ViPipe, 0x37ac, 0xa0); + os04c10_write_register(ViPipe, 0x37b9, 0x01); + os04c10_write_register(ViPipe, 0x37bd, 0x01); + os04c10_write_register(ViPipe, 0x37bf, 0x26); + os04c10_write_register(ViPipe, 0x37c0, 0x11); + os04c10_write_register(ViPipe, 0x37c2, 0x04); + os04c10_write_register(ViPipe, 0x37cd, 0x19); + os04c10_write_register(ViPipe, 0x37e0, 0x08); + os04c10_write_register(ViPipe, 0x37e6, 0x04); + os04c10_write_register(ViPipe, 0x37e5, 0x02); + os04c10_write_register(ViPipe, 0x37e1, 0x0c); + os04c10_write_register(ViPipe, 0x3737, 0x04); + os04c10_write_register(ViPipe, 0x37d8, 0x02); + os04c10_write_register(ViPipe, 0x37e2, 0x10); + os04c10_write_register(ViPipe, 0x3739, 0x10); + os04c10_write_register(ViPipe, 0x3662, 0x10); + os04c10_write_register(ViPipe, 0x37e4, 0x20); + os04c10_write_register(ViPipe, 0x37e3, 0x08); + os04c10_write_register(ViPipe, 0x37d9, 0x08); + os04c10_write_register(ViPipe, 0x4040, 0x00); + os04c10_write_register(ViPipe, 0x4041, 0x07); + os04c10_write_register(ViPipe, 0x4008, 0x02); + os04c10_write_register(ViPipe, 0x4009, 0x0d); + os04c10_write_register(ViPipe, 0x3800, 0x00); + os04c10_write_register(ViPipe, 0x3801, 0x40); + os04c10_write_register(ViPipe, 0x3802, 0x00); + os04c10_write_register(ViPipe, 0x3803, 0x28); + os04c10_write_register(ViPipe, 0x3804, 0x0a); + os04c10_write_register(ViPipe, 0x3805, 0x4f); + os04c10_write_register(ViPipe, 0x3806, 0x05); + os04c10_write_register(ViPipe, 0x3807, 0xd7); + os04c10_write_register(ViPipe, 0x3808, 0x0a); + os04c10_write_register(ViPipe, 0x3809, 0x00); + os04c10_write_register(ViPipe, 0x380a, 0x05); + os04c10_write_register(ViPipe, 0x380b, 0xa0); + os04c10_write_register(ViPipe, 0x380c, 0x04); + os04c10_write_register(ViPipe, 0x380d, 0x2e); + os04c10_write_register(ViPipe, 0x380e, 0x06); + os04c10_write_register(ViPipe, 0x380f, 0x92); + os04c10_write_register(ViPipe, 0x3811, 0x08); + os04c10_write_register(ViPipe, 0x3813, 0x08); + os04c10_write_register(ViPipe, 0x3814, 0x01); + os04c10_write_register(ViPipe, 0x3815, 0x01); + os04c10_write_register(ViPipe, 0x3816, 0x01); + os04c10_write_register(ViPipe, 0x3817, 0x01); + os04c10_write_register(ViPipe, 0x3820, 0x88); + os04c10_write_register(ViPipe, 0x3821, 0x04); + os04c10_write_register(ViPipe, 0x3880, 0x25); + os04c10_write_register(ViPipe, 0x3882, 0x20); + os04c10_write_register(ViPipe, 0x3c91, 0x0b); + os04c10_write_register(ViPipe, 0x3c94, 0x45); + os04c10_write_register(ViPipe, 0x4000, 0xf3); + os04c10_write_register(ViPipe, 0x4001, 0x60); + os04c10_write_register(ViPipe, 0x4003, 0x40); + os04c10_write_register(ViPipe, 0x4300, 0xff); + os04c10_write_register(ViPipe, 0x4302, 0x0f); + os04c10_write_register(ViPipe, 0x4305, 0x83); + os04c10_write_register(ViPipe, 0x4505, 0x84); + os04c10_write_register(ViPipe, 0x4809, 0x0e); + os04c10_write_register(ViPipe, 0x480a, 0x04); + os04c10_write_register(ViPipe, 0x4837, 0x14); + os04c10_write_register(ViPipe, 0x4c00, 0x08); + os04c10_write_register(ViPipe, 0x4c01, 0x08); + os04c10_write_register(ViPipe, 0x4c04, 0x00); + os04c10_write_register(ViPipe, 0x4c05, 0x00); + os04c10_write_register(ViPipe, 0x5000, 0xe9); + os04c10_write_register(ViPipe, 0x3624, 0x00); + os04c10_write_register(ViPipe, 0x3016, 0x32); + os04c10_write_register(ViPipe, 0x0306, 0x00); + os04c10_write_register(ViPipe, 0x4837, 0x0a); + os04c10_write_register(ViPipe, 0x0305, 0x5a); + os04c10_write_register(ViPipe, 0x0325, 0x6b); + os04c10_write_register(ViPipe, 0x3106, 0x25); + os04c10_default_reg_init(ViPipe); + + if (!g_au16Os04c10_UseHwSync[ViPipe]) { + /* freerun */ + os04c10_write_register(ViPipe, 0x3002, 0x21); + } else { + /* auto master */ + os04c10_write_register(ViPipe, 0x3002, 0x22); // [1] vsync_oen, [0]: fsin_oen + os04c10_write_register(ViPipe, 0x3690, 0x00); // [4]: 1'b0, 1st set vsync pulse + os04c10_write_register(ViPipe, 0x383e, 0x00); // vscyn_rise_rcnt_pt[23:16] + os04c10_write_register(ViPipe, 0x3818, 0x00); // Slave vsync pulse position cs [15:8] + os04c10_write_register(ViPipe, 0x3819, 0x00); // Slave vsync pulse position cs [7:0], + // max is HTS/4 + os04c10_write_register(ViPipe, 0x381a, 0x00); // vscyn_rise_rcnt_pt[15:8] + os04c10_write_register(ViPipe, 0x381b, 0x00); // vscyn_rise_rcnt_pt[7:0], max: + // VTS-12 for AHBIN 720p, (VTS -12)*2 for + // other formats + os04c10_write_register(ViPipe, 0x3832, 0xf8); // default, 8'h08, [7:4] vsync pulse width + os04c10_write_register(ViPipe, 0x368a, 0x04); // GPIO enable + } + + os04c10_write_register(ViPipe, 0x0100, 0x01); + + usleep(50*1000); + + printf("===Os04c10 sensor 1440P30fps 10bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} \ No newline at end of file diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_os08a20/Makefile b/middleware/v2/component/isp/sensor/cv180x/ov_os08a20/Makefile new file mode 100644 index 000000000..3a9655ed2 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_os08a20/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_os08a20.a +TARGET_SO = $(MW_LIB)/libsns_os08a20.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_os08a20/os08a20_cmos.c b/middleware/v2/component/isp/sensor/cv180x/ov_os08a20/os08a20_cmos.c new file mode 100644 index 000000000..80e81bee0 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_os08a20/os08a20_cmos.c @@ -0,0 +1,1083 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "os08a20_cmos_ex.h" +#include "os08a20_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define OS08A20_ID 820 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastOs08a20[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define OS08A20_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastOs08a20[dev]) +#define OS08A20_SENSOR_SET_CTX(dev, pstCtx) (g_pastOs08a20[dev] = pstCtx) +#define OS08A20_SENSOR_RESET_CTX(dev) (g_pastOs08a20[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunOs08a20_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Os08a20_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Os08a20_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +OS08A20_STATE_S g_astOs08a20_State[VI_MAX_PIPE_NUM] = {{0} }; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Os08a20 Lines Range*****/ +#define OS08A20_FULL_LINES_MAX (0xFFFF) +#define OS08A20_FULL_LINES_MAX_2TO1_WDR (0xFFFF) + +/*****Os08a20 Register Address*****/ +#define OS08A20_HOLD1_ADDR 0x320D +#define OS08A20_HOLD2_ADDR 0x3208 +#define OS08A20_HOLD3_ADDR 0x0808 +#define OS08A20_EXP1_ADDR 0x3501 +#define OS08A20_EXP2_ADDR 0x3511 +#define OS08A20_AGAIN1_ADDR 0x3508 +#define OS08A20_DGAIN1_ADDR 0x350A +#define OS08A20_AGAIN2_ADDR 0x350C +#define OS08A20_DGAIN2_ADDR 0x350E +#define OS08A20_VTS_ADDR 0x380E +#define OS08A20_TABLE_END 0xffff + +#define OS08A20_RES_IS_1944P(w, h) ((w) <= 2592 && (h) <= 1944) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const OS08A20_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astOs08a20_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = OS08A20_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astOs08a20_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astOs08a20_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astOs08a20_mode[pstSnsState->u8ImgMode].f32MinFps; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OS08A20_FULL_LINES_MAX) ? OS08A20_FULL_LINES_MAX : u32VMAX; + + pstSnsRegsInfo->astI2cData[LINEAR_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_1].u32Data = (u32VMAX & 0xFF); + } else { + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OS08A20_FULL_LINES_MAX_2TO1_WDR) ? OS08A20_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + pstSnsRegsInfo->astI2cData[WDR2_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_VTS_1].u32Data = (u32VMAX & 0xFF); + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + /* sanity check for HDR-VC mode */ + if (u32IntTime[0] >= u32IntTime[1]) { + CVI_TRACE_SNS(CVI_DBG_ERR, "shutter : sef %d shall not be greater than sef %d\n", + u32IntTime[0], u32IntTime[1]); + return CVI_FAILURE; + } + if ((u32IntTime[0] + u32IntTime[1]) >= (pstSnsState->au32FL[0] - 4)) { + CVI_TRACE_SNS(CVI_DBG_ERR, "shutter : total shutter %d shall not be greater than %d\n", + u32IntTime[0] + u32IntTime[1], pstSnsState->au32FL[0] - 4); + return CVI_FAILURE; + } + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32IntTime[0]; + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = u32IntTime[1]; + + pstSnsRegsInfo->astI2cData[WDR2_EXP1_0].u32Data = ((pstSnsState->au32WDRIntTime[1] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_EXP1_1].u32Data = (pstSnsState->au32WDRIntTime[1] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_EXP2_0].u32Data = ((pstSnsState->au32WDRIntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_EXP2_1].u32Data = (pstSnsState->au32WDRIntTime[0] & 0xFF); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + pstSnsRegsInfo->astI2cData[LINEAR_EXP_0].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_1].u32Data = (u32IntTime[0] & 0xFF); + } + + return CVI_SUCCESS; + +} + +/* + * GainReg {0x3508, 0x3509} Real Gain + * 0x0080~0x00FF INT(GainReg/8)/16 + * 0x0100~0x01FF INT(GainReg/16)/8 + * 0x0200~0x03FF INT(GainReg/32)/4 + * 0x0400~0x07FF INT(GainReg/64)/2 + */ + +static CVI_U32 gain_table[64] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[63]) { + *pu32AgainLin = gain_table[63]; + *pu32AgainDb = (63 - 48) * 64 + 1024; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + i--; + if (i < 16) + *pu32AgainDb = i * 8 + 128; + else if (i < 32) + *pu32AgainDb = (i - 16) * 16 + 256; + else if (i < 48) + *pu32AgainDb = (i - 32) * 32 + 512; + else + *pu32AgainDb = (i - 48) * 64 + 1024; + + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin <= 1024) { + *pu32DgainLin = 1024; + } else if (*pu32DgainLin > 16383) { + *pu32DgainLin = 16383; + } + *pu32DgainDb = *pu32DgainLin; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0].u32Data = ((u32Again & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_1].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0].u32Data = ((u32Dgain & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1].u32Data = (u32Dgain & 0xFF); + } else { + /* DOL mode */ + u32Again = pu32Again[1]; + u32Dgain = pu32Dgain[1]; + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_0].u32Data = ((u32Again & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_1].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_0].u32Data = ((u32Dgain & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_1].u32Data = (u32Dgain & 0xFF); + + if (g_au16Os08a20_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[1]; + u32Dgain = pu32Dgain[1]; + } else if (g_au16Os08a20_GainMode[ViPipe] == SNS_GAIN_MODE_WDR_2F) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + } else { + return CVI_SUCCESS; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_0].u32Data = ((u32Again & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_1].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_0].u32Data = ((u32Dgain & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_1].u32Data = (u32Dgain & 0xFF); + + } + + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 8 : 8; + /* + * Long exp + Short exp < VTS - 4, choose even number VTS - 6. + */ + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + syslog(LOG_DEBUG, "Max inttime0 = %u\n", u32IntTimeMaxTmp); + + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio is too large!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const OS08A20_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astOs08a20_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == OS08A20_MODE_2592X1944P30_WDR) + pstSnsState->u8ImgMode = OS08A20_MODE_2592X1944P30; + else { + } + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOs08a20_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == OS08A20_MODE_2592X1944P30) { + pstSnsState->u8ImgMode = OS08A20_MODE_2592X1944P30_WDR; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1944p mode(60fps->30fps)\n"); + } else { + } + + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astOs08a20_mode[pstSnsState->u8ImgMode].u32VtsDef; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunOs08a20_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = os08a20_i2c_addr; + pstI2c_data[i].u32AddrByteNum = os08a20_addr_byte; + pstI2c_data[i].u32DataByteNum = os08a20_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[WDR2_HOLD1].u32RegAddr = OS08A20_HOLD1_ADDR; + pstI2c_data[WDR2_HOLD1].u32Data = 0; + pstI2c_data[WDR2_HOLD2].u32RegAddr = OS08A20_HOLD2_ADDR; + pstI2c_data[WDR2_HOLD2].u32Data = 0; + pstI2c_data[WDR2_HOLD3].u32RegAddr = OS08A20_HOLD3_ADDR; + pstI2c_data[WDR2_HOLD3].u32Data = 0; + pstI2c_data[WDR2_EXP1_0].u32RegAddr = OS08A20_EXP1_ADDR; + pstI2c_data[WDR2_EXP1_1].u32RegAddr = OS08A20_EXP1_ADDR + 1; + pstI2c_data[WDR2_EXP2_0].u32RegAddr = OS08A20_EXP2_ADDR; + pstI2c_data[WDR2_EXP2_1].u32RegAddr = OS08A20_EXP2_ADDR + 1; + pstI2c_data[WDR2_AGAIN1_0].u32RegAddr = OS08A20_AGAIN1_ADDR; + pstI2c_data[WDR2_AGAIN1_1].u32RegAddr = OS08A20_AGAIN1_ADDR + 1; + pstI2c_data[WDR2_AGAIN2_0].u32RegAddr = OS08A20_AGAIN2_ADDR; + pstI2c_data[WDR2_AGAIN2_1].u32RegAddr = OS08A20_AGAIN2_ADDR + 1; + pstI2c_data[WDR2_DGAIN1_0].u32RegAddr = OS08A20_DGAIN1_ADDR; + pstI2c_data[WDR2_DGAIN1_1].u32RegAddr = OS08A20_DGAIN1_ADDR + 1; + pstI2c_data[WDR2_DGAIN2_0].u32RegAddr = OS08A20_DGAIN2_ADDR; + pstI2c_data[WDR2_DGAIN2_1].u32RegAddr = OS08A20_DGAIN2_ADDR + 1; + pstI2c_data[WDR2_VTS_0].u32RegAddr = OS08A20_VTS_ADDR; + pstI2c_data[WDR2_VTS_1].u32RegAddr = OS08A20_VTS_ADDR + 1; + pstI2c_data[WDR2_REL1].u32RegAddr = OS08A20_HOLD2_ADDR; + pstI2c_data[WDR2_REL1].u32Data = 0x10; + pstI2c_data[WDR2_REL2].u32RegAddr = OS08A20_HOLD1_ADDR; + pstI2c_data[WDR2_REL2].u32Data = 0x0; + pstI2c_data[WDR2_REL3].u32RegAddr = OS08A20_HOLD2_ADDR; + pstI2c_data[WDR2_REL3].u32Data = 0xE0; + break; + default: + pstI2c_data[LINEAR_HOLD1].u32RegAddr = OS08A20_HOLD1_ADDR; + pstI2c_data[LINEAR_HOLD1].u32Data = 0; + pstI2c_data[LINEAR_HOLD2].u32RegAddr = OS08A20_HOLD2_ADDR; + pstI2c_data[LINEAR_HOLD2].u32Data = 0; + pstI2c_data[LINEAR_HOLD3].u32RegAddr = OS08A20_HOLD3_ADDR; + pstI2c_data[LINEAR_HOLD3].u32Data = 0; + pstI2c_data[LINEAR_EXP_0].u32RegAddr = OS08A20_EXP1_ADDR; + pstI2c_data[LINEAR_EXP_1].u32RegAddr = OS08A20_EXP1_ADDR + 1; + pstI2c_data[LINEAR_AGAIN_0].u32RegAddr = OS08A20_AGAIN1_ADDR; + pstI2c_data[LINEAR_AGAIN_1].u32RegAddr = OS08A20_AGAIN1_ADDR + 1; + pstI2c_data[LINEAR_DGAIN_0].u32RegAddr = OS08A20_DGAIN1_ADDR; + pstI2c_data[LINEAR_DGAIN_1].u32RegAddr = OS08A20_DGAIN1_ADDR + 1; + pstI2c_data[LINEAR_VTS_0].u32RegAddr = OS08A20_VTS_ADDR; + pstI2c_data[LINEAR_VTS_1].u32RegAddr = OS08A20_VTS_ADDR + 1; + pstI2c_data[LINEAR_REL1].u32RegAddr = OS08A20_HOLD2_ADDR; + pstI2c_data[LINEAR_REL1].u32Data = 0x10; + pstI2c_data[LINEAR_REL2].u32RegAddr = OS08A20_HOLD1_ADDR; + pstI2c_data[LINEAR_REL2].u32Data = 0x0; + pstI2c_data[LINEAR_REL3].u32RegAddr = OS08A20_HOLD2_ADDR; + pstI2c_data[LINEAR_REL3].u32Data = 0xE0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[WDR2_HOLD1].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_HOLD2].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_HOLD3].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_REL1].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_REL2].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_REL3].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD1].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_HOLD2].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_HOLD3].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL1].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL2].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL3].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (OS08A20_RES_IS_1944P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OS08A20_MODE_2592X1944P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (OS08A20_RES_IS_1944P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OS08A20_MODE_2592X1944P30_WDR; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = OS08A20_MODE_2592X1944P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOs08a20_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astOs08a20_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astOs08a20_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &os08a20_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astOs08a20_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astOs08a20_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &os08a20_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = os08a20_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = os08a20_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 os08a20_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunOs08a20_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OS08A20_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + OS08A20_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OS08A20_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + OS08A20_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = OS08A20_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, OS08A20_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, OS08A20_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, OS08A20_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Os08a20_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Os08a20_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsOs08a20_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = os08a20_standby, + .pfnRestart = os08a20_restart, + .pfnMirrorFlip = CVI_NULL, + .pfnWriteReg = os08a20_write_register, + .pfnReadReg = os08a20_read_register, + .pfnSetBusInfo = os08a20_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_os08a20/os08a20_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/ov_os08a20/os08a20_cmos_ex.h new file mode 100644 index 000000000..ce48bf901 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_os08a20/os08a20_cmos_ex.h @@ -0,0 +1,116 @@ +#ifndef __OS08A20_CMOS_EX_H_ +#define __OS08A20_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum os08a20_linear_regs_e { + LINEAR_HOLD1 = 0, + LINEAR_HOLD2, + LINEAR_HOLD3, + LINEAR_EXP_0, + LINEAR_EXP_1, + LINEAR_AGAIN_0, + LINEAR_AGAIN_1, + LINEAR_DGAIN_0, + LINEAR_DGAIN_1, + LINEAR_VTS_0, + LINEAR_VTS_1, + LINEAR_REL1, + LINEAR_REL2, + LINEAR_REL3, + LINEAR_REGS_NUM +}; + +enum os08a20_wdr2_regs_e { + WDR2_HOLD1 = 0, + WDR2_HOLD2, + WDR2_HOLD3, + WDR2_EXP1_0, + WDR2_EXP1_1, + WDR2_EXP2_0, + WDR2_EXP2_1, + WDR2_AGAIN1_0, + WDR2_AGAIN1_1, + WDR2_AGAIN2_0, + WDR2_AGAIN2_1, + WDR2_DGAIN1_0, + WDR2_DGAIN1_1, + WDR2_DGAIN2_0, + WDR2_DGAIN2_1, + WDR2_VTS_0, + WDR2_VTS_1, + WDR2_REL1, + WDR2_REL2, + WDR2_REL3, + WDR2_REGS_NUM +}; + +typedef enum _OS08A20_MODE_E { + OS08A20_MODE_2592X1944P30 = 0, + OS08A20_MODE_LINEAR_NUM, + OS08A20_MODE_2592X1944P30_WDR = OS08A20_MODE_LINEAR_NUM, + OS08A20_MODE_NUM +} OS08A20_MODE_E; + +typedef struct _OS08A20_STATE_S { + CVI_U32 u32Sexp_MAX; +} OS08A20_STATE_S; + +typedef struct _OS08A20_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + CVI_U16 u16L2sOffset; + CVI_U16 u16TopBoundary; + CVI_U16 u16BotBoundary; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U32 u32L2S_MAX; + char name[64]; +} OS08A20_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastOs08a20[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunOs08a20_BusInfo[]; +extern CVI_U16 g_au16Os08a20_GainMode[]; +extern CVI_U16 g_au16Os08a20_L2SMode[VI_MAX_PIPE_NUM]; +extern const CVI_U8 os08a20_i2c_addr; +extern const CVI_U32 os08a20_addr_byte; +extern const CVI_U32 os08a20_data_byte; +extern void os08a20_init(VI_PIPE ViPipe); +extern void os08a20_exit(VI_PIPE ViPipe); +extern void os08a20_standby(VI_PIPE ViPipe); +extern void os08a20_restart(VI_PIPE ViPipe); +extern int os08a20_write_register(VI_PIPE ViPipe, int addr, int data); +extern int os08a20_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OS08A20_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_os08a20/os08a20_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/ov_os08a20/os08a20_cmos_param.h new file mode 100644 index 000000000..692e7313c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_os08a20/os08a20_cmos_param.h @@ -0,0 +1,300 @@ +#ifndef __OS08A20_CMOS_PARAM_H_ +#define __OS08A20_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "os08a20_cmos_ex.h" + +static const OS08A20_MODE_S g_astOs08a20_mode[OS08A20_MODE_NUM] = { + [OS08A20_MODE_2592X1944P30] = { + .name = "2592x1944p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2592, + .u32Height = 1944, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2592, + .u32Height = 1944, + }, + .stMaxSize = { + .u32Width = 2592, + .u32Height = 1944, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.06, /* 0x90a * 30 / 0xFFFF */ + .u32HtsDef = 0x818, + .u32VtsDef = 0x90a, + .stExp[0] = { + .u16Min = 8, + .u16Max = 0x90a - 8, + .u16Def = 0x462, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 16383, + .u16Def = 1024, + .u16Step = 1, + }, + }, + [OS08A20_MODE_2592X1944P30_WDR] = { + .name = "2592x1944p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2592, + .u32Height = 1944, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2592, + .u32Height = 1944, + }, + .stMaxSize = { + .u32Width = 2592, + .u32Height = 1944, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 2592, + .u32Height = 1944, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2592, + .u32Height = 1944, + }, + .stMaxSize = { + .u32Width = 2592, + .u32Height = 1944, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.08, /* 0x92a * 30 / 0xFFFF */ + .u32HtsDef = 0x40c, + .u32VtsDef = 0x92a, + .u16L2sOffset = 4, + .u16TopBoundary = 36, + .u16BotBoundary = 8, + .stExp[0] = { + .u16Min = 8, + .u16Max = 312, + .u16Def = 100, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 8, + .u16Max = 0x486 - 4 - 312, + .u16Def = 500, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 16383, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 16383, + .u16Def = 1024, + .u16Step = 1, + }, + .u32L2S_MAX = 0x13D, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.03190412744879722595, 3.86617159843444824219}, //B: slope, intercept + {0.02441397681832313538, 4.87663412094116210938}, //Gb: slope, intercept + {0.02471913769841194153, 4.85860157012939453125}, //Gr: slope, intercept + {0.02652409672737121582, 4.48996973037719726563}, //R: slope, intercept + }, + { //iso 200 + {0.04349273815751075745, 5.49785566329956054688}, //B: slope, intercept + {0.03087714128196239471, 7.49881792068481445313}, //Gb: slope, intercept + {0.03145518898963928223, 7.35760211944580078125}, //Gr: slope, intercept + {0.03530855849385261536, 6.56339693069458007813}, //R: slope, intercept + }, + { //iso 400 + {0.05788951739668846130, 8.34851074218750000000}, //B: slope, intercept + {0.04015926644206047058, 11.21226787567138671875}, //Gb: slope, intercept + {0.04018958285450935364, 11.29319286346435546875}, //Gr: slope, intercept + {0.04840981587767601013, 9.35622310638427734375}, //R: slope, intercept + }, + { //iso 800 + {0.08085585385560989380, 11.91084861755371093750}, //B: slope, intercept + {0.05333026498556137085, 16.38746833801269531250}, //Gb: slope, intercept + {0.05413141101598739624, 16.21148872375488281250}, //Gr: slope, intercept + {0.06530260294675827026, 13.91790008544921875000}, //R: slope, intercept + }, + { //iso 1600 + {0.09407941251993179321, 17.58893775939941406250}, //B: slope, intercept + {0.05309880897402763367, 24.13221168518066406250}, //Gb: slope, intercept + {0.05440055206418037415, 23.84361267089843750000}, //Gr: slope, intercept + {0.06805266439914703369, 20.56119728088378906250}, //R: slope, intercept + }, + { //iso 3200 + {0.09407941251993179321, 17.58893775939941406250}, //B: slope, intercept + {0.05309880897402763367, 24.13221168518066406250}, //Gb: slope, intercept + {0.05440055206418037415, 23.84361267089843750000}, //Gr: slope, intercept + {0.06805266439914703369, 20.56119728088378906250}, //R: slope, intercept + }, + { //iso 6400 + {0.09407941251993179321, 17.58893775939941406250}, //B: slope, intercept + {0.05309880897402763367, 24.13221168518066406250}, //Gb: slope, intercept + {0.05440055206418037415, 23.84361267089843750000}, //Gr: slope, intercept + {0.06805266439914703369, 20.56119728088378906250}, //R: slope, intercept + }, + { //iso 12800 + {0.09407941251993179321, 17.58893775939941406250}, //B: slope, intercept + {0.05309880897402763367, 24.13221168518066406250}, //Gb: slope, intercept + {0.05440055206418037415, 23.84361267089843750000}, //Gr: slope, intercept + {0.06805266439914703369, 20.56119728088378906250}, //R: slope, intercept + }, + { //iso 25600 + {0.48950406908988952637, 67.73629760742187500000}, //B: slope, intercept + {0.25487670302391052246, 101.95156860351562500000}, //Gb: slope, intercept + {0.24315287172794342041, 105.36353302001953125000}, //Gr: slope, intercept + {0.33707463741302490234, 86.65032958984375000000}, //R: slope, intercept + }, + { //iso 51200 + {0.48950406908988952637, 67.73629760742187500000}, //B: slope, intercept + {0.25487670302391052246, 101.95156860351562500000}, //Gb: slope, intercept + {0.24315287172794342041, 105.36353302001953125000}, //Gr: slope, intercept + {0.33707463741302490234, 86.65032958984375000000}, //R: slope, intercept + }, + { //iso 102400 + {0.48950406908988952637, 67.73629760742187500000}, //B: slope, intercept + {0.25487670302391052246, 101.95156860351562500000}, //Gb: slope, intercept + {0.24315287172794342041, 105.36353302001953125000}, //Gr: slope, intercept + {0.33707463741302490234, 86.65032958984375000000}, //R: slope, intercept + }, + { //iso 204800 + {0.48950406908988952637, 67.73629760742187500000}, //B: slope, intercept + {0.25487670302391052246, 101.95156860351562500000}, //Gb: slope, intercept + {0.24315287172794342041, 105.36353302001953125000}, //Gr: slope, intercept + {0.33707463741302490234, 86.65032958984375000000}, //R: slope, intercept + }, + { //iso 409600 + {0.48950406908988952637, 67.73629760742187500000}, //B: slope, intercept + {0.25487670302391052246, 101.95156860351562500000}, //Gb: slope, intercept + {0.24315287172794342041, 105.36353302001953125000}, //Gr: slope, intercept + {0.33707463741302490234, 86.65032958984375000000}, //R: slope, intercept + }, + { //iso 819200 + {0.48950406908988952637, 67.73629760742187500000}, //B: slope, intercept + {0.25487670302391052246, 101.95156860351562500000}, //Gb: slope, intercept + {0.24315287172794342041, 105.36353302001953125000}, //Gr: slope, intercept + {0.33707463741302490234, 86.65032958984375000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.48950406908988952637, 67.73629760742187500000}, //B: slope, intercept + {0.25487670302391052246, 101.95156860351562500000}, //Gb: slope, intercept + {0.24315287172794342041, 105.36353302001953125000}, //Gr: slope, intercept + {0.33707463741302490234, 86.65032958984375000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.48950406908988952637, 67.73629760742187500000}, //B: slope, intercept + {0.25487670302391052246, 101.95156860351562500000}, //Gb: slope, intercept + {0.24315287172794342041, 105.36353302001953125000}, //Gr: slope, intercept + {0.33707463741302490234, 86.65032958984375000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, +#endif + }, + }, +}; + +struct combo_dev_attr_s os08a20_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_600M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {3, 2, 1, 4, 0}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_25M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OS08A20_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_os08a20/os08a20_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/ov_os08a20/os08a20_sensor_ctl.c new file mode 100644 index 000000000..f9bfe49c6 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_os08a20/os08a20_sensor_ctl.c @@ -0,0 +1,585 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "os08a20_cmos_ex.h" + +static void os08a20_wdr_1944p30_2to1_init(VI_PIPE ViPipe); +static void os08a20_linear_1944p30_init(VI_PIPE ViPipe); + +const CVI_U8 os08a20_i2c_addr = 0x36; /* I2C Address of OS08A20 */ +const CVI_U32 os08a20_addr_byte = 2; +const CVI_U32 os08a20_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int os08a20_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunOs08a20_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, os08a20_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int os08a20_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int os08a20_read_register(VI_PIPE ViPipe, int addr) +{ + /* TODO:*/ + (void) ViPipe; + (void) addr; + + return CVI_SUCCESS; +} + + +int os08a20_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (os08a20_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (os08a20_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, os08a20_addr_byte + os08a20_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void os08a20_standby(VI_PIPE ViPipe) +{ + os08a20_write_register(ViPipe, 0x0100, 0x00); /* STANDBY */ +} + +void os08a20_restart(VI_PIPE ViPipe) +{ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ +} + +void os08a20_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + /* by pass the group hold and clear registers since it won't update when stream is off. */ + for (i = 3; i < g_pastOs08a20[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum - 3; i++) { + os08a20_write_register(ViPipe, + g_pastOs08a20[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastOs08a20[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void os08a20_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastOs08a20[ViPipe]->enWDRMode; + u8ImgMode = g_pastOs08a20[ViPipe]->u8ImgMode; + + os08a20_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == OS08A20_MODE_2592X1944P30_WDR) + os08a20_wdr_1944p30_2to1_init(ViPipe); + else { + } + } else { + if (u8ImgMode == OS08A20_MODE_2592X1944P30) + os08a20_linear_1944p30_init(ViPipe); + else { + } + } + g_pastOs08a20[ViPipe]->bInit = CVI_TRUE; +} + +void os08a20_exit(VI_PIPE ViPipe) +{ + os08a20_i2c_exit(ViPipe); +} + +/* 1944P30 and 1944P25 */ +static void os08a20_linear_1944p30_init(VI_PIPE ViPipe) +{ + os08a20_write_register(ViPipe, 0x0100, 0x00); + os08a20_write_register(ViPipe, 0x0103, 0x01); + os08a20_write_register(ViPipe, 0x0303, 0x01); + os08a20_write_register(ViPipe, 0x0305, 0x5a); + os08a20_write_register(ViPipe, 0x0306, 0x00); + os08a20_write_register(ViPipe, 0x0308, 0x03); + os08a20_write_register(ViPipe, 0x0309, 0x04); + os08a20_write_register(ViPipe, 0x032a, 0x00); + os08a20_write_register(ViPipe, 0x300f, 0x11); + os08a20_write_register(ViPipe, 0x3010, 0x01); + os08a20_write_register(ViPipe, 0x3011, 0x04); + os08a20_write_register(ViPipe, 0x3012, 0x41); + os08a20_write_register(ViPipe, 0x3016, 0xf0); + os08a20_write_register(ViPipe, 0x301e, 0x98); + os08a20_write_register(ViPipe, 0x3031, 0xa9); + os08a20_write_register(ViPipe, 0x3103, 0x92); + os08a20_write_register(ViPipe, 0x3104, 0x01); + os08a20_write_register(ViPipe, 0x3106, 0x10); + os08a20_write_register(ViPipe, 0x3400, 0x04); + os08a20_write_register(ViPipe, 0x3025, 0x03); + os08a20_write_register(ViPipe, 0x3425, 0x01); + os08a20_write_register(ViPipe, 0x3428, 0x01); + os08a20_write_register(ViPipe, 0x3406, 0x08); + os08a20_write_register(ViPipe, 0x3408, 0x03); + os08a20_write_register(ViPipe, 0x340c, 0xff); + os08a20_write_register(ViPipe, 0x340d, 0xff); + os08a20_write_register(ViPipe, 0x031e, 0x09); + os08a20_write_register(ViPipe, 0x3501, 0x08); + os08a20_write_register(ViPipe, 0x3502, 0xe5); + os08a20_write_register(ViPipe, 0x3505, 0x83); + os08a20_write_register(ViPipe, 0x3508, 0x00); + os08a20_write_register(ViPipe, 0x3509, 0x80); + os08a20_write_register(ViPipe, 0x350a, 0x04); + os08a20_write_register(ViPipe, 0x350b, 0x00); + os08a20_write_register(ViPipe, 0x350c, 0x00); + os08a20_write_register(ViPipe, 0x350d, 0x80); + os08a20_write_register(ViPipe, 0x350e, 0x04); + os08a20_write_register(ViPipe, 0x350f, 0x00); + os08a20_write_register(ViPipe, 0x3600, 0x00); + os08a20_write_register(ViPipe, 0x3603, 0x2c); + os08a20_write_register(ViPipe, 0x3605, 0x50); + os08a20_write_register(ViPipe, 0x3609, 0xb5); + os08a20_write_register(ViPipe, 0x3610, 0x39); + os08a20_write_register(ViPipe, 0x360c, 0x01); + os08a20_write_register(ViPipe, 0x3628, 0xa4); + os08a20_write_register(ViPipe, 0x362d, 0x10); + os08a20_write_register(ViPipe, 0x3660, 0x43); + os08a20_write_register(ViPipe, 0x3661, 0x06); + os08a20_write_register(ViPipe, 0x3662, 0x00); + os08a20_write_register(ViPipe, 0x3663, 0x28); + os08a20_write_register(ViPipe, 0x3664, 0x0d); + os08a20_write_register(ViPipe, 0x366a, 0x38); + os08a20_write_register(ViPipe, 0x366b, 0xa0); + os08a20_write_register(ViPipe, 0x366d, 0x00); + os08a20_write_register(ViPipe, 0x366e, 0x00); + os08a20_write_register(ViPipe, 0x3680, 0x00); + os08a20_write_register(ViPipe, 0x36c0, 0x00); + os08a20_write_register(ViPipe, 0x3701, 0x02); + os08a20_write_register(ViPipe, 0x373b, 0x02); + os08a20_write_register(ViPipe, 0x373c, 0x02); + os08a20_write_register(ViPipe, 0x3736, 0x02); + os08a20_write_register(ViPipe, 0x3737, 0x02); + os08a20_write_register(ViPipe, 0x3705, 0x00); + os08a20_write_register(ViPipe, 0x3706, 0x39); + os08a20_write_register(ViPipe, 0x370a, 0x00); + os08a20_write_register(ViPipe, 0x370b, 0x98); + os08a20_write_register(ViPipe, 0x3709, 0x49); + os08a20_write_register(ViPipe, 0x3714, 0x21); + os08a20_write_register(ViPipe, 0x371c, 0x00); + os08a20_write_register(ViPipe, 0x371d, 0x08); + os08a20_write_register(ViPipe, 0x3740, 0x1b); + os08a20_write_register(ViPipe, 0x3741, 0x04); + os08a20_write_register(ViPipe, 0x375e, 0x0b); + os08a20_write_register(ViPipe, 0x3760, 0x10); + os08a20_write_register(ViPipe, 0x3776, 0x10); + os08a20_write_register(ViPipe, 0x3781, 0x02); + os08a20_write_register(ViPipe, 0x3782, 0x04); + os08a20_write_register(ViPipe, 0x3783, 0x02); + os08a20_write_register(ViPipe, 0x3784, 0x08); + os08a20_write_register(ViPipe, 0x3785, 0x08); + os08a20_write_register(ViPipe, 0x3788, 0x01); + os08a20_write_register(ViPipe, 0x3789, 0x01); + os08a20_write_register(ViPipe, 0x3797, 0x04); + os08a20_write_register(ViPipe, 0x3762, 0x11); + os08a20_write_register(ViPipe, 0x3800, 0x00); + os08a20_write_register(ViPipe, 0x3801, 0x00); + os08a20_write_register(ViPipe, 0x3802, 0x00); + os08a20_write_register(ViPipe, 0x3803, 0x0c); + os08a20_write_register(ViPipe, 0x3804, 0x0e); + os08a20_write_register(ViPipe, 0x3805, 0xff); + os08a20_write_register(ViPipe, 0x3806, 0x08); + os08a20_write_register(ViPipe, 0x3807, 0x6f); + os08a20_write_register(ViPipe, 0x3808, 0x0f); + os08a20_write_register(ViPipe, 0x3809, 0x00); + os08a20_write_register(ViPipe, 0x380a, 0x08); + os08a20_write_register(ViPipe, 0x380b, 0x70); + os08a20_write_register(ViPipe, 0x380c, 0x04); + os08a20_write_register(ViPipe, 0x380d, 0x0c); + os08a20_write_register(ViPipe, 0x380e, 0x09); + os08a20_write_register(ViPipe, 0x380f, 0x0a); + os08a20_write_register(ViPipe, 0x3813, 0x10); + os08a20_write_register(ViPipe, 0x3814, 0x01); + os08a20_write_register(ViPipe, 0x3815, 0x01); + os08a20_write_register(ViPipe, 0x3816, 0x01); + os08a20_write_register(ViPipe, 0x3817, 0x01); + os08a20_write_register(ViPipe, 0x381c, 0x00); + os08a20_write_register(ViPipe, 0x3820, 0x00); + os08a20_write_register(ViPipe, 0x3821, 0x04); + os08a20_write_register(ViPipe, 0x3823, 0x08); + os08a20_write_register(ViPipe, 0x3826, 0x00); + os08a20_write_register(ViPipe, 0x3827, 0x08); + os08a20_write_register(ViPipe, 0x382d, 0x08); + os08a20_write_register(ViPipe, 0x3832, 0x02); + os08a20_write_register(ViPipe, 0x3833, 0x00); + os08a20_write_register(ViPipe, 0x383c, 0x48); + os08a20_write_register(ViPipe, 0x383d, 0xff); + os08a20_write_register(ViPipe, 0x3d85, 0x0b); + os08a20_write_register(ViPipe, 0x3d84, 0x40); + os08a20_write_register(ViPipe, 0x3d8c, 0x63); + os08a20_write_register(ViPipe, 0x3d8d, 0xd7); + os08a20_write_register(ViPipe, 0x4000, 0xf8); + os08a20_write_register(ViPipe, 0x4001, 0x2b); + os08a20_write_register(ViPipe, 0x4004, 0x00); + os08a20_write_register(ViPipe, 0x4005, 0x40); + os08a20_write_register(ViPipe, 0x400a, 0x01); + os08a20_write_register(ViPipe, 0x400f, 0xa0); + os08a20_write_register(ViPipe, 0x4010, 0x12); + os08a20_write_register(ViPipe, 0x4018, 0x00); + os08a20_write_register(ViPipe, 0x4008, 0x02); + os08a20_write_register(ViPipe, 0x4009, 0x0d); + os08a20_write_register(ViPipe, 0x401a, 0x58); + os08a20_write_register(ViPipe, 0x4050, 0x00); + os08a20_write_register(ViPipe, 0x4051, 0x01); + os08a20_write_register(ViPipe, 0x4028, 0x2f); + os08a20_write_register(ViPipe, 0x4052, 0x00); + os08a20_write_register(ViPipe, 0x4053, 0x80); + os08a20_write_register(ViPipe, 0x4054, 0x00); + os08a20_write_register(ViPipe, 0x4055, 0x80); + os08a20_write_register(ViPipe, 0x4056, 0x00); + os08a20_write_register(ViPipe, 0x4057, 0x80); + os08a20_write_register(ViPipe, 0x4058, 0x00); + os08a20_write_register(ViPipe, 0x4059, 0x80); + os08a20_write_register(ViPipe, 0x430b, 0xff); + os08a20_write_register(ViPipe, 0x430c, 0xff); + os08a20_write_register(ViPipe, 0x430d, 0x00); + os08a20_write_register(ViPipe, 0x430e, 0x00); + os08a20_write_register(ViPipe, 0x4501, 0x18); + os08a20_write_register(ViPipe, 0x4502, 0x00); + os08a20_write_register(ViPipe, 0x4643, 0x00); + os08a20_write_register(ViPipe, 0x4640, 0x01); + os08a20_write_register(ViPipe, 0x4641, 0x04); + os08a20_write_register(ViPipe, 0x4800, 0x64); + os08a20_write_register(ViPipe, 0x4809, 0x2b); + os08a20_write_register(ViPipe, 0x4813, 0x90); + os08a20_write_register(ViPipe, 0x4817, 0x04); + os08a20_write_register(ViPipe, 0x4833, 0x18); + os08a20_write_register(ViPipe, 0x4837, 0x0b); + os08a20_write_register(ViPipe, 0x483b, 0x00); + os08a20_write_register(ViPipe, 0x484b, 0x03); + os08a20_write_register(ViPipe, 0x4850, 0x7c); + os08a20_write_register(ViPipe, 0x4852, 0x06); + os08a20_write_register(ViPipe, 0x4856, 0x58); + os08a20_write_register(ViPipe, 0x4857, 0xaa); + os08a20_write_register(ViPipe, 0x4862, 0x0a); + os08a20_write_register(ViPipe, 0x4869, 0x18); + os08a20_write_register(ViPipe, 0x486a, 0xaa); + os08a20_write_register(ViPipe, 0x486e, 0x03); + os08a20_write_register(ViPipe, 0x486f, 0x55); + os08a20_write_register(ViPipe, 0x4875, 0xf0); + os08a20_write_register(ViPipe, 0x5000, 0x89); + os08a20_write_register(ViPipe, 0x5001, 0x42); + os08a20_write_register(ViPipe, 0x5004, 0x40); + os08a20_write_register(ViPipe, 0x5005, 0x00); + os08a20_write_register(ViPipe, 0x5180, 0x00); + os08a20_write_register(ViPipe, 0x5181, 0x10); + os08a20_write_register(ViPipe, 0x580b, 0x03); + os08a20_write_register(ViPipe, 0x4d00, 0x03); + os08a20_write_register(ViPipe, 0x4d01, 0xc9); + os08a20_write_register(ViPipe, 0x4d02, 0xbc); + os08a20_write_register(ViPipe, 0x4d03, 0xc6); + os08a20_write_register(ViPipe, 0x4d04, 0x4a); + os08a20_write_register(ViPipe, 0x4d05, 0x25); + os08a20_write_register(ViPipe, 0x4700, 0x2b); + os08a20_write_register(ViPipe, 0x4e00, 0x2b); + os08a20_write_register(ViPipe, 0x3501, 0x09); + os08a20_write_register(ViPipe, 0x3502, 0x01); + os08a20_write_register(ViPipe, 0x0305, 0x57); + os08a20_write_register(ViPipe, 0x380c, 0x08); + os08a20_write_register(ViPipe, 0x380d, 0x18); + os08a20_write_register(ViPipe, 0x380e, 0x09); + os08a20_write_register(ViPipe, 0x380f, 0x0a); + os08a20_write_register(ViPipe, 0x3501, 0x09); + os08a20_write_register(ViPipe, 0x3502, 0x02); + os08a20_write_register(ViPipe, 0x3808, 0x0a); + os08a20_write_register(ViPipe, 0x3809, 0x20); + os08a20_write_register(ViPipe, 0x380a, 0x07); + os08a20_write_register(ViPipe, 0x380b, 0x98); + + os08a20_default_reg_init(ViPipe); + + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + + delay_ms(50); + + printf("ViPipe:%d,===OS08A20 1944P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +static void os08a20_wdr_1944p30_2to1_init(VI_PIPE ViPipe) +{ + os08a20_write_register(ViPipe, 0x0100, 0x00); + os08a20_write_register(ViPipe, 0x0103, 0x01); + os08a20_write_register(ViPipe, 0x0303, 0x01); + os08a20_write_register(ViPipe, 0x0305, 0x5a); + os08a20_write_register(ViPipe, 0x0306, 0x00); + os08a20_write_register(ViPipe, 0x0308, 0x03); + os08a20_write_register(ViPipe, 0x0309, 0x04); + os08a20_write_register(ViPipe, 0x032a, 0x00); + os08a20_write_register(ViPipe, 0x300f, 0x11); + os08a20_write_register(ViPipe, 0x3010, 0x01); + os08a20_write_register(ViPipe, 0x3011, 0x04); + os08a20_write_register(ViPipe, 0x3012, 0x41); + os08a20_write_register(ViPipe, 0x3016, 0xf0); + os08a20_write_register(ViPipe, 0x301e, 0x98); + os08a20_write_register(ViPipe, 0x3031, 0xa9); + os08a20_write_register(ViPipe, 0x3103, 0x92); + os08a20_write_register(ViPipe, 0x3104, 0x01); + os08a20_write_register(ViPipe, 0x3106, 0x10); + os08a20_write_register(ViPipe, 0x340c, 0xff); + os08a20_write_register(ViPipe, 0x340d, 0xff); + os08a20_write_register(ViPipe, 0x031e, 0x09); + os08a20_write_register(ViPipe, 0x3501, 0x08); + os08a20_write_register(ViPipe, 0x3502, 0xe5); + os08a20_write_register(ViPipe, 0x3505, 0x83); + os08a20_write_register(ViPipe, 0x3508, 0x00); + os08a20_write_register(ViPipe, 0x3509, 0x80); + os08a20_write_register(ViPipe, 0x350a, 0x04); + os08a20_write_register(ViPipe, 0x350b, 0x00); + os08a20_write_register(ViPipe, 0x350c, 0x00); + os08a20_write_register(ViPipe, 0x350d, 0x80); + os08a20_write_register(ViPipe, 0x350e, 0x04); + os08a20_write_register(ViPipe, 0x350f, 0x00); + os08a20_write_register(ViPipe, 0x3600, 0x00); + os08a20_write_register(ViPipe, 0x3603, 0x2c); + os08a20_write_register(ViPipe, 0x3605, 0x50); + os08a20_write_register(ViPipe, 0x3609, 0xb5); + os08a20_write_register(ViPipe, 0x3610, 0x39); + os08a20_write_register(ViPipe, 0x360c, 0x01); + os08a20_write_register(ViPipe, 0x3628, 0xa4); + os08a20_write_register(ViPipe, 0x362d, 0x10); + os08a20_write_register(ViPipe, 0x3660, 0x42); + os08a20_write_register(ViPipe, 0x3661, 0x07); + os08a20_write_register(ViPipe, 0x3662, 0x00); + os08a20_write_register(ViPipe, 0x3663, 0x28); + os08a20_write_register(ViPipe, 0x3664, 0x0d); + os08a20_write_register(ViPipe, 0x366a, 0x38); + os08a20_write_register(ViPipe, 0x366b, 0xa0); + os08a20_write_register(ViPipe, 0x366d, 0x00); + os08a20_write_register(ViPipe, 0x366e, 0x00); + os08a20_write_register(ViPipe, 0x3680, 0x00); + os08a20_write_register(ViPipe, 0x36c0, 0x00); + os08a20_write_register(ViPipe, 0x3701, 0x02); + os08a20_write_register(ViPipe, 0x373b, 0x02); + os08a20_write_register(ViPipe, 0x373c, 0x02); + os08a20_write_register(ViPipe, 0x3736, 0x02); + os08a20_write_register(ViPipe, 0x3737, 0x02); + os08a20_write_register(ViPipe, 0x3705, 0x00); + os08a20_write_register(ViPipe, 0x3706, 0x39); + os08a20_write_register(ViPipe, 0x370a, 0x00); + os08a20_write_register(ViPipe, 0x370b, 0x98); + os08a20_write_register(ViPipe, 0x3709, 0x49); + os08a20_write_register(ViPipe, 0x3714, 0x21); + os08a20_write_register(ViPipe, 0x371c, 0x00); + os08a20_write_register(ViPipe, 0x371d, 0x08); + os08a20_write_register(ViPipe, 0x3740, 0x1b); + os08a20_write_register(ViPipe, 0x3741, 0x04); + os08a20_write_register(ViPipe, 0x375e, 0x0b); + os08a20_write_register(ViPipe, 0x3760, 0x10); + os08a20_write_register(ViPipe, 0x3776, 0x10); + os08a20_write_register(ViPipe, 0x3781, 0x02); + os08a20_write_register(ViPipe, 0x3782, 0x04); + os08a20_write_register(ViPipe, 0x3783, 0x02); + os08a20_write_register(ViPipe, 0x3784, 0x08); + os08a20_write_register(ViPipe, 0x3785, 0x08); + os08a20_write_register(ViPipe, 0x3788, 0x01); + os08a20_write_register(ViPipe, 0x3789, 0x01); + os08a20_write_register(ViPipe, 0x3797, 0x04); + os08a20_write_register(ViPipe, 0x3762, 0x11); + os08a20_write_register(ViPipe, 0x3800, 0x00); + os08a20_write_register(ViPipe, 0x3801, 0x00); + os08a20_write_register(ViPipe, 0x3802, 0x00); + os08a20_write_register(ViPipe, 0x3803, 0x0c); + os08a20_write_register(ViPipe, 0x3804, 0x0e); + os08a20_write_register(ViPipe, 0x3805, 0xff); + os08a20_write_register(ViPipe, 0x3806, 0x08); + os08a20_write_register(ViPipe, 0x3807, 0x6f); + os08a20_write_register(ViPipe, 0x3808, 0x0a); + os08a20_write_register(ViPipe, 0x3809, 0x20); + os08a20_write_register(ViPipe, 0x380a, 0x07); + os08a20_write_register(ViPipe, 0x380b, 0x98); + os08a20_write_register(ViPipe, 0x380c, 0x04); + os08a20_write_register(ViPipe, 0x380d, 0x0c); + os08a20_write_register(ViPipe, 0x380e, 0x09); + os08a20_write_register(ViPipe, 0x380f, 0x0a); + os08a20_write_register(ViPipe, 0x3813, 0x10); + os08a20_write_register(ViPipe, 0x3814, 0x01); + os08a20_write_register(ViPipe, 0x3815, 0x01); + os08a20_write_register(ViPipe, 0x3816, 0x01); + os08a20_write_register(ViPipe, 0x3817, 0x01); + os08a20_write_register(ViPipe, 0x381c, 0x08); + os08a20_write_register(ViPipe, 0x3820, 0x00); + os08a20_write_register(ViPipe, 0x3821, 0x24); + os08a20_write_register(ViPipe, 0x3823, 0x08); + os08a20_write_register(ViPipe, 0x3826, 0x00); + os08a20_write_register(ViPipe, 0x3827, 0x08); + os08a20_write_register(ViPipe, 0x382d, 0x08); + os08a20_write_register(ViPipe, 0x3832, 0x02); + os08a20_write_register(ViPipe, 0x3833, 0x01); + os08a20_write_register(ViPipe, 0x383c, 0x48); + os08a20_write_register(ViPipe, 0x383d, 0xff); + os08a20_write_register(ViPipe, 0x3d85, 0x0b); + os08a20_write_register(ViPipe, 0x3d84, 0x40); + os08a20_write_register(ViPipe, 0x3d8c, 0x63); + os08a20_write_register(ViPipe, 0x3d8d, 0xd7); + os08a20_write_register(ViPipe, 0x4000, 0xf8); + os08a20_write_register(ViPipe, 0x4001, 0x2b); + os08a20_write_register(ViPipe, 0x4004, 0x00); + os08a20_write_register(ViPipe, 0x4005, 0x40); + os08a20_write_register(ViPipe, 0x400a, 0x01); + os08a20_write_register(ViPipe, 0x400f, 0xa0); + os08a20_write_register(ViPipe, 0x4010, 0x12); + os08a20_write_register(ViPipe, 0x4018, 0x00); + os08a20_write_register(ViPipe, 0x4008, 0x02); + os08a20_write_register(ViPipe, 0x4009, 0x0d); + os08a20_write_register(ViPipe, 0x401a, 0x58); + os08a20_write_register(ViPipe, 0x4050, 0x00); + os08a20_write_register(ViPipe, 0x4051, 0x01); + os08a20_write_register(ViPipe, 0x4028, 0x2f); + os08a20_write_register(ViPipe, 0x4052, 0x00); + os08a20_write_register(ViPipe, 0x4053, 0x80); + os08a20_write_register(ViPipe, 0x4054, 0x00); + os08a20_write_register(ViPipe, 0x4055, 0x80); + os08a20_write_register(ViPipe, 0x4056, 0x00); + os08a20_write_register(ViPipe, 0x4057, 0x80); + os08a20_write_register(ViPipe, 0x4058, 0x00); + os08a20_write_register(ViPipe, 0x4059, 0x80); + os08a20_write_register(ViPipe, 0x430b, 0xff); + os08a20_write_register(ViPipe, 0x430c, 0xff); + os08a20_write_register(ViPipe, 0x430d, 0x00); + os08a20_write_register(ViPipe, 0x430e, 0x00); + os08a20_write_register(ViPipe, 0x4501, 0x18); + os08a20_write_register(ViPipe, 0x4502, 0x00); + os08a20_write_register(ViPipe, 0x4643, 0x00); + os08a20_write_register(ViPipe, 0x4640, 0x01); + os08a20_write_register(ViPipe, 0x4641, 0x04); + os08a20_write_register(ViPipe, 0x4800, 0x64); + os08a20_write_register(ViPipe, 0x4809, 0x2b); + os08a20_write_register(ViPipe, 0x4813, 0x98); + os08a20_write_register(ViPipe, 0x4817, 0x04); + os08a20_write_register(ViPipe, 0x4833, 0x18); + os08a20_write_register(ViPipe, 0x4837, 0x0b); + os08a20_write_register(ViPipe, 0x483b, 0x00); + os08a20_write_register(ViPipe, 0x484b, 0x03); + os08a20_write_register(ViPipe, 0x4850, 0x7c); + os08a20_write_register(ViPipe, 0x4852, 0x06); + os08a20_write_register(ViPipe, 0x4856, 0x58); + os08a20_write_register(ViPipe, 0x4857, 0xaa); + os08a20_write_register(ViPipe, 0x4862, 0x0a); + os08a20_write_register(ViPipe, 0x4869, 0x18); + os08a20_write_register(ViPipe, 0x486a, 0xaa); + os08a20_write_register(ViPipe, 0x486e, 0x07); + os08a20_write_register(ViPipe, 0x486f, 0x55); + os08a20_write_register(ViPipe, 0x4875, 0xf0); + os08a20_write_register(ViPipe, 0x5000, 0x89); + os08a20_write_register(ViPipe, 0x5001, 0x42); + os08a20_write_register(ViPipe, 0x5004, 0x40); + os08a20_write_register(ViPipe, 0x5005, 0x00); + os08a20_write_register(ViPipe, 0x5180, 0x00); + os08a20_write_register(ViPipe, 0x5181, 0x10); + os08a20_write_register(ViPipe, 0x580b, 0x03); + os08a20_write_register(ViPipe, 0x4d00, 0x03); + os08a20_write_register(ViPipe, 0x4d01, 0xc9); + os08a20_write_register(ViPipe, 0x4d02, 0xbc); + os08a20_write_register(ViPipe, 0x4d03, 0xc6); + os08a20_write_register(ViPipe, 0x4d04, 0x4a); + os08a20_write_register(ViPipe, 0x4d05, 0x25); + os08a20_write_register(ViPipe, 0x4700, 0x2b); + os08a20_write_register(ViPipe, 0x4e00, 0x2b); + os08a20_write_register(ViPipe, 0x3501, 0x08); + os08a20_write_register(ViPipe, 0x3502, 0xe1); + os08a20_write_register(ViPipe, 0x3511, 0x00); + os08a20_write_register(ViPipe, 0x3512, 0x20); + os08a20_write_register(ViPipe, 0x3833, 0x01); + os08a20_write_register(ViPipe, 0x0305, 0x57); + os08a20_write_register(ViPipe, 0x0325, 0x46); + os08a20_write_register(ViPipe, 0x380e, 0x09); + os08a20_write_register(ViPipe, 0x380f, 0x2a); + os08a20_write_register(ViPipe, 0x4028, 0x4f); + os08a20_write_register(ViPipe, 0x4029, 0x1f); + os08a20_write_register(ViPipe, 0x402a, 0x7f); + os08a20_write_register(ViPipe, 0x402b, 0x01); + + os08a20_default_reg_init(ViPipe); + + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + + delay_ms(50); + + printf("===Os08a20 sensor 1944P30fps 10bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} + diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_ov4689/Makefile b/middleware/v2/component/isp/sensor/cv180x/ov_ov4689/Makefile new file mode 100644 index 000000000..b492c96f8 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_ov4689/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_ov4689.a +TARGET_SO = $(MW_LIB)/libsns_ov4689.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_ov4689/ov4689_cmos.c b/middleware/v2/component/isp/sensor/cv180x/ov_ov4689/ov4689_cmos.c new file mode 100644 index 000000000..2cba827c7 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_ov4689/ov4689_cmos.c @@ -0,0 +1,1034 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "ov4689_cmos_ex.h" +#include "ov4689_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define OV4689_ID 0x530243 +#define OV4689_I2C_ADDR_1 0x36 +#define OV4689_I2C_ADDR_2 0x10 +#define OV4689_I2C_ADDR_IS_VALID(addr) \ + ((addr) == OV4689_I2C_ADDR_1 || (addr) == OV4689_I2C_ADDR_2) +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastOv4689[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define OV4689_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastOv4689[dev]) +#define OV4689_SENSOR_SET_CTX(dev, pstCtx) (g_pastOv4689[dev] = pstCtx) +#define OV4689_SENSOR_RESET_CTX(dev) (g_pastOv4689[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunOv4689_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Ov4689_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Ov4689_UseHwSync[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeOv4689_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Ov4689 Lines Range*****/ +#define OV4689_FULL_LINES_MAX (0xFFFF) + +/*****Ov4689 Register Address*****/ +#define OV4689_HOLD_3208 0x3208 +#define OV4689_HOLD_320B 0x320B +#define OV4689_EXP1_ADDR 0x3500 +#define OV4689_AGAIN1_ADDR 0x3507 +#define OV4689_DGAIN1_ADDR 0x352A +#define OV4689_VTS_ADDR 0x380E +#define OV4689_TABLE_END 0xffff + +#define OV4689_RES_IS_1520P(w, h) ((w) == 2688 && (h) == 1520) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const OV4689_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astOv4689_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = OV4689_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + /* OV sensor cannot update new setting before the old setting takes effect */ + pstAeSnsDft->u8AERunInterval = 1; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astOv4689_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astOv4689_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astOv4689_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case OV4689_MODE_2688X1520P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OV4689_FULL_LINES_MAX) ? OV4689_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_1].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 4 + * max : vts - 4 + * step : 1 + */ + CVI_U32 u32TmpIntTime = u32IntTime[0]; + CVI_U32 mimExp = 4; + CVI_U32 maxExp = pstSnsState->au32FL[0] - 4; + + u32TmpIntTime = (u32TmpIntTime > maxExp) ? maxExp : u32TmpIntTime; + u32TmpIntTime = (u32TmpIntTime < mimExp) ? mimExp : u32TmpIntTime; + u32IntTime[0] = u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_0].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_1].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_2].u32Data = ((u32TmpIntTime & 0x000F) << 4); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +typedef struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} gain_tbl_info_s; + +static struct gain_tbl_info_s AgainInfo[15] = { + { + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 8, + }, + { + .gainMax = 3008, + .idxBase = 16, + .regGain = 0x01, + .regGainFineBase = 0x78, + .regGainFineStep = 4, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x01, + .regGainFineBase = 0xb8, + .regGainFineStep = 4, + }, + { + .gainMax = 5056, + .idxBase = 48, + .regGain = 0x03, + .regGainFineBase = 0x74, + .regGainFineStep = 2, + }, + { + .gainMax = 6080, + .idxBase = 64, + .regGain = 0x03, + .regGainFineBase = 0x94, + .regGainFineStep = 2, + }, + { + .gainMax = 7104, + .idxBase = 80, + .regGain = 0x03, + .regGainFineBase = 0xb4, + .regGainFineStep = 2, + }, + { + .gainMax = 8128, + .idxBase = 96, + .regGain = 0x03, + .regGainFineBase = 0xd4, + .regGainFineStep = 2, + }, + { + .gainMax = 9152, + .idxBase = 112, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + }, + { + .gainMax = 10176, + .idxBase = 120, + .regGain = 0x07, + .regGainFineBase = 0x88, + .regGainFineStep = 1, + }, + { + .gainMax = 11200, + .idxBase = 136, + .regGain = 0x07, + .regGainFineBase = 0x98, + .regGainFineStep = 1, + }, + { + .gainMax = 12224, + .idxBase = 152, + .regGain = 0x07, + .regGainFineBase = 0xa8, + .regGainFineStep = 1, + }, + { + .gainMax = 13248, + .idxBase = 168, + .regGain = 0x07, + .regGainFineBase = 0xb8, + .regGainFineStep = 1, + }, + { + .gainMax = 14272, + .idxBase = 184, + .regGain = 0x07, + .regGainFineBase = 0xc8, + .regGainFineStep = 1, + }, + { + .gainMax = 15296, + .idxBase = 200, + .regGain = 0x07, + .regGainFineBase = 0xd8, + .regGainFineStep = 1, + }, + { + .gainMax = 16320, + .idxBase = 216, + .regGain = 0x07, + .regGainFineBase = 0xe8, + .regGainFineStep = 1, + }, + +}; + +static CVI_U32 Again_table[] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, 1856, 1920, + 1984, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, + 2944, 3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, + 3904, 3968, 4032, 4096, 4160, 4224, 4288, 4352, 4416, 4480, 4544, 4608, 4672, 4736, 4800, + 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, 5504, 5568, 5632, 5696, 5760, + 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, 6464, 6528, 6592, 6656, 6720, + 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, 7424, 7488, 7552, 7616, 7680, + 7744, 7808, 7872, 7936, 8000, 8064, 8128, 8704, 8768, 8832, 8896, 8960, 9024, 9088, 9152, + 9216, 9280, 9344, 9408, 9472, 9536, 9600, 9664, 9728, 9792, 9856, 9920, 9984, 10048, 10112, + 10176, 10240, 10304, 10368, 10432, 10496, 10560, 10624, 10688, 10752, 10816, 10880, 10944, + 11008, 11072, 11136, 11200, 11264, 11328, 11392, 11456, 11520, 11584, 11648, 11712, 11776, + 11840, 11904, 11968, 12032, 12096, 12160, 12224, 12288, 12352, 12416, 12480, 12544, 12608, + 12672, 12736, 12800, 12864, 12928, 12992, 13056, 13120, 13184, 13248, 13312, 13376, 13440, + 13504, 13568, 13632, 13696, 13760, 13824, 13888, 13952, 14016, 14080, 14144, 14208, 14272, + 14336, 14400, 14464, 14528, 14592, 14656, 14720, 14784, 14848, 14912, 14976, 15040, 15104, + 15168, 15232, 15296, 15360, 15424, 15488, 15552, 15616, 15680, 15744, 15808, 15872, 15936, + 16000, 16064, 16128, 16192, 16256, 16320 +}; + +static CVI_U32 Dgain_table[] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, 1856, 1920, + 1984, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, + 2944, 3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, + 3904, 3968, 4032, 4096, 4160, 4224, 4288, 4352, 4416, 4480, 4544, 4608, 4672, 4736, 4800, + 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, 5504, 5568, 5632, 5696, 5760, + 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, 6464, 6528, 6592, 6656, 6720, + 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, 7424, 7488, 7552, 7616, 7680, + 7744, 7808, 7872, 7936, 8000, 8064, 8128, 8192, 8256, 8320, 8384, 8448, 8512, 8576, 8640, + 8704, 8768, 8832, 8896, 8960, 9024, 9088, 9152, 9216, 9280, 9344, 9408, 9472, 9536, 9600, + 9664, 9728, 9792, 9856, 9920, 9984, 10048, 10112, 10176, 10240, 10304, 10368, 10432, 10496, + 10560, 10624, 10688, 10752, 10816, 10880, 10944, 11008, 11072, 11136, 11200, 11264, 11328, + 11392, 11456, 11520, 11584, 11648, 11712, 11776, 11840, 11904, 11968, 12032, 12096, 12160, + 12224, 12288, 12352, 12416, 12480, 12544, 12608, 12672, 12736, 12800, 12864, 12928, 12992, + 13056, 13120, 13184, 13248, 13312, 13376, 13440, 13504, 13568, 13632, 13696, 13760, 13824, + 13888, 13952, 14016, 14080, 14144, 14208, 14272, 14336, 14400, 14464, 14528, 14592, 14656, + 14720, 14784, 14848, 14912, 14976, 15040, 15104, 15168, 15232, 15296, 15360, 15424, 15488, + 15552, 15616, 15680, 15744, 15808, 15872, 15936, 16000, 16064, 16128, 16192, 16256, 16320 +}; + +static const CVI_U32 again_table_size = ARRAY_SIZE(Again_table); +static const CVI_U32 dgain_table_size = ARRAY_SIZE(Dgain_table); + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[again_table_size - 1]) { + *pu32AgainLin = Again_table[again_table_size - 1]; + *pu32AgainDb = again_table_size - 1; + return CVI_SUCCESS; + } + + for (i = 1; i < again_table_size; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[dgain_table_size - 1]) { + *pu32DgainLin = Dgain_table[dgain_table_size - 1]; + *pu32DgainDb = dgain_table_size - 1; + return CVI_SUCCESS; + } + + for (i = 1; i < dgain_table_size; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u32Again = pu32Again[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0].u32Data = 0; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_1].u32Data = info->regGain & 0xFF; + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_2].u32Data = u32Again & 0xFF; + + /* find Dgain register setting. */ + u32Dgain = Dgain_table[pu32Dgain[0]] * 2; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0].u32Data = (u32Dgain & 0xFF00) >> 8; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1].u32Data = u32Dgain & 0xFF; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const OV4689_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astOv4689_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = OV4689_MODE_2688X1520P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOv4689_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunOv4689_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = ov4689_i2c_addr; + pstI2c_data[i].u32AddrByteNum = ov4689_addr_byte; + pstI2c_data[i].u32DataByteNum = ov4689_data_byte; + } + + switch (pstSnsState->enWDRMode) { + default: + pstI2c_data[LINEAR_HOLD_START].u32RegAddr = OV4689_HOLD_3208; + pstI2c_data[LINEAR_HOLD_START].u32Data = 0x00; + pstI2c_data[LINEAR_EXP_0].u32RegAddr = OV4689_EXP1_ADDR; + pstI2c_data[LINEAR_EXP_1].u32RegAddr = OV4689_EXP1_ADDR + 1; + pstI2c_data[LINEAR_EXP_2].u32RegAddr = OV4689_EXP1_ADDR + 2; + pstI2c_data[LINEAR_AGAIN_0].u32RegAddr = OV4689_AGAIN1_ADDR; + pstI2c_data[LINEAR_AGAIN_1].u32RegAddr = OV4689_AGAIN1_ADDR + 1; + pstI2c_data[LINEAR_AGAIN_2].u32RegAddr = OV4689_AGAIN1_ADDR + 2; + pstI2c_data[LINEAR_DGAIN_0].u32RegAddr = OV4689_DGAIN1_ADDR; + pstI2c_data[LINEAR_DGAIN_1].u32RegAddr = OV4689_DGAIN1_ADDR + 1; + pstI2c_data[LINEAR_VTS_0].u32RegAddr = OV4689_VTS_ADDR; + pstI2c_data[LINEAR_VTS_1].u32RegAddr = OV4689_VTS_ADDR + 1; + pstI2c_data[LINEAR_HOLD_END].u32RegAddr = OV4689_HOLD_3208; + pstI2c_data[LINEAR_HOLD_END].u32Data = 0x10; + pstI2c_data[LINEAR_LAUNCH_0].u32RegAddr = OV4689_HOLD_320B; + pstI2c_data[LINEAR_LAUNCH_0].u32Data = 0x00; + pstI2c_data[LINEAR_LAUNCH_0].u8DelayFrmNum = 0; + pstI2c_data[LINEAR_LAUNCH_1].u32RegAddr = OV4689_HOLD_3208; + pstI2c_data[LINEAR_LAUNCH_1].u32Data = 0xE0; + pstI2c_data[LINEAR_LAUNCH_1].u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + pstI2c_data[LINEAR_HOLD_START].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_HOLD_END].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_LAUNCH_0].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_LAUNCH_1].bUpdate = CVI_TRUE; + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (OV4689_RES_IS_1520P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OV4689_MODE_2688X1520P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeOv4689_MirrorFip[ViPipe] != eSnsMirrorFlip) { + ov4689_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeOv4689_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = OV4689_MODE_2688X1520P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOv4689_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astOv4689_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astOv4689_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &ov4689_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astOv4689_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astOv4689_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &ov4689_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = ov4689_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = ov4689_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (OV4689_I2C_ADDR_IS_VALID(s32I2cAddr)) + ov4689_i2c_addr = s32I2cAddr; +} + +static CVI_S32 ov4689_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunOv4689_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OV4689_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + OV4689_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OV4689_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + OV4689_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = OV4689_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, OV4689_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, OV4689_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, OV4689_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Ov4689_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Ov4689_UseHwSync[ViPipe] = pstInitAttr->u16UseHwSync; + + return CVI_SUCCESS; +} +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return ov4689_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsOv4689_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = ov4689_standby, + .pfnRestart = ov4689_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = ov4689_write_register, + .pfnReadReg = ov4689_read_register, + .pfnSetBusInfo = ov4689_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_ov4689/ov4689_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/ov_ov4689/ov4689_cmos_ex.h new file mode 100644 index 000000000..cbbf6dc17 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_ov4689/ov4689_cmos_ex.h @@ -0,0 +1,95 @@ +#ifndef __OV4689_CMOS_EX_H_ +#define __OV4689_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum ov4689_linear_regs_e { + LINEAR_HOLD_START = 0, + LINEAR_EXP_0, + LINEAR_EXP_1, + LINEAR_EXP_2, + LINEAR_AGAIN_0, + LINEAR_AGAIN_1, + LINEAR_AGAIN_2, + LINEAR_DGAIN_0, + LINEAR_DGAIN_1, + LINEAR_VTS_0, + LINEAR_VTS_1, + LINEAR_HOLD_END, + LINEAR_LAUNCH_0, + LINEAR_LAUNCH_1, + LINEAR_REGS_NUM +}; + +typedef enum _OV4689_MODE_E { + OV4689_MODE_2688X1520P30 = 0, + OV4689_MODE_LINEAR_NUM, + OV4689_MODE_NUM +} OV4689_MODE_E; + +typedef struct _OV4689_STATE_S { + CVI_U32 u32Sexp_MAX; +} OV4689_STATE_S; + +typedef struct _OV4689_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + CVI_U16 u16L2sOffset; + CVI_U16 u16TopBoundary; + CVI_U16 u16BotBoundary; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + CVI_U32 u32L2S_offset; + CVI_U32 u32IspResTime; + CVI_U32 u32HdrMargin; + char name[64]; +} OV4689_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastOv4689[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunOv4689_BusInfo[]; +extern CVI_U16 g_au16Ov4689_GainMode[]; +extern CVI_U16 g_au16Ov4689_UseHwSync[VI_MAX_PIPE_NUM]; +extern CVI_U8 ov4689_i2c_addr; +extern const CVI_U32 ov4689_addr_byte; +extern const CVI_U32 ov4689_data_byte; +extern void ov4689_init(VI_PIPE ViPipe); +extern void ov4689_exit(VI_PIPE ViPipe); +extern void ov4689_standby(VI_PIPE ViPipe); +extern void ov4689_restart(VI_PIPE ViPipe); +extern int ov4689_write_register(VI_PIPE ViPipe, int addr, int data); +extern int ov4689_read_register(VI_PIPE ViPipe, int addr); +extern void ov4689_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int ov4689_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OV4689_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_ov4689/ov4689_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/ov_ov4689/ov4689_cmos_param.h new file mode 100644 index 000000000..d8c6c1bdb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_ov4689/ov4689_cmos_param.h @@ -0,0 +1,124 @@ +#ifndef __OV4689_CMOS_PARAM_H_ +#define __OV4689_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "ov4689_cmos_ex.h" + +static const OV4689_MODE_S g_astOv4689_mode[OV4689_MODE_NUM] = { + [OV4689_MODE_2688X1520P30] = { + .name = "2688x1520p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2688, + .u32Height = 1520, + }, + .stMaxSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + }, + + .f32MaxFps = 30, + .f32MinFps = 0.711, /* 0x4e2 * 30 / 0xFFFF */ + .u32HtsDef = 2584, + .u32VtsDef = 1554, + .stExp[0] = { + .u16Min = 4, + .u16Max = 1554 - 4, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 16320, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16320, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {60, 60, 60, 60, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1039, 1039, 1039, 1039 +#endif + }, + .stAuto = { + {60, 60, 60, 60, 60, 60, 60, 60, /*8*/60, 60, 60, 60, 60, 60, 60, 60}, + {60, 60, 60, 60, 60, 60, 60, 60, /*8*/60, 60, 60, 60, 60, 60, 60, 60}, + {60, 60, 60, 60, 60, 60, 60, 60, /*8*/60, 60, 60, 60, 60, 60, 60, 60}, + {60, 60, 60, 60, 60, 60, 60, 60, /*8*/60, 60, 60, 60, 60, 60, 60, 60}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, + /*8*/1039, 1039, 1039, 1039, 1204, 1039, 1039, 1039}, + {1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, + /*8*/1039, 1039, 1039, 1039, 1204, 1039, 1039, 1039}, + {1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, + /*8*/1039, 1039, 1039, 1039, 1204, 1039, 1039, 1039}, + {1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, + /*8*/1039, 1039, 1039, 1039, 1204, 1039, 1039, 1039}, +#endif + }, + }, +}; + + +struct combo_dev_attr_s ov4689_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_400M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {0, 1, 2, -1, -1}, + .pn_swap = {0, 0, 0, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OV4689_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_ov4689/ov4689_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/ov_ov4689/ov4689_sensor_ctl.c new file mode 100644 index 000000000..ca9479135 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_ov4689/ov4689_sensor_ctl.c @@ -0,0 +1,509 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "ov4689_cmos_ex.h" + +static void ov4689_linear_1520p30_init(VI_PIPE ViPipe); + +CVI_U8 ov4689_i2c_addr = 0x36; /* I2C Address of OV4689 */ +const CVI_U32 ov4689_addr_byte = 2; +const CVI_U32 ov4689_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int ov4689_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunOv4689_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, ov4689_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int ov4689_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int ov4689_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (ov4689_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, ov4689_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, ov4689_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (ov4689_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + + return data; +} + +int ov4689_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (ov4689_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (ov4689_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, ov4689_addr_byte + ov4689_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void ov4689_standby(VI_PIPE ViPipe) +{ + ov4689_write_register(ViPipe, 0x0100, 0x00); /* STANDBY */ +} + +void ov4689_restart(VI_PIPE ViPipe) +{ + ov4689_write_register(ViPipe, 0x0100, 0x01); /* standby */ +} + +void ov4689_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + CVI_U32 start = 1; + CVI_U32 end = g_pastOv4689[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum - 3; + + for (i = start; i < end; i++) { + ov4689_write_register(ViPipe, + g_pastOv4689[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastOv4689[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define OV4689_FLIP 0x3820 +#define OV4689_MIRROR 0x3821 +void ov4689_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 flip, mirror; + + flip = ov4689_read_register(ViPipe, OV4689_FLIP); + mirror = ov4689_read_register(ViPipe, OV4689_MIRROR); + flip &= ~(0x3 << 1); + mirror &= ~(0x3 << 1); + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + mirror |= 0x3 << 1; + break; + case ISP_SNS_FLIP: + flip |= 0x3 << 1; + break; + case ISP_SNS_MIRROR_FLIP: + flip |= 0x3 << 1; + mirror |= 0x3 << 1; + break; + default: + return; + } + + ov4689_write_register(ViPipe, OV4689_FLIP, flip); + ov4689_write_register(ViPipe, OV4689_MIRROR, mirror); +} + +#define OV4689_CHIP_ID_ADDR_H 0x300A +#define OV4689_CHIP_ID_ADDR_L 0x300B +#define OV4689_CHIP_ID 0x4688 + +int ov4689_probe(VI_PIPE ViPipe) +{ + int nVal, nVal2; + + usleep(1000); + if (ov4689_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = ov4689_read_register(ViPipe, OV4689_CHIP_ID_ADDR_H); + nVal2 = ov4689_read_register(ViPipe, OV4689_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != OV4689_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + return CVI_SUCCESS; +} + +void ov4689_init(VI_PIPE ViPipe) +{ + ov4689_i2c_init(ViPipe); + + delay_ms(10); + + ov4689_linear_1520p30_init(ViPipe); + + g_pastOv4689[ViPipe]->bInit = CVI_TRUE; +} + +void ov4689_exit(VI_PIPE ViPipe) +{ + ov4689_i2c_exit(ViPipe); +} + +/* 1080P30 */ +static void ov4689_linear_1520p30_init(VI_PIPE ViPipe) +{ + ov4689_write_register(ViPipe, 0x0103, 0x01); + ov4689_write_register(ViPipe, 0x3638, 0x00); + ov4689_write_register(ViPipe, 0x0300, 0x00); + ov4689_write_register(ViPipe, 0x0302, 0x2a); + ov4689_write_register(ViPipe, 0x0303, 0x00); + ov4689_write_register(ViPipe, 0x0304, 0x03); + ov4689_write_register(ViPipe, 0x030b, 0x00); + ov4689_write_register(ViPipe, 0x030d, 0x1e); + ov4689_write_register(ViPipe, 0x030e, 0x04); + ov4689_write_register(ViPipe, 0x030f, 0x01); + ov4689_write_register(ViPipe, 0x0312, 0x01); + ov4689_write_register(ViPipe, 0x031e, 0x00); + ov4689_write_register(ViPipe, 0x3000, 0x20); + ov4689_write_register(ViPipe, 0x3002, 0x00); + ov4689_write_register(ViPipe, 0x3018, 0x32); + ov4689_write_register(ViPipe, 0x3020, 0x93); + ov4689_write_register(ViPipe, 0x3021, 0x03); + ov4689_write_register(ViPipe, 0x3022, 0x01); + ov4689_write_register(ViPipe, 0x3031, 0x0a); + ov4689_write_register(ViPipe, 0x303f, 0x0c); + ov4689_write_register(ViPipe, 0x3305, 0xf1); + ov4689_write_register(ViPipe, 0x3307, 0x04); + ov4689_write_register(ViPipe, 0x3309, 0x29); + ov4689_write_register(ViPipe, 0x3500, 0x00); + ov4689_write_register(ViPipe, 0x3501, 0x60); + ov4689_write_register(ViPipe, 0x3502, 0x00); + ov4689_write_register(ViPipe, 0x3503, 0x04); + ov4689_write_register(ViPipe, 0x3504, 0x00); + ov4689_write_register(ViPipe, 0x3505, 0x00); + ov4689_write_register(ViPipe, 0x3506, 0x00); + ov4689_write_register(ViPipe, 0x3507, 0x00); + ov4689_write_register(ViPipe, 0x3508, 0x00); + ov4689_write_register(ViPipe, 0x3509, 0x80); + ov4689_write_register(ViPipe, 0x350a, 0x00); + ov4689_write_register(ViPipe, 0x350b, 0x00); + ov4689_write_register(ViPipe, 0x350c, 0x00); + ov4689_write_register(ViPipe, 0x350d, 0x00); + ov4689_write_register(ViPipe, 0x350e, 0x00); + ov4689_write_register(ViPipe, 0x350f, 0x80); + ov4689_write_register(ViPipe, 0x3510, 0x00); + ov4689_write_register(ViPipe, 0x3511, 0x00); + ov4689_write_register(ViPipe, 0x3512, 0x00); + ov4689_write_register(ViPipe, 0x3513, 0x00); + ov4689_write_register(ViPipe, 0x3514, 0x00); + ov4689_write_register(ViPipe, 0x3515, 0x80); + ov4689_write_register(ViPipe, 0x3516, 0x00); + ov4689_write_register(ViPipe, 0x3517, 0x00); + ov4689_write_register(ViPipe, 0x3518, 0x00); + ov4689_write_register(ViPipe, 0x3519, 0x00); + ov4689_write_register(ViPipe, 0x351a, 0x00); + ov4689_write_register(ViPipe, 0x351b, 0x80); + ov4689_write_register(ViPipe, 0x351c, 0x00); + ov4689_write_register(ViPipe, 0x351d, 0x00); + ov4689_write_register(ViPipe, 0x351e, 0x00); + ov4689_write_register(ViPipe, 0x351f, 0x00); + ov4689_write_register(ViPipe, 0x3520, 0x00); + ov4689_write_register(ViPipe, 0x3521, 0x80); + ov4689_write_register(ViPipe, 0x3522, 0x08); + ov4689_write_register(ViPipe, 0x3524, 0x08); + ov4689_write_register(ViPipe, 0x3526, 0x08); + ov4689_write_register(ViPipe, 0x3528, 0x08); + ov4689_write_register(ViPipe, 0x352a, 0x08); + ov4689_write_register(ViPipe, 0x3602, 0x00); + ov4689_write_register(ViPipe, 0x3603, 0x40); + ov4689_write_register(ViPipe, 0x3604, 0x02); + ov4689_write_register(ViPipe, 0x3605, 0x00); + ov4689_write_register(ViPipe, 0x3606, 0x00); + ov4689_write_register(ViPipe, 0x3607, 0x00); + ov4689_write_register(ViPipe, 0x3609, 0x12); + ov4689_write_register(ViPipe, 0x360a, 0x40); + ov4689_write_register(ViPipe, 0x360c, 0x08); + ov4689_write_register(ViPipe, 0x360f, 0xe5); + ov4689_write_register(ViPipe, 0x3608, 0x8f); + ov4689_write_register(ViPipe, 0x3611, 0x00); + ov4689_write_register(ViPipe, 0x3613, 0xf7); + ov4689_write_register(ViPipe, 0x3616, 0x58); + ov4689_write_register(ViPipe, 0x3619, 0x99); + ov4689_write_register(ViPipe, 0x361b, 0x60); + ov4689_write_register(ViPipe, 0x361c, 0x7a); + ov4689_write_register(ViPipe, 0x361e, 0x79); + ov4689_write_register(ViPipe, 0x361f, 0x02); + ov4689_write_register(ViPipe, 0x3632, 0x00); + ov4689_write_register(ViPipe, 0x3633, 0x10); + ov4689_write_register(ViPipe, 0x3634, 0x10); + ov4689_write_register(ViPipe, 0x3635, 0x10); + ov4689_write_register(ViPipe, 0x3636, 0x15); + ov4689_write_register(ViPipe, 0x3646, 0x86); + ov4689_write_register(ViPipe, 0x364a, 0x0b); + ov4689_write_register(ViPipe, 0x3700, 0x17); + ov4689_write_register(ViPipe, 0x3701, 0x22); + ov4689_write_register(ViPipe, 0x3703, 0x10); + ov4689_write_register(ViPipe, 0x370a, 0x37); + ov4689_write_register(ViPipe, 0x3705, 0x00); + ov4689_write_register(ViPipe, 0x3706, 0x63); + ov4689_write_register(ViPipe, 0x3709, 0x3c); + ov4689_write_register(ViPipe, 0x370b, 0x01); + ov4689_write_register(ViPipe, 0x370c, 0x30); + ov4689_write_register(ViPipe, 0x3710, 0x24); + ov4689_write_register(ViPipe, 0x3711, 0x0c); + ov4689_write_register(ViPipe, 0x3716, 0x00); + ov4689_write_register(ViPipe, 0x3720, 0x28); + ov4689_write_register(ViPipe, 0x3729, 0x7b); + ov4689_write_register(ViPipe, 0x372a, 0x84); + ov4689_write_register(ViPipe, 0x372b, 0xbd); + ov4689_write_register(ViPipe, 0x372c, 0xbc); + ov4689_write_register(ViPipe, 0x372e, 0x52); + ov4689_write_register(ViPipe, 0x373c, 0x0e); + ov4689_write_register(ViPipe, 0x373e, 0x33); + ov4689_write_register(ViPipe, 0x3743, 0x10); + ov4689_write_register(ViPipe, 0x3744, 0x88); + ov4689_write_register(ViPipe, 0x3745, 0xc0); + ov4689_write_register(ViPipe, 0x374a, 0x43); + ov4689_write_register(ViPipe, 0x374c, 0x00); + ov4689_write_register(ViPipe, 0x374e, 0x23); + ov4689_write_register(ViPipe, 0x3751, 0x7b); + ov4689_write_register(ViPipe, 0x3752, 0x84); + ov4689_write_register(ViPipe, 0x3753, 0xbd); + ov4689_write_register(ViPipe, 0x3754, 0xbc); + ov4689_write_register(ViPipe, 0x3756, 0x52); + ov4689_write_register(ViPipe, 0x375c, 0x00); + ov4689_write_register(ViPipe, 0x3760, 0x00); + ov4689_write_register(ViPipe, 0x3761, 0x00); + ov4689_write_register(ViPipe, 0x3762, 0x00); + ov4689_write_register(ViPipe, 0x3763, 0x00); + ov4689_write_register(ViPipe, 0x3764, 0x00); + ov4689_write_register(ViPipe, 0x3767, 0x04); + ov4689_write_register(ViPipe, 0x3768, 0x04); + ov4689_write_register(ViPipe, 0x3769, 0x08); + ov4689_write_register(ViPipe, 0x376a, 0x08); + ov4689_write_register(ViPipe, 0x376b, 0x20); + ov4689_write_register(ViPipe, 0x376c, 0x00); + ov4689_write_register(ViPipe, 0x376d, 0x00); + ov4689_write_register(ViPipe, 0x376e, 0x00); + ov4689_write_register(ViPipe, 0x3773, 0x00); + ov4689_write_register(ViPipe, 0x3774, 0x51); + ov4689_write_register(ViPipe, 0x3776, 0xbd); + ov4689_write_register(ViPipe, 0x3777, 0xbd); + ov4689_write_register(ViPipe, 0x3781, 0x18); + ov4689_write_register(ViPipe, 0x3783, 0x25); + ov4689_write_register(ViPipe, 0x3798, 0x1b); + ov4689_write_register(ViPipe, 0x3800, 0x00); + ov4689_write_register(ViPipe, 0x3801, 0x08); + ov4689_write_register(ViPipe, 0x3802, 0x00); + ov4689_write_register(ViPipe, 0x3803, 0x04); + ov4689_write_register(ViPipe, 0x3804, 0x0a); + ov4689_write_register(ViPipe, 0x3805, 0x97); + ov4689_write_register(ViPipe, 0x3806, 0x05); + ov4689_write_register(ViPipe, 0x3807, 0xfb); + ov4689_write_register(ViPipe, 0x3808, 0x0a); + ov4689_write_register(ViPipe, 0x3809, 0x80); + ov4689_write_register(ViPipe, 0x380a, 0x05); + ov4689_write_register(ViPipe, 0x380b, 0xf0); + ov4689_write_register(ViPipe, 0x380c, 0x0A); + ov4689_write_register(ViPipe, 0x380d, 0x18); + ov4689_write_register(ViPipe, 0x380e, 0x06); + ov4689_write_register(ViPipe, 0x380f, 0x12); + ov4689_write_register(ViPipe, 0x3810, 0x00); + ov4689_write_register(ViPipe, 0x3811, 0x08); + ov4689_write_register(ViPipe, 0x3812, 0x00); + ov4689_write_register(ViPipe, 0x3813, 0x04); + ov4689_write_register(ViPipe, 0x3814, 0x01); + ov4689_write_register(ViPipe, 0x3815, 0x01); + ov4689_write_register(ViPipe, 0x3819, 0x01); + ov4689_write_register(ViPipe, 0x3820, 0x00); + ov4689_write_register(ViPipe, 0x3821, 0x00); + ov4689_write_register(ViPipe, 0x3829, 0x00); + ov4689_write_register(ViPipe, 0x382a, 0x01); + ov4689_write_register(ViPipe, 0x382b, 0x01); + ov4689_write_register(ViPipe, 0x382d, 0x7f); + ov4689_write_register(ViPipe, 0x3830, 0x04); + ov4689_write_register(ViPipe, 0x3836, 0x01); + ov4689_write_register(ViPipe, 0x3837, 0x00); + ov4689_write_register(ViPipe, 0x3841, 0x02); + ov4689_write_register(ViPipe, 0x3846, 0x08); + ov4689_write_register(ViPipe, 0x3847, 0x07); + ov4689_write_register(ViPipe, 0x3d85, 0x36); + ov4689_write_register(ViPipe, 0x3d8c, 0x71); + ov4689_write_register(ViPipe, 0x3d8d, 0xcb); + ov4689_write_register(ViPipe, 0x3f0a, 0x00); + ov4689_write_register(ViPipe, 0x4000, 0xf1); + ov4689_write_register(ViPipe, 0x4001, 0x40); + ov4689_write_register(ViPipe, 0x4002, 0x04); + ov4689_write_register(ViPipe, 0x4003, 0x14); + ov4689_write_register(ViPipe, 0x400e, 0x00); + ov4689_write_register(ViPipe, 0x4011, 0x00); + ov4689_write_register(ViPipe, 0x401a, 0x00); + ov4689_write_register(ViPipe, 0x401b, 0x00); + ov4689_write_register(ViPipe, 0x401c, 0x00); + ov4689_write_register(ViPipe, 0x401d, 0x00); + ov4689_write_register(ViPipe, 0x401f, 0x00); + ov4689_write_register(ViPipe, 0x4020, 0x00); + ov4689_write_register(ViPipe, 0x4021, 0x10); + ov4689_write_register(ViPipe, 0x4022, 0x07); + ov4689_write_register(ViPipe, 0x4023, 0xcf); + ov4689_write_register(ViPipe, 0x4024, 0x09); + ov4689_write_register(ViPipe, 0x4025, 0x60); + ov4689_write_register(ViPipe, 0x4026, 0x09); + ov4689_write_register(ViPipe, 0x4027, 0x6f); + ov4689_write_register(ViPipe, 0x4028, 0x00); + ov4689_write_register(ViPipe, 0x4029, 0x02); + ov4689_write_register(ViPipe, 0x402a, 0x06); + ov4689_write_register(ViPipe, 0x402b, 0x04); + ov4689_write_register(ViPipe, 0x402c, 0x02); + ov4689_write_register(ViPipe, 0x402d, 0x02); + ov4689_write_register(ViPipe, 0x402e, 0x0e); + ov4689_write_register(ViPipe, 0x402f, 0x04); + ov4689_write_register(ViPipe, 0x4302, 0xff); + ov4689_write_register(ViPipe, 0x4303, 0xff); + ov4689_write_register(ViPipe, 0x4304, 0x00); + ov4689_write_register(ViPipe, 0x4305, 0x00); + ov4689_write_register(ViPipe, 0x4306, 0x00); + ov4689_write_register(ViPipe, 0x4308, 0x02); + ov4689_write_register(ViPipe, 0x4500, 0x6c); + ov4689_write_register(ViPipe, 0x4501, 0xc4); + ov4689_write_register(ViPipe, 0x4502, 0x40); + ov4689_write_register(ViPipe, 0x4503, 0x01); + ov4689_write_register(ViPipe, 0x4601, 0xA7); + ov4689_write_register(ViPipe, 0x4800, 0x04); + ov4689_write_register(ViPipe, 0x4813, 0x08); + ov4689_write_register(ViPipe, 0x481f, 0x40); + ov4689_write_register(ViPipe, 0x4829, 0x78); + ov4689_write_register(ViPipe, 0x4837, 0x10); + ov4689_write_register(ViPipe, 0x4b00, 0x2a); + ov4689_write_register(ViPipe, 0x4b0d, 0x00); + ov4689_write_register(ViPipe, 0x4d00, 0x04); + ov4689_write_register(ViPipe, 0x4d01, 0x42); + ov4689_write_register(ViPipe, 0x4d02, 0xd1); + ov4689_write_register(ViPipe, 0x4d03, 0x93); + ov4689_write_register(ViPipe, 0x4d04, 0xf5); + ov4689_write_register(ViPipe, 0x4d05, 0xc1); + ov4689_write_register(ViPipe, 0x5000, 0xf3); + ov4689_write_register(ViPipe, 0x5001, 0x11); + ov4689_write_register(ViPipe, 0x5004, 0x00); + ov4689_write_register(ViPipe, 0x500a, 0x00); + ov4689_write_register(ViPipe, 0x500b, 0x00); + ov4689_write_register(ViPipe, 0x5032, 0x00); + ov4689_write_register(ViPipe, 0x5040, 0x00); + ov4689_write_register(ViPipe, 0x5050, 0x0c); + ov4689_write_register(ViPipe, 0x5500, 0x00); + ov4689_write_register(ViPipe, 0x5501, 0x10); + ov4689_write_register(ViPipe, 0x5502, 0x01); + ov4689_write_register(ViPipe, 0x5503, 0x0f); + ov4689_write_register(ViPipe, 0x8000, 0x00); + ov4689_write_register(ViPipe, 0x8001, 0x00); + ov4689_write_register(ViPipe, 0x8002, 0x00); + ov4689_write_register(ViPipe, 0x8003, 0x00); + ov4689_write_register(ViPipe, 0x8004, 0x00); + ov4689_write_register(ViPipe, 0x8005, 0x00); + ov4689_write_register(ViPipe, 0x8006, 0x00); + ov4689_write_register(ViPipe, 0x8007, 0x00); + ov4689_write_register(ViPipe, 0x8008, 0x00); + ov4689_write_register(ViPipe, 0x3638, 0x00); + + ov4689_default_reg_init(ViPipe); + + ov4689_write_register(ViPipe, 0x0100, 0x01); + + delay_ms(100); + + printf("ViPipe:%d,===OV4689 1520P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + + + + diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_ov6211/Makefile b/middleware/v2/component/isp/sensor/cv180x/ov_ov6211/Makefile new file mode 100644 index 000000000..ec5cc8cb4 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_ov6211/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_ov6211.a +TARGET_SO = $(MW_LIB)/libsns_ov6211.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_ov6211/ov6211_cmos.c b/middleware/v2/component/isp/sensor/cv180x/ov_ov6211/ov6211_cmos.c new file mode 100644 index 000000000..4c3ce796b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_ov6211/ov6211_cmos.c @@ -0,0 +1,966 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "ov6211_cmos_ex.h" +#include "ov6211_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define OV6211_ID 6211 +#define OV6211_I2C_ADDR_1 0x60 +#define OV6211_I2C_ADDR_2 0x70 +#define OV6211_I2C_ADDR_IS_VALID(addr) ((addr) == OV6211_I2C_ADDR_1 || (addr) == OV6211_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastOv6211[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define OV6211_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastOv6211[dev]) +#define OV6211_SENSOR_SET_CTX(dev, pstCtx) (g_pastOv6211[dev] = pstCtx) +#define OV6211_SENSOR_RESET_CTX(dev) (g_pastOv6211[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunOv6211_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Ov6211_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Ov6211_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeOv6211_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Ov6211 Lines Range*****/ +#define OV6211_FULL_LINES_MAX (0xFFFF) + +/*****Ov6211 Register Address*****/ +#define OV6211_EXP_ADDR 0x3500 +#define OV6211_AGAIN_ADDR 0x350a +#define OV6211_VTS_ADDR 0x380E + +#define OV6211_RES_IS_400P(w, h) ((w) == 400 && (h) == 400) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const OV6211_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astOv6211_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = OV6211_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astOv6211_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astOv6211_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astOv6211_mode[pstSnsState->u8ImgMode].f32MinFps; + + + switch (pstSnsState->u8ImgMode) { + case OV6211_MODE_400X400P120: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OV6211_FULL_LINES_MAX) ? OV6211_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_1].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 1 + * max : vts - 4 + * step : 1 + */ + u32MinTime = 1; + u32MaxTime = pstSnsState->au32FL[0] - 4; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_0].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_1].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_2].u32Data = ((u32TmpIntTime & 0x000F) << 4); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +typedef struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} gain_tbl_info_s; + +static struct gain_tbl_info_s AgainInfo[15] = { + { + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x01, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 2944, + .idxBase = 16, + .regGain = 0x02, + .regGainFineBase = 0x00, + .regGainFineStep = 2, + }, + { + .gainMax = 3968, + .idxBase = 24, + .regGain = 0x03, + .regGainFineBase = 0x00, + .regGainFineStep = 2, + }, + { + .gainMax = 4864, + .idxBase = 32, + .regGain = 0x04, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 5888, + .idxBase = 36, + .regGain = 0x05, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 6912, + .idxBase = 40, + .regGain = 0x06, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 7936, + .idxBase = 44, + .regGain = 0x07, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 8704, + .idxBase = 48, + .regGain = 0x08, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 9728, + .idxBase = 50, + .regGain = 0x09, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 10752, + .idxBase = 52, + .regGain = 0x0a, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 11776, + .idxBase = 54, + .regGain = 0x0b, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 12800, + .idxBase = 56, + .regGain = 0x0c, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 13824, + .idxBase = 58, + .regGain = 0x0d, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 14848, + .idxBase = 60, + .regGain = 0x0e, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 15872, + .idxBase = 62, + .regGain = 0x0f, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, +}; + +static CVI_U32 Again_table[64] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[63]) { + *pu32AgainLin = Again_table[63]; + *pu32AgainDb = 63; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + struct gain_tbl_info_s *info; + int i, tbl_num; + + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN0].u32Data = 0x00; + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN1].u32Data = (info->regGain & 0x0F) << 4; + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN1].u32Data |= (u32Again & 0x0F); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const OV6211_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astOv6211_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = OV6211_MODE_400X400P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOv6211_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunOv6211_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = ov6211_i2c_addr; + pstI2c_data[i].u32AddrByteNum = ov6211_addr_byte; + pstI2c_data[i].u32DataByteNum = ov6211_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + pstI2c_data[LINEAR_EXP_0].u32RegAddr = OV6211_EXP_ADDR; + pstI2c_data[LINEAR_EXP_1].u32RegAddr = OV6211_EXP_ADDR + 1; + pstI2c_data[LINEAR_EXP_2].u32RegAddr = OV6211_EXP_ADDR + 2; + pstI2c_data[LINEAR_AGAIN0].u32RegAddr = OV6211_AGAIN_ADDR; + pstI2c_data[LINEAR_AGAIN1].u32RegAddr = OV6211_AGAIN_ADDR + 1; + pstI2c_data[LINEAR_VTS_0].u32RegAddr = OV6211_VTS_ADDR; + pstI2c_data[LINEAR_VTS_1].u32RegAddr = OV6211_VTS_ADDR + 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 120) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (OV6211_RES_IS_400P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OV6211_MODE_400X400P120; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeOv6211_MirrorFip[ViPipe] != eSnsMirrorFlip) { + ov6211_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeOv6211_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = OV6211_MODE_400X400P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOv6211_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astOv6211_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astOv6211_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &ov6211_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astOv6211_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astOv6211_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &ov6211_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = ov6211_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = ov6211_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (OV6211_I2C_ADDR_IS_VALID(s32I2cAddr)) + ov6211_i2c_addr = s32I2cAddr; +} + +static CVI_S32 ov6211_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunOv6211_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OV6211_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + OV6211_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OV6211_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + OV6211_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = OV6211_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, OV6211_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, OV6211_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, OV6211_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Ov6211_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Ov6211_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return ov6211_probe(ViPipe); +} + + +ISP_SNS_OBJ_S stSnsOv6211_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = ov6211_standby, + .pfnRestart = ov6211_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = ov6211_write_register, + .pfnReadReg = ov6211_read_register, + .pfnSetBusInfo = ov6211_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_ov6211/ov6211_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/ov_ov6211/ov6211_cmos_ex.h new file mode 100644 index 000000000..d8427c342 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_ov6211/ov6211_cmos_ex.h @@ -0,0 +1,86 @@ +#ifndef __OV6211_CMOS_EX_H_ +#define __OV6211_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum ov6211_linear_regs_e { + LINEAR_EXP_0 = 0, + LINEAR_EXP_1, + LINEAR_EXP_2, + LINEAR_AGAIN0, + LINEAR_AGAIN1, + LINEAR_VTS_0, + LINEAR_VTS_1, + LINEAR_REGS_NUM +}; + +typedef enum _OV6211_MODE_E { + OV6211_MODE_400X400P120 = 0, + OV6211_MODE_LINEAR_NUM, + OV6211_MODE_NUM +} OV6211_MODE_E; + +typedef struct _OV6211_STATE_S { + CVI_U32 u32Sexp_MAX; +} OV6211_STATE_S; + +typedef struct _OV6211_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + CVI_U16 u16L2sOffset; + CVI_U16 u16TopBoundary; + CVI_U16 u16BotBoundary; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U32 u32L2S_MAX; + char name[64]; +} OV6211_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastOv6211[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunOv6211_BusInfo[]; +extern CVI_U16 g_au16Ov6211_GainMode[]; +extern CVI_U16 g_au16Ov6211_L2SMode[VI_MAX_PIPE_NUM]; +extern CVI_U8 ov6211_i2c_addr; +extern const CVI_U32 ov6211_addr_byte; +extern const CVI_U32 ov6211_data_byte; +extern void ov6211_init(VI_PIPE ViPipe); +extern void ov6211_exit(VI_PIPE ViPipe); +extern void ov6211_standby(VI_PIPE ViPipe); +extern void ov6211_restart(VI_PIPE ViPipe); +extern int ov6211_write_register(VI_PIPE ViPipe, int addr, int data); +extern int ov6211_read_register(VI_PIPE ViPipe, int addr); +extern void ov6211_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int ov6211_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OV6211_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_ov6211/ov6211_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/ov_ov6211/ov6211_cmos_param.h new file mode 100644 index 000000000..1274eb2ab --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_ov6211/ov6211_cmos_param.h @@ -0,0 +1,126 @@ +#ifndef __OV6211_CMOS_PARAM_H_ +#define __OV6211_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "ov6211_cmos_ex.h" + +static const OV6211_MODE_S g_astOv6211_mode[OV6211_MODE_NUM] = { + [OV6211_MODE_400X400P120] = { + .name = "400X400P120", + .astImg[0] = { + .stSnsSize = { + .u32Width = 400, + .u32Height = 400, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 400, + .u32Height = 400, + }, + .stMaxSize = { + .u32Width = 400, + .u32Height = 400, + }, + }, + .f32MaxFps = 120, + .f32MinFps = 0.80, /* 0x1b6 * 120 / 0xFFFF */ + .u32HtsDef = 1522, + .u32VtsDef = 438, + .stExp[0] = { + .u16Min = 1, + .u16Max = 438 - 4, + .u16Def = 100, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {128, 128, 128, 128, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1057, 1057, 1057, 1057 +#endif + }, + .stAuto = { + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, +#endif + }, + }, +}; + +struct combo_dev_attr_s ov6211_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {1, 0, -1, -1, -1}, + .pn_swap = {1, 1, 0, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 8, + } + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OV6211_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_ov6211/ov6211_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/ov_ov6211/ov6211_sensor_ctl.c new file mode 100644 index 000000000..56cef42fe --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_ov6211/ov6211_sensor_ctl.c @@ -0,0 +1,391 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "ov6211_cmos_ex.h" + +static void ov6211_linear_400p120_init(VI_PIPE ViPipe); + +CVI_U8 ov6211_i2c_addr = 0x60; /* I2C Address of OV6211 */ +const CVI_U32 ov6211_addr_byte = 2; +const CVI_U32 ov6211_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int ov6211_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunOv6211_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, ov6211_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int ov6211_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int ov6211_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (ov6211_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, ov6211_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, ov6211_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (ov6211_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; + +} + +int ov6211_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (ov6211_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (ov6211_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, ov6211_addr_byte + ov6211_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void ov6211_standby(VI_PIPE ViPipe) +{ + ov6211_write_register(ViPipe, 0x0100, 0x00); /* standby */ +} + +void ov6211_restart(VI_PIPE ViPipe) +{ + ov6211_write_register(ViPipe, 0x0100, 0x01); /* restart */ +} + +void ov6211_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastOv6211[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastOv6211[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + ov6211_write_register(ViPipe, + g_pastOv6211[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastOv6211[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void ov6211_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 flip, mirror; + + flip = ov6211_read_register(ViPipe, 0x3820); + mirror = ov6211_read_register(ViPipe, 0x3821); + + flip &= ~(0x1 << 2); + mirror &= ~(0x1 << 2); + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + mirror |= 0x1 << 2; + break; + case ISP_SNS_FLIP: + flip |= 0x1 << 2; + break; + case ISP_SNS_MIRROR_FLIP: + flip |= 0x1 << 2; + mirror |= 0x1 << 2; + break; + default: + return; + } + + ov6211_write_register(ViPipe, 0x3820, flip); + ov6211_write_register(ViPipe, 0x3821, mirror); +} + +#define OV6211_CHIP_ID_ADDR_H 0x300A +#define OV6211_CHIP_ID_ADDR_L 0x300B +#define OV6211_CHIP_ID 0x6710 + +int ov6211_probe(VI_PIPE ViPipe) +{ + int nVal, nVal2; + + usleep(500); + if (ov6211_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = ov6211_read_register(ViPipe, OV6211_CHIP_ID_ADDR_H); + nVal2 = ov6211_read_register(ViPipe, OV6211_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | ((nVal2 & 0xFF) << 0)) != OV6211_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void ov6211_init(VI_PIPE ViPipe) +{ + ov6211_i2c_init(ViPipe); + delay_ms(50); + ov6211_linear_400p120_init(ViPipe); + + g_pastOv6211[ViPipe]->bInit = CVI_TRUE; +} + +void ov6211_exit(VI_PIPE ViPipe) +{ + ov6211_i2c_exit(ViPipe); +} + +/* 1944P30 and 1944P25 */ +static void ov6211_linear_400p120_init(VI_PIPE ViPipe) +{ + ov6211_write_register(ViPipe, 0x0103, 0x01); + ov6211_write_register(ViPipe, 0x0100, 0x00); + ov6211_write_register(ViPipe, 0x3005, 0x00); + ov6211_write_register(ViPipe, 0x3013, 0x12); + ov6211_write_register(ViPipe, 0x3014, 0x04); + ov6211_write_register(ViPipe, 0x3016, 0x10); + ov6211_write_register(ViPipe, 0x3017, 0x00); + ov6211_write_register(ViPipe, 0x3018, 0x00); + ov6211_write_register(ViPipe, 0x301a, 0x00); + ov6211_write_register(ViPipe, 0x301b, 0x00); + ov6211_write_register(ViPipe, 0x301c, 0x00); + ov6211_write_register(ViPipe, 0x3037, 0xf0); + ov6211_write_register(ViPipe, 0x3080, 0x01); + ov6211_write_register(ViPipe, 0x3081, 0x00); + ov6211_write_register(ViPipe, 0x3082, 0x01); + ov6211_write_register(ViPipe, 0x3098, 0x04); + ov6211_write_register(ViPipe, 0x3099, 0x28); + ov6211_write_register(ViPipe, 0x309a, 0x06); + ov6211_write_register(ViPipe, 0x309b, 0x04); + ov6211_write_register(ViPipe, 0x309c, 0x00); + ov6211_write_register(ViPipe, 0x309d, 0x00); + ov6211_write_register(ViPipe, 0x309e, 0x01); + ov6211_write_register(ViPipe, 0x309f, 0x00); + ov6211_write_register(ViPipe, 0x30b0, 0x0a); + ov6211_write_register(ViPipe, 0x30b1, 0x02); + ov6211_write_register(ViPipe, 0x30b2, 0x00); + ov6211_write_register(ViPipe, 0x30b3, 0x32); + ov6211_write_register(ViPipe, 0x30b4, 0x02); + ov6211_write_register(ViPipe, 0x30b5, 0x05); + ov6211_write_register(ViPipe, 0x3106, 0xd9); + ov6211_write_register(ViPipe, 0x3500, 0x00); + ov6211_write_register(ViPipe, 0x3501, 0x1b); + ov6211_write_register(ViPipe, 0x3502, 0x20); + ov6211_write_register(ViPipe, 0x3503, 0x07); + ov6211_write_register(ViPipe, 0x3509, 0x10); + ov6211_write_register(ViPipe, 0x350b, 0x10); + ov6211_write_register(ViPipe, 0x3600, 0xfc); + ov6211_write_register(ViPipe, 0x3620, 0xb7); + ov6211_write_register(ViPipe, 0x3621, 0x05); + ov6211_write_register(ViPipe, 0x3626, 0x31); + ov6211_write_register(ViPipe, 0x3627, 0x40); + ov6211_write_register(ViPipe, 0x3632, 0xa3); + ov6211_write_register(ViPipe, 0x3633, 0x34); + ov6211_write_register(ViPipe, 0x3634, 0x40); + ov6211_write_register(ViPipe, 0x3636, 0x00); + ov6211_write_register(ViPipe, 0x3660, 0x80); + ov6211_write_register(ViPipe, 0x3662, 0x01); + ov6211_write_register(ViPipe, 0x3664, 0xf0); + ov6211_write_register(ViPipe, 0x366a, 0x10); + ov6211_write_register(ViPipe, 0x366b, 0x06); + ov6211_write_register(ViPipe, 0x3680, 0xf4); + ov6211_write_register(ViPipe, 0x3681, 0x50); + ov6211_write_register(ViPipe, 0x3682, 0x00); + ov6211_write_register(ViPipe, 0x3708, 0x20); + ov6211_write_register(ViPipe, 0x3709, 0x40); + ov6211_write_register(ViPipe, 0x370d, 0x03); + ov6211_write_register(ViPipe, 0x373b, 0x02); + ov6211_write_register(ViPipe, 0x373c, 0x08); + ov6211_write_register(ViPipe, 0x3742, 0x00); + ov6211_write_register(ViPipe, 0x3744, 0x16); + ov6211_write_register(ViPipe, 0x3745, 0x08); + ov6211_write_register(ViPipe, 0x3781, 0xfc); + ov6211_write_register(ViPipe, 0x3788, 0x00); + ov6211_write_register(ViPipe, 0x3800, 0x00); + ov6211_write_register(ViPipe, 0x3801, 0x04); + ov6211_write_register(ViPipe, 0x3802, 0x00); + ov6211_write_register(ViPipe, 0x3803, 0x04); + ov6211_write_register(ViPipe, 0x3804, 0x01); + ov6211_write_register(ViPipe, 0x3805, 0x9b); + ov6211_write_register(ViPipe, 0x3806, 0x01); + ov6211_write_register(ViPipe, 0x3807, 0x9b); + ov6211_write_register(ViPipe, 0x3808, 0x01); + ov6211_write_register(ViPipe, 0x3809, 0x90); + ov6211_write_register(ViPipe, 0x380a, 0x01); + ov6211_write_register(ViPipe, 0x380b, 0x90); + ov6211_write_register(ViPipe, 0x380c, 0x05); + ov6211_write_register(ViPipe, 0x380d, 0xf2); + ov6211_write_register(ViPipe, 0x380e, 0x01); + ov6211_write_register(ViPipe, 0x380f, 0xb6); + ov6211_write_register(ViPipe, 0x3810, 0x00); + ov6211_write_register(ViPipe, 0x3811, 0x04); + ov6211_write_register(ViPipe, 0x3812, 0x00); + ov6211_write_register(ViPipe, 0x3813, 0x04); + ov6211_write_register(ViPipe, 0x3814, 0x11); + ov6211_write_register(ViPipe, 0x3815, 0x11); + ov6211_write_register(ViPipe, 0x3820, 0x00); + ov6211_write_register(ViPipe, 0x3821, 0x00); + ov6211_write_register(ViPipe, 0x382b, 0xfa); + ov6211_write_register(ViPipe, 0x382f, 0x04); + ov6211_write_register(ViPipe, 0x3832, 0x00); + ov6211_write_register(ViPipe, 0x3833, 0x05); + ov6211_write_register(ViPipe, 0x3834, 0x00); + ov6211_write_register(ViPipe, 0x3835, 0x05); + ov6211_write_register(ViPipe, 0x3882, 0x04); + ov6211_write_register(ViPipe, 0x3883, 0x00); + ov6211_write_register(ViPipe, 0x38a4, 0x10); + ov6211_write_register(ViPipe, 0x38a5, 0x00); + ov6211_write_register(ViPipe, 0x38b1, 0x03); + ov6211_write_register(ViPipe, 0x3b80, 0x00); + ov6211_write_register(ViPipe, 0x3b81, 0xa5); + ov6211_write_register(ViPipe, 0x3b82, 0x10); + ov6211_write_register(ViPipe, 0x3b83, 0x00); + ov6211_write_register(ViPipe, 0x3b84, 0x08); + ov6211_write_register(ViPipe, 0x3b85, 0x00); + ov6211_write_register(ViPipe, 0x3b86, 0x01); + ov6211_write_register(ViPipe, 0x3b87, 0x00); + ov6211_write_register(ViPipe, 0x3b88, 0x00); + ov6211_write_register(ViPipe, 0x3b89, 0x00); + ov6211_write_register(ViPipe, 0x3b8a, 0x00); + ov6211_write_register(ViPipe, 0x3b8b, 0x05); + ov6211_write_register(ViPipe, 0x3b8c, 0x00); + ov6211_write_register(ViPipe, 0x3b8d, 0x00); + ov6211_write_register(ViPipe, 0x3b8e, 0x00); + ov6211_write_register(ViPipe, 0x3b8f, 0x1a); + ov6211_write_register(ViPipe, 0x3b94, 0x05); + ov6211_write_register(ViPipe, 0x3b95, 0xf2); + ov6211_write_register(ViPipe, 0x3b96, 0xf0); + ov6211_write_register(ViPipe, 0x4004, 0x04); + ov6211_write_register(ViPipe, 0x404e, 0x01); + ov6211_write_register(ViPipe, 0x4801, 0x0f); + ov6211_write_register(ViPipe, 0x4806, 0x0f); + + ov6211_write_register(ViPipe, 0x4818, 0x00); + ov6211_write_register(ViPipe, 0x4819, 0xaa); + ov6211_write_register(ViPipe, 0x482a, 0x08); + + ov6211_write_register(ViPipe, 0x481a, 0x00); + ov6211_write_register(ViPipe, 0x481b, 0x4a); + ov6211_write_register(ViPipe, 0x482b, 0x08); + + ov6211_write_register(ViPipe, 0x4837, 0x43); + ov6211_write_register(ViPipe, 0x5a08, 0x00); + ov6211_write_register(ViPipe, 0x5a01, 0x00); + ov6211_write_register(ViPipe, 0x5a03, 0x00); + ov6211_write_register(ViPipe, 0x5a04, 0x10); + ov6211_write_register(ViPipe, 0x5a05, 0xa0); + ov6211_write_register(ViPipe, 0x5a06, 0x0c); + ov6211_write_register(ViPipe, 0x5a07, 0x78); + + ov6211_default_reg_init(ViPipe); + + ov6211_write_register(ViPipe, 0x0100, 0x01); + + delay_ms(100); + + printf("ViPipe:%d,===OV6211 400P 120fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_ov7251/Makefile b/middleware/v2/component/isp/sensor/cv180x/ov_ov7251/Makefile new file mode 100644 index 000000000..880ea8509 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_ov7251/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_ov7251.a +TARGET_SO = $(MW_LIB)/libsns_ov7251.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_ov7251/ov7251_cmos.c b/middleware/v2/component/isp/sensor/cv180x/ov_ov7251/ov7251_cmos.c new file mode 100644 index 000000000..30a0c7adb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_ov7251/ov7251_cmos.c @@ -0,0 +1,967 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "ov7251_cmos_ex.h" +#include "ov7251_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define OV7251_ID 7251 +#define OV7251_I2C_ADDR_1 0x60 +#define OV7251_I2C_ADDR_2 0x70 +#define OV7251_I2C_ADDR_IS_VALID(addr) ((addr) == OV7251_I2C_ADDR_1 || (addr) == OV7251_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastOv7251[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define OV7251_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastOv7251[dev]) +#define OV7251_SENSOR_SET_CTX(dev, pstCtx) (g_pastOv7251[dev] = pstCtx) +#define OV7251_SENSOR_RESET_CTX(dev) (g_pastOv7251[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunOv7251_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Ov7251_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Ov7251_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeOv7251_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Ov7251 Lines Range*****/ +#define OV7251_FULL_LINES_MAX (0xFFFF) + +/*****Ov7251 Register Address*****/ +#define OV7251_EXP_ADDR 0x3500 +#define OV7251_AGAIN_ADDR 0x350a +#define OV7251_VTS_ADDR 0x380E + +#define OV7251_RES_IS_480P(w, h) ((w) == 640 && (h) == 480) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const OV7251_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astOv7251_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = OV7251_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astOv7251_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astOv7251_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astOv7251_mode[pstSnsState->u8ImgMode].f32MinFps; + + + switch (pstSnsState->u8ImgMode) { + case OV7251_MODE_640X480P120: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OV7251_FULL_LINES_MAX) ? OV7251_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_1].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 2 + * max : vts - 20 + * step : 1 + */ + u32MinTime = 2; + u32MaxTime = pstSnsState->au32FL[0] - 20; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_0].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_1].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_2].u32Data = ((u32TmpIntTime & 0x000F) << 4); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +typedef struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} gain_tbl_info_s; + +static struct gain_tbl_info_s AgainInfo[15] = { + { + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x01, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 2944, + .idxBase = 16, + .regGain = 0x02, + .regGainFineBase = 0x00, + .regGainFineStep = 2, + }, + { + .gainMax = 3968, + .idxBase = 24, + .regGain = 0x03, + .regGainFineBase = 0x00, + .regGainFineStep = 2, + }, + { + .gainMax = 4864, + .idxBase = 32, + .regGain = 0x04, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 5888, + .idxBase = 36, + .regGain = 0x05, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 6912, + .idxBase = 40, + .regGain = 0x06, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 7936, + .idxBase = 44, + .regGain = 0x07, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 8704, + .idxBase = 48, + .regGain = 0x08, + .regGainFineBase = 0x08, + .regGainFineStep = 8, + }, + { + .gainMax = 9728, + .idxBase = 49, + .regGain = 0x09, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 10752, + .idxBase = 51, + .regGain = 0x0a, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 11776, + .idxBase = 53, + .regGain = 0x0b, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 12800, + .idxBase = 55, + .regGain = 0x0c, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 13824, + .idxBase = 57, + .regGain = 0x0d, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 14848, + .idxBase = 59, + .regGain = 0x0e, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 15872, + .idxBase = 61, + .regGain = 0x0f, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, +}; + +static CVI_U32 Again_table[] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8704, 9216, 9728, 10240, + 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, 15872 +}; + +static const CVI_U32 again_table_size = ARRAY_SIZE(Again_table); + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[again_table_size - 1]) { + *pu32AgainLin = Again_table[again_table_size - 1]; + *pu32AgainDb = again_table_size - 1; + return CVI_SUCCESS; + } + + for (i = 1; i < again_table_size; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + struct gain_tbl_info_s *info; + int i, tbl_num; + + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN0].u32Data = 0x00; + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN1].u32Data = (info->regGain & 0x0F) << 4; + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN1].u32Data |= (u32Again & 0x0F); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const OV7251_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astOv7251_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = OV7251_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOv7251_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunOv7251_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = ov7251_i2c_addr; + pstI2c_data[i].u32AddrByteNum = ov7251_addr_byte; + pstI2c_data[i].u32DataByteNum = ov7251_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + pstI2c_data[LINEAR_EXP_0].u32RegAddr = OV7251_EXP_ADDR; + pstI2c_data[LINEAR_EXP_1].u32RegAddr = OV7251_EXP_ADDR + 1; + pstI2c_data[LINEAR_EXP_2].u32RegAddr = OV7251_EXP_ADDR + 2; + pstI2c_data[LINEAR_AGAIN0].u32RegAddr = OV7251_AGAIN_ADDR; + pstI2c_data[LINEAR_AGAIN1].u32RegAddr = OV7251_AGAIN_ADDR + 1; + pstI2c_data[LINEAR_VTS_0].u32RegAddr = OV7251_VTS_ADDR; + pstI2c_data[LINEAR_VTS_1].u32RegAddr = OV7251_VTS_ADDR + 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 120) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (OV7251_RES_IS_480P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OV7251_MODE_640X480P120; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeOv7251_MirrorFip[ViPipe] != eSnsMirrorFlip) { + ov7251_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeOv7251_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = OV7251_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOv7251_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astOv7251_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astOv7251_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &ov7251_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astOv7251_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astOv7251_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &ov7251_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = ov7251_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = ov7251_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (OV7251_I2C_ADDR_IS_VALID(s32I2cAddr)) + ov7251_i2c_addr = s32I2cAddr; +} + +static CVI_S32 ov7251_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunOv7251_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OV7251_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + OV7251_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OV7251_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + OV7251_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = OV7251_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, OV7251_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, OV7251_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, OV7251_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Ov7251_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Ov7251_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return ov7251_probe(ViPipe); +} + + +ISP_SNS_OBJ_S stSnsOv7251_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = ov7251_standby, + .pfnRestart = ov7251_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = ov7251_write_register, + .pfnReadReg = ov7251_read_register, + .pfnSetBusInfo = ov7251_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_ov7251/ov7251_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/ov_ov7251/ov7251_cmos_ex.h new file mode 100644 index 000000000..339ec679f --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_ov7251/ov7251_cmos_ex.h @@ -0,0 +1,86 @@ +#ifndef __OV7251_CMOS_EX_H_ +#define __OV7251_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum ov7251_linear_regs_e { + LINEAR_EXP_0 = 0, + LINEAR_EXP_1, + LINEAR_EXP_2, + LINEAR_AGAIN0, + LINEAR_AGAIN1, + LINEAR_VTS_0, + LINEAR_VTS_1, + LINEAR_REGS_NUM +}; + +typedef enum _OV7251_MODE_E { + OV7251_MODE_640X480P120 = 0, + OV7251_MODE_LINEAR_NUM, + OV7251_MODE_NUM +} OV7251_MODE_E; + +typedef struct _OV7251_STATE_S { + CVI_U32 u32Sexp_MAX; +} OV7251_STATE_S; + +typedef struct _OV7251_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + CVI_U16 u16L2sOffset; + CVI_U16 u16TopBoundary; + CVI_U16 u16BotBoundary; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U32 u32L2S_MAX; + char name[64]; +} OV7251_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastOv7251[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunOv7251_BusInfo[]; +extern CVI_U16 g_au16Ov7251_GainMode[]; +extern CVI_U16 g_au16Ov7251_L2SMode[VI_MAX_PIPE_NUM]; +extern CVI_U8 ov7251_i2c_addr; +extern const CVI_U32 ov7251_addr_byte; +extern const CVI_U32 ov7251_data_byte; +extern void ov7251_init(VI_PIPE ViPipe); +extern void ov7251_exit(VI_PIPE ViPipe); +extern void ov7251_standby(VI_PIPE ViPipe); +extern void ov7251_restart(VI_PIPE ViPipe); +extern int ov7251_write_register(VI_PIPE ViPipe, int addr, int data); +extern int ov7251_read_register(VI_PIPE ViPipe, int addr); +extern void ov7251_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int ov7251_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OV7251_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_ov7251/ov7251_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/ov_ov7251/ov7251_cmos_param.h new file mode 100644 index 000000000..adf3415d6 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_ov7251/ov7251_cmos_param.h @@ -0,0 +1,122 @@ +#ifndef __OV7251_CMOS_PARAM_H_ +#define __OV7251_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "ov7251_cmos_ex.h" + +static const OV7251_MODE_S g_astOv7251_mode[OV7251_MODE_NUM] = { + [OV7251_MODE_640X480P120] = { + .name = "640X480P120", + .astImg[0] = { + .stSnsSize = { + .u32Width = 640, + .u32Height = 480, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 640, + .u32Height = 480, + }, + .stMaxSize = { + .u32Width = 640, + .u32Height = 480, + }, + }, + .f32MaxFps = 120, + .f32MinFps = 0.79, /* 0x20a * 100 / 0xFFFF */ + .u32HtsDef = 1522, + .u32VtsDef = 538, + .stExp[0] = { + .u16Min = 2, + .u16Max = 538 - 20, + .u16Def = 100, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {64, 64, 64, 64, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1040, 1040, 1040, 1040 +#endif + }, + .stAuto = { + {64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, +#endif + }, + }, +}; + +struct combo_dev_attr_s ov7251_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {1, 0, -1, -1, -1}, + .pn_swap = {1, 1, 0, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OV7251_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/ov_ov7251/ov7251_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/ov_ov7251/ov7251_sensor_ctl.c new file mode 100644 index 000000000..38d3518bb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/ov_ov7251/ov7251_sensor_ctl.c @@ -0,0 +1,318 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "ov7251_cmos_ex.h" + +static void ov7251_linear_480p120_init(VI_PIPE ViPipe); + +CVI_U8 ov7251_i2c_addr = 0x60; /* I2C Address of OV7251 */ +const CVI_U32 ov7251_addr_byte = 2; +const CVI_U32 ov7251_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int ov7251_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunOv7251_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, ov7251_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int ov7251_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int ov7251_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (ov7251_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, ov7251_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, ov7251_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (ov7251_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; + +} + +int ov7251_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (ov7251_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (ov7251_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, ov7251_addr_byte + ov7251_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void ov7251_standby(VI_PIPE ViPipe) +{ + ov7251_write_register(ViPipe, 0x0100, 0x00); /* standby */ +} + +void ov7251_restart(VI_PIPE ViPipe) +{ + ov7251_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + ov7251_write_register(ViPipe, 0x0100, 0x01); /* restart */ +} + +void ov7251_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastOv7251[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastOv7251[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + ov7251_write_register(ViPipe, + g_pastOv7251[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastOv7251[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void ov7251_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 flip, mirror; + + flip = ov7251_read_register(ViPipe, 0x3820); + mirror = ov7251_read_register(ViPipe, 0x3821); + + flip &= ~(0x1 << 2); + mirror &= ~(0x1 << 2); + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + mirror |= 0x1 << 2; + break; + case ISP_SNS_FLIP: + flip |= 0x1 << 2; + break; + case ISP_SNS_MIRROR_FLIP: + flip |= 0x1 << 2; + mirror |= 0x1 << 2; + break; + default: + return; + } + + ov7251_write_register(ViPipe, 0x3820, flip); + ov7251_write_register(ViPipe, 0x3821, mirror); +} + +#define OV7251_CHIP_ID_ADDR_H 0x300A +#define OV7251_CHIP_ID_ADDR_L 0x300B +#define OV7251_CHIP_ID 0x7750 + +int ov7251_probe(VI_PIPE ViPipe) +{ + int nVal, nVal2; + + if (ov7251_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + delay_ms(5); + + nVal = ov7251_read_register(ViPipe, OV7251_CHIP_ID_ADDR_H); + nVal2 = ov7251_read_register(ViPipe, OV7251_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | ((nVal2 & 0xFF) << 0)) != OV7251_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void ov7251_init(VI_PIPE ViPipe) +{ + ov7251_i2c_init(ViPipe); + + ov7251_linear_480p120_init(ViPipe); + + g_pastOv7251[ViPipe]->bInit = CVI_TRUE; +} + +void ov7251_exit(VI_PIPE ViPipe) +{ + ov7251_i2c_exit(ViPipe); +} + +/* 1944P30 and 1944P25 */ +static void ov7251_linear_480p120_init(VI_PIPE ViPipe) +{ + ov7251_write_register(ViPipe, 0x0103, 0x01); + ov7251_write_register(ViPipe, 0x0100, 0x00); + ov7251_write_register(ViPipe, 0x3012, 0xc0); + ov7251_write_register(ViPipe, 0x3013, 0xd2); + ov7251_write_register(ViPipe, 0x3016, 0x10); + ov7251_write_register(ViPipe, 0x3017, 0x00); + ov7251_write_register(ViPipe, 0x3018, 0x00); + ov7251_write_register(ViPipe, 0x301a, 0x00); + ov7251_write_register(ViPipe, 0x301b, 0x00); + ov7251_write_register(ViPipe, 0x301c, 0x00); + ov7251_write_register(ViPipe, 0x3023, 0x05); + ov7251_write_register(ViPipe, 0x3099, 0x32); + ov7251_write_register(ViPipe, 0x30b3, 0x64); + ov7251_write_register(ViPipe, 0x30b4, 0x03); + ov7251_write_register(ViPipe, 0x30b5, 0x05); + ov7251_write_register(ViPipe, 0x3106, 0xda); + ov7251_write_register(ViPipe, 0x3501, 0x1f); + ov7251_write_register(ViPipe, 0x3502, 0x80); + ov7251_write_register(ViPipe, 0x3503, 0x07); + ov7251_write_register(ViPipe, 0x3600, 0x1c); + ov7251_write_register(ViPipe, 0x3602, 0x62); + ov7251_write_register(ViPipe, 0x3620, 0xb7); + ov7251_write_register(ViPipe, 0x3622, 0x04); + ov7251_write_register(ViPipe, 0x3626, 0x21); + ov7251_write_register(ViPipe, 0x3627, 0x30); + ov7251_write_register(ViPipe, 0x3630, 0x44); + ov7251_write_register(ViPipe, 0x3631, 0x35); + ov7251_write_register(ViPipe, 0x3634, 0x60); + ov7251_write_register(ViPipe, 0x3663, 0x70); + ov7251_write_register(ViPipe, 0x3669, 0x1a); + ov7251_write_register(ViPipe, 0x3673, 0x01); + ov7251_write_register(ViPipe, 0x3674, 0xef); + ov7251_write_register(ViPipe, 0x3675, 0x03); + ov7251_write_register(ViPipe, 0x3705, 0xc1); + ov7251_write_register(ViPipe, 0x3757, 0xb3); + ov7251_write_register(ViPipe, 0x37a8, 0x01); + ov7251_write_register(ViPipe, 0x37a9, 0xc0); + ov7251_write_register(ViPipe, 0x380d, 0xa0); + ov7251_write_register(ViPipe, 0x380f, 0x1a); + ov7251_write_register(ViPipe, 0x3811, 0x04); + ov7251_write_register(ViPipe, 0x3813, 0x05); + ov7251_write_register(ViPipe, 0x3820, 0x40); + ov7251_write_register(ViPipe, 0x382f, 0x0e); + ov7251_write_register(ViPipe, 0x3835, 0x0c); + ov7251_write_register(ViPipe, 0x3b80, 0x00); + ov7251_write_register(ViPipe, 0x3c01, 0x63); + ov7251_write_register(ViPipe, 0x3c07, 0x06); + ov7251_write_register(ViPipe, 0x3c0c, 0x01); + ov7251_write_register(ViPipe, 0x3c0d, 0xd0); + ov7251_write_register(ViPipe, 0x3c0e, 0x02); + ov7251_write_register(ViPipe, 0x3c0f, 0x0a); + ov7251_write_register(ViPipe, 0x4001, 0x42); + ov7251_write_register(ViPipe, 0x404e, 0x01); + ov7251_write_register(ViPipe, 0x4501, 0x48); + ov7251_write_register(ViPipe, 0x4601, 0x4e); + ov7251_write_register(ViPipe, 0x4801, 0x0f); + ov7251_write_register(ViPipe, 0x4819, 0xaa); + ov7251_write_register(ViPipe, 0x4823, 0x3e); + ov7251_write_register(ViPipe, 0x4a47, 0x7f); + ov7251_write_register(ViPipe, 0x4a49, 0xf0); + ov7251_write_register(ViPipe, 0x4a4b, 0x30); + ov7251_write_register(ViPipe, 0x5001, 0x80); + + ov7251_default_reg_init(ViPipe); + + ov7251_write_register(ViPipe, 0x0100, 0x01); + + delay_ms(100); + + printf("ViPipe:%d,===OV7251 480P 120fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2020/Makefile b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2020/Makefile new file mode 100644 index 000000000..7ebc9b71c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2020/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_pr2020.a +TARGET_SO = $(MW_LIB)/libsns_pr2020.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2020/pr2020_cmos.c b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2020/pr2020_cmos.c new file mode 100644 index 000000000..727d3d85e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2020/pr2020_cmos.c @@ -0,0 +1,293 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_isp.h" + +#include "pr2020_cmos_ex.h" +#include "pr2020_cmos_param.h" + +/**************************************************************************** + * global variables * + ****************************************************************************/ +ISP_SNS_COMMBUS_U g_aunPr2020_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_STATE_S *g_pastPr2020[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define PR2020_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastPr2020[dev]) +#define PR2020_SENSOR_SET_CTX(dev, pstCtx) (g_pastPr2020[dev] = pstCtx) +#define PR2020_SENSOR_RESET_CTX(dev) (g_pastPr2020[dev] = CVI_NULL) + +#define PR2020_RES_IS_720P(w, h) ((w) <= 1280 && (h) <= 720) +#define PR2020_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) +#define PR2020_ID 2020 + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const PR2020_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + PR2020_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astPr2020_mode[pstSnsState->u8ImgMode]; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + PR2020_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstCfg0 = &pstSnsState->astSyncInfo[0]; + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + PR2020_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + + if (pstSensorImageMode->f32Fps <= 25) { + if (PR2020_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = PR2020_MODE_720P_25; + } else if (PR2020_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = PR2020_MODE_1080P_25; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSensorImageMode->f32Fps <= 30) { + if (PR2020_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = PR2020_MODE_720P_30; + } else if (PR2020_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = PR2020_MODE_1080P_30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + PR2020_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->u8ImgMode = PR2020_MODE_1080P_25; + pstSnsState->enWDRMode = WDR_MODE_NONE; +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + PR2020_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + if (ViPipe == 0) { + memcpy(pstRxAttr, &pr2020_rx_attr, sizeof(*pstRxAttr)); + CVI_TRACE_SNS(CVI_DBG_INFO, "get pr2020_rx_attr\n"); + } else { + memcpy(pstRxAttr, &pr2020_rx1_attr, sizeof(*pstRxAttr)); + CVI_TRACE_SNS(CVI_DBG_INFO, "get pr2020_rx1_attr\n"); + } + + pstRxAttr->img_size.width = g_astPr2020_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astPr2020_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &pr2020_rx_attr; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = pr2020_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = pr2020_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 pr2020_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunPr2020_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + PR2020_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + PR2020_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + PR2020_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + PR2020_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + (void) pstAeLib; + (void) pstAwbLib; + + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = PR2020_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + (void) pstAeLib; + (void) pstAwbLib; + + CVI_S32 s32Ret; + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, PR2020_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsPR2020_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = CVI_NULL, + .pfnRestart = CVI_NULL, + .pfnMirrorFlip = CVI_NULL, + .pfnWriteReg = pr2020_write_register, + .pfnReadReg = pr2020_read_register, + .pfnSetBusInfo = pr2020_set_bus_info, + .pfnSetInit = CVI_NULL, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = CVI_NULL, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2020/pr2020_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2020/pr2020_cmos_ex.h new file mode 100644 index 000000000..7bd2db22a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2020/pr2020_cmos_ex.h @@ -0,0 +1,70 @@ +#ifndef __PR2020_CMOS_EX_H_ +#define __PR2020_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +typedef enum _PR2020_MODE_E { + PR2020_MODE_NONE, + PR2020_MODE_720H_NTSC, + PR2020_MODE_720H_PAL, + PR2020_MODE_720P_25, + PR2020_MODE_720P_30, + PR2020_MODE_720P_50, + PR2020_MODE_720P_60, + PR2020_MODE_1080P_25, + PR2020_MODE_1080P_30, + PR2020_MODE_NUM +} PR2020_MODE_E; + +typedef struct _PR2020_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + char name[64]; +} PR2020_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastPr2020[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunPr2020_BusInfo[]; +extern const CVI_U8 pr2020_i2c_addr; +extern const CVI_U32 pr2020_addr_byte; +extern const CVI_U32 pr2020_data_byte; +extern void pr2020_init(VI_PIPE ViPipe); +extern void pr2020_exit(VI_PIPE ViPipe); +extern void pr2020_standby(VI_PIPE ViPipe); +extern void pr2020_restart(VI_PIPE ViPipe); +extern int pr2020_write_register(VI_PIPE ViPipe, int addr, int data); +extern int pr2020_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __PR2020_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2020/pr2020_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2020/pr2020_cmos_param.h new file mode 100644 index 000000000..309f92603 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2020/pr2020_cmos_param.h @@ -0,0 +1,146 @@ +#ifndef __PR2020_CMOS_PARAM_H_ +#define __PR2020_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "pr2020_cmos_ex.h" + +static const PR2020_MODE_S g_astPr2020_mode[PR2020_MODE_NUM] = { + [PR2020_MODE_720P_25] = { + .name = "720p25", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + }, + [PR2020_MODE_720P_30] = { + .name = "720p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + }, + [PR2020_MODE_1080P_25] = { + .name = "1080p25", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + }, + [PR2020_MODE_1080P_30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + }, +}; + +struct combo_dev_attr_s pr2020_rx_attr = { + .input_mode = INPUT_MODE_BT656_9B, + .mac_clk = RX_MAC_CLK_200M, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_NONE, + }, + .ttl_attr = { + .vi = TTL_VI_SRC_VI1, + .func = { + -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, + -1, -1, -1, -1, + -1, -1, -1, -1, + }, + }, + .devno = 0, +}; + +struct combo_dev_attr_s pr2020_rx1_attr = { + .input_mode = INPUT_MODE_BT656_9B, + .mac_clk = RX_MAC_CLK_200M, + .mclk = { + .cam = 1, + .freq = CAMPLL_FREQ_NONE, + }, + .ttl_attr = { + .vi = TTL_VI_SRC_VI1, + .func = { + -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, + -1, -1, -1, -1, + -1, -1, -1, -1, + }, + }, + .devno = 1, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __PR2020_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2020/pr2020_sensor_ctrl.c b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2020/pr2020_sensor_ctrl.c new file mode 100644 index 000000000..d50158fdd --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2020/pr2020_sensor_ctrl.c @@ -0,0 +1,1908 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "cvi_vi.h" +#include "pr2020_cmos_ex.h" + +const CVI_U8 pr2020_i2c_addr = 0x5C; /* I2C slave address of PR2020*/ +const CVI_U32 pr2020_addr_byte = 1; +const CVI_U32 pr2020_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; +static pthread_t g_pr2020_thid; +static PR2020_MODE_E signal_type = PR2020_MODE_NONE; + +#define PR2020_AUTO_DETECT 1 + +/*gpio*/ +enum CVI_GPIO_NUM_E { +CVI_GPIOD_00 = 404, +CVI_GPIOD_01, CVI_GPIOD_02, CVI_GPIOD_03, CVI_GPIOD_04, CVI_GPIOD_05, +CVI_GPIOD_06, CVI_GPIOD_07, CVI_GPIOD_08, CVI_GPIOD_09, CVI_GPIOD_10, +CVI_GPIOD_11, +CVI_GPIOC_00 = 416, +CVI_GPIOC_01, CVI_GPIOC_02, CVI_GPIOC_03, CVI_GPIOC_04, CVI_GPIOC_05, +CVI_GPIOC_06, CVI_GPIOC_07, CVI_GPIOC_08, CVI_GPIOC_09, CVI_GPIOC_10, +CVI_GPIOC_11, CVI_GPIOC_12, CVI_GPIOC_13, CVI_GPIOC_14, CVI_GPIOC_15, +CVI_GPIOC_16, CVI_GPIOC_17, CVI_GPIOC_18, CVI_GPIOC_19, CVI_GPIOC_20, +CVI_GPIOC_21, CVI_GPIOC_22, CVI_GPIOC_23, CVI_GPIOC_24, CVI_GPIOC_25, +CVI_GPIOC_26, CVI_GPIOC_27, CVI_GPIOC_28, CVI_GPIOC_29, CVI_GPIOC_30, +CVI_GPIOC_31, +CVI_GPIOB_00 = 448, +CVI_GPIOB_01, CVI_GPIOB_02, CVI_GPIOB_03, CVI_GPIOB_04, CVI_GPIOB_05, +CVI_GPIOB_06, CVI_GPIOB_07, CVI_GPIOB_08, CVI_GPIOB_09, CVI_GPIOB_10, +CVI_GPIOB_11, CVI_GPIOB_12, CVI_GPIOB_13, CVI_GPIOB_14, CVI_GPIOB_15, +CVI_GPIOB_16, CVI_GPIOB_17, CVI_GPIOB_18, CVI_GPIOB_19, CVI_GPIOB_20, +CVI_GPIOB_21, CVI_GPIOB_22, CVI_GPIOB_23, CVI_GPIOB_24, CVI_GPIOB_25, +CVI_GPIOB_26, CVI_GPIOB_27, CVI_GPIOB_28, CVI_GPIOB_29, CVI_GPIOB_30, +CVI_GPIOB_31, +CVI_GPIOA_00 = 480, +CVI_GPIOA_01, CVI_GPIOA_02, CVI_GPIOA_03, CVI_GPIOA_04, CVI_GPIOA_05, +CVI_GPIOA_06, CVI_GPIOA_07, CVI_GPIOA_08, CVI_GPIOA_09, CVI_GPIOA_10, +CVI_GPIOA_11, CVI_GPIOA_12, CVI_GPIOA_13, CVI_GPIOA_14, CVI_GPIOA_15, +CVI_GPIOA_16, CVI_GPIOA_17, CVI_GPIOA_18, CVI_GPIOA_19, CVI_GPIOA_20, +CVI_GPIOA_21, CVI_GPIOA_22, CVI_GPIOA_23, CVI_GPIOA_24, CVI_GPIOA_25, +CVI_GPIOA_26, CVI_GPIOA_27, CVI_GPIOA_28, CVI_GPIOA_29, CVI_GPIOA_30, +CVI_GPIOA_31, +}; + +#define CVI_GPIO_MIN CVI_GPIOD_00 +#define CVI_GPIO_MAX CVI_GPIOA_31 + +#define SYSFS_GPIO_DIR "/sys/class/gpio" +#define MAX_BUF 64 + +static int PR2020_GPIO_Export(unsigned int gpio) +{ + int fd, len; + char buf[MAX_BUF]; + + fd = open(SYSFS_GPIO_DIR"/export", O_WRONLY); + if (fd < 0) { + perror("gpio/export"); + return fd; + } + + len = snprintf(buf, sizeof(buf), "%d", gpio); + write(fd, buf, len); + close(fd); + + return 0; +} + +static int PR2020_GPIO_SetDirection(unsigned int gpio, unsigned int out_flag) +{ + int fd; + char buf[MAX_BUF]; + + snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR"/gpio%d/direction", gpio); + if (access(buf, 0) == -1) + PR2020_GPIO_Export(gpio); + + fd = open(buf, O_WRONLY); + if (fd < 0) { + perror("gpio/direction"); + return fd; + } + //printf("mark %d , %s\n",out_flag, buf); + if (out_flag) + write(fd, "out", 4); + else + write(fd, "in", 3); + + close(fd); + return 0; +} + +static int PR2020_GPIO_SetValue(unsigned int gpio, unsigned int value) +{ + int fd; + char buf[MAX_BUF]; + + snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR"/gpio%d/value", gpio); + if (access(buf, 0) == -1) + PR2020_GPIO_Export(gpio); + + PR2020_GPIO_SetDirection(gpio, 1); //output + + fd = open(buf, O_WRONLY); + if (fd < 0) { + perror("gpio/set-value"); + return fd; + } + + if (value) + write(fd, "1", 2); + else + write(fd, "0", 2); + + close(fd); + return 0; +} + +int pr2020_sys_init(VI_PIPE ViPipe) +{ + (void) ViPipe; + +#if 0 + //AHD_PWR_EN + if (PR2020_GPIO_SetValue(CVI_GPIOA_00, 1) != 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "set power down gpio error!\n"); + return CVI_FAILURE; + } +#endif + //PR2K_RST + if (PR2020_GPIO_SetValue(CVI_GPIOB_12, 1) != 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "set reset gpio error!\n"); + return CVI_FAILURE; + } +#if 0 + //BACK_DET + if (PR2020_GPIO_SetValue(CVI_GPIOD_01, 1) != 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "set back detect gpio error!\n"); + return CVI_FAILURE; + } +#endif + return CVI_SUCCESS; +} + +int pr2020_i2c_init(VI_PIPE ViPipe) +{ + int ret; + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + + u8DevNum = g_aunPr2020_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + CVI_TRACE_SNS(CVI_DBG_INFO, "open %s\n", acDevFile); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, pr2020_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int pr2020_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int pr2020_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return 0; + + if (pr2020_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, pr2020_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, pr2020_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (pr2020_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + CVI_TRACE_SNS(CVI_DBG_INFO, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int pr2020_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (pr2020_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + if (pr2020_data_byte == 2) + buf[idx++] = (data >> 8) & 0xff; + + // add data byte 0 + buf[idx++] = data & 0xff; + + ret = write(g_fd[ViPipe], buf, pr2020_addr_byte + pr2020_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + CVI_TRACE_SNS(CVI_DBG_INFO, "i2c w 0x%x 0x%x\n", addr, data); + +#if 0 // read back checing + ret = pr2020_read_register(ViPipe, addr); + if (ret != data) + CVI_TRACE_SNS(CVI_DBG_INFO, "i2c readback-check fail, 0x%x != 0x%x\n", ret, data); +#endif + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void pr2020_fw_init(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe=%d\n", ViPipe); + + pr2020_write_register(ViPipe, 0xFF, 0x00); + pr2020_write_register(ViPipe, 0xD0, 0x30); + pr2020_write_register(ViPipe, 0xD1, 0x08); + pr2020_write_register(ViPipe, 0xD2, 0x21); + pr2020_write_register(ViPipe, 0xD3, 0x00); + pr2020_write_register(ViPipe, 0xD8, 0x37); + pr2020_write_register(ViPipe, 0xD9, 0x08); + + pr2020_write_register(ViPipe, 0xFF, 0x01); + pr2020_write_register(ViPipe, 0x00, 0xE4);//no-video data, 0xe4: black, 0xe5: blue + pr2020_write_register(ViPipe, 0x01, 0x61); + pr2020_write_register(ViPipe, 0x02, 0x00); + pr2020_write_register(ViPipe, 0x03, 0x57); + pr2020_write_register(ViPipe, 0x04, 0x0C); + pr2020_write_register(ViPipe, 0x05, 0x88); + pr2020_write_register(ViPipe, 0x06, 0x04); + pr2020_write_register(ViPipe, 0x07, 0xB2); + pr2020_write_register(ViPipe, 0x08, 0x44); + pr2020_write_register(ViPipe, 0x09, 0x34); + pr2020_write_register(ViPipe, 0x0A, 0x02); + pr2020_write_register(ViPipe, 0x0B, 0x14); + pr2020_write_register(ViPipe, 0x0C, 0x04); + pr2020_write_register(ViPipe, 0x0D, 0x08); + pr2020_write_register(ViPipe, 0x0E, 0x5E); + pr2020_write_register(ViPipe, 0x0F, 0x5E); + pr2020_write_register(ViPipe, 0x10, 0x26); +} + +void pr2020_set_cvbs_ntsc_60(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe=%d\n", ViPipe); + + //Page0 sys + pr2020_write_register(ViPipe, 0xff, 0x00); + pr2020_write_register(ViPipe, 0x10, 0x30); + pr2020_write_register(ViPipe, 0x11, 0x07); + pr2020_write_register(ViPipe, 0x12, 0x00); + pr2020_write_register(ViPipe, 0x13, 0x00); + pr2020_write_register(ViPipe, 0x14, 0x21);//b[1:0); => Select Camera Input. VinP(1), VinN(3), Differ(0). + pr2020_write_register(ViPipe, 0x15, 0x44); + pr2020_write_register(ViPipe, 0x16, 0x0d); + pr2020_write_register(ViPipe, 0x40, 0x00); + pr2020_write_register(ViPipe, 0x47, 0x36); + pr2020_write_register(ViPipe, 0x4e, 0x3f); + pr2020_write_register(ViPipe, 0x80, 0x56); + pr2020_write_register(ViPipe, 0x81, 0x0e); + pr2020_write_register(ViPipe, 0x82, 0x0d); + pr2020_write_register(ViPipe, 0x84, 0x30); + pr2020_write_register(ViPipe, 0x86, 0x20); + pr2020_write_register(ViPipe, 0x87, 0x00); + pr2020_write_register(ViPipe, 0x8a, 0x00); + pr2020_write_register(ViPipe, 0x90, 0x00); + pr2020_write_register(ViPipe, 0x91, 0x00); + pr2020_write_register(ViPipe, 0x92, 0x00); + pr2020_write_register(ViPipe, 0x94, 0xff); + pr2020_write_register(ViPipe, 0x95, 0xff); + pr2020_write_register(ViPipe, 0x96, 0xff); + pr2020_write_register(ViPipe, 0xa0, 0x00); + pr2020_write_register(ViPipe, 0xa1, 0x20); + pr2020_write_register(ViPipe, 0xa4, 0x01); + pr2020_write_register(ViPipe, 0xa5, 0xe3); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0x12); + pr2020_write_register(ViPipe, 0xa8, 0x00); + pr2020_write_register(ViPipe, 0xd0, 0x30); + pr2020_write_register(ViPipe, 0xd1, 0x08); + pr2020_write_register(ViPipe, 0xd2, 0x21); + pr2020_write_register(ViPipe, 0xd3, 0x00); + pr2020_write_register(ViPipe, 0xd8, 0x31); + pr2020_write_register(ViPipe, 0xd9, 0x08); + pr2020_write_register(ViPipe, 0xda, 0x21); + pr2020_write_register(ViPipe, 0xe0, 0x3e); + pr2020_write_register(ViPipe, 0xe1, 0x80); + pr2020_write_register(ViPipe, 0xe2, 0x38); + pr2020_write_register(ViPipe, 0xe3, 0x19); + pr2020_write_register(ViPipe, 0xe4, 0x19); + pr2020_write_register(ViPipe, 0xea, 0x01); + pr2020_write_register(ViPipe, 0xeb, 0xff); + pr2020_write_register(ViPipe, 0xf1, 0x44); + pr2020_write_register(ViPipe, 0xf2, 0x01); + + //Page1 vdec + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x00, 0xe4); + pr2020_write_register(ViPipe, 0x01, 0x61); + pr2020_write_register(ViPipe, 0x02, 0x00); + pr2020_write_register(ViPipe, 0x03, 0x57); + pr2020_write_register(ViPipe, 0x04, 0x0c); + pr2020_write_register(ViPipe, 0x05, 0x88); + pr2020_write_register(ViPipe, 0x06, 0x04); + pr2020_write_register(ViPipe, 0x07, 0xb2); + pr2020_write_register(ViPipe, 0x08, 0x44); + pr2020_write_register(ViPipe, 0x09, 0x34); + pr2020_write_register(ViPipe, 0x0a, 0x02); + pr2020_write_register(ViPipe, 0x0b, 0x14); + pr2020_write_register(ViPipe, 0x0c, 0x04); + pr2020_write_register(ViPipe, 0x0d, 0x08); + pr2020_write_register(ViPipe, 0x0e, 0x5e); + pr2020_write_register(ViPipe, 0x0f, 0x5e); + pr2020_write_register(ViPipe, 0x10, 0x26); + pr2020_write_register(ViPipe, 0x11, 0x00); + pr2020_write_register(ViPipe, 0x12, 0x02); + pr2020_write_register(ViPipe, 0x13, 0x90); + pr2020_write_register(ViPipe, 0x14, 0xd0); + pr2020_write_register(ViPipe, 0x15, 0x10); + pr2020_write_register(ViPipe, 0x16, 0xf0); + pr2020_write_register(ViPipe, 0x17, 0x00); + pr2020_write_register(ViPipe, 0x18, 0x21); + pr2020_write_register(ViPipe, 0x19, 0x4a); + pr2020_write_register(ViPipe, 0x1a, 0x20); + pr2020_write_register(ViPipe, 0x1b, 0x07); + pr2020_write_register(ViPipe, 0x1c, 0x00); + pr2020_write_register(ViPipe, 0x1d, 0x42); + pr2020_write_register(ViPipe, 0x1e, 0x40); + pr2020_write_register(ViPipe, 0x1f, 0xd0); + pr2020_write_register(ViPipe, 0x20, 0x80); + pr2020_write_register(ViPipe, 0x21, 0x70); + pr2020_write_register(ViPipe, 0x22, 0x65); + pr2020_write_register(ViPipe, 0x23, 0x83); + pr2020_write_register(ViPipe, 0x24, 0x80); + pr2020_write_register(ViPipe, 0x25, 0x80); + pr2020_write_register(ViPipe, 0x26, 0x84); + pr2020_write_register(ViPipe, 0x27, 0x80); + pr2020_write_register(ViPipe, 0x28, 0x00); + pr2020_write_register(ViPipe, 0x29, 0x5f); + pr2020_write_register(ViPipe, 0x2a, 0x20); + pr2020_write_register(ViPipe, 0x2b, 0x00); + pr2020_write_register(ViPipe, 0x2c, 0x00); + pr2020_write_register(ViPipe, 0x2d, 0x00); + pr2020_write_register(ViPipe, 0x2e, 0x00); + pr2020_write_register(ViPipe, 0x2f, 0x00); + pr2020_write_register(ViPipe, 0x30, 0x00); + pr2020_write_register(ViPipe, 0x31, 0x00); + pr2020_write_register(ViPipe, 0x32, 0xc0); + pr2020_write_register(ViPipe, 0x33, 0x14); + pr2020_write_register(ViPipe, 0x34, 0x14); + pr2020_write_register(ViPipe, 0x35, 0x80); + pr2020_write_register(ViPipe, 0x36, 0x80); + pr2020_write_register(ViPipe, 0x37, 0xe2); + pr2020_write_register(ViPipe, 0x38, 0x41); + pr2020_write_register(ViPipe, 0x39, 0x00); + pr2020_write_register(ViPipe, 0x3a, 0xac); + pr2020_write_register(ViPipe, 0x3b, 0x04); + pr2020_write_register(ViPipe, 0x3c, 0x01); + pr2020_write_register(ViPipe, 0x3d, 0x21); + pr2020_write_register(ViPipe, 0x3e, 0x06); + pr2020_write_register(ViPipe, 0x3f, 0xd5); + pr2020_write_register(ViPipe, 0x40, 0x05); + pr2020_write_register(ViPipe, 0x41, 0x55); + pr2020_write_register(ViPipe, 0x42, 0x01); + pr2020_write_register(ViPipe, 0x43, 0x30); + pr2020_write_register(ViPipe, 0x44, 0x6a); + pr2020_write_register(ViPipe, 0x45, 0x00); + pr2020_write_register(ViPipe, 0x46, 0x06); + pr2020_write_register(ViPipe, 0x47, 0x2b); + pr2020_write_register(ViPipe, 0x48, 0xb9); + pr2020_write_register(ViPipe, 0x49, 0x00); + pr2020_write_register(ViPipe, 0x4a, 0x7b); + pr2020_write_register(ViPipe, 0x4b, 0x60); + pr2020_write_register(ViPipe, 0x4c, 0x00); + pr2020_write_register(ViPipe, 0x4d, 0x47); + pr2020_write_register(ViPipe, 0x4e, 0x02); + pr2020_write_register(ViPipe, 0x4f, 0x20); + pr2020_write_register(ViPipe, 0x50, 0x01); + pr2020_write_register(ViPipe, 0x51, 0x28); + pr2020_write_register(ViPipe, 0x52, 0x40); + pr2020_write_register(ViPipe, 0x53, 0x0c); + pr2020_write_register(ViPipe, 0x54, 0x0f); + pr2020_write_register(ViPipe, 0x55, 0x8d); + pr2020_write_register(ViPipe, 0x70, 0x06); + pr2020_write_register(ViPipe, 0x71, 0x08); + pr2020_write_register(ViPipe, 0x72, 0x0a); + pr2020_write_register(ViPipe, 0x73, 0x0c); + pr2020_write_register(ViPipe, 0x74, 0x0e); + pr2020_write_register(ViPipe, 0x75, 0x10); + pr2020_write_register(ViPipe, 0x76, 0x12); + pr2020_write_register(ViPipe, 0x77, 0x14); + pr2020_write_register(ViPipe, 0x78, 0x06); + pr2020_write_register(ViPipe, 0x79, 0x08); + pr2020_write_register(ViPipe, 0x7a, 0x0a); + pr2020_write_register(ViPipe, 0x7b, 0x0c); + pr2020_write_register(ViPipe, 0x7c, 0x0e); + pr2020_write_register(ViPipe, 0x7d, 0x10); + pr2020_write_register(ViPipe, 0x7e, 0x12); + pr2020_write_register(ViPipe, 0x7f, 0x14); + pr2020_write_register(ViPipe, 0x80, 0x00); + pr2020_write_register(ViPipe, 0x81, 0x09); + pr2020_write_register(ViPipe, 0x82, 0x00); + pr2020_write_register(ViPipe, 0x83, 0x07); + pr2020_write_register(ViPipe, 0x84, 0x00); + pr2020_write_register(ViPipe, 0x85, 0x17); + pr2020_write_register(ViPipe, 0x86, 0x03); + pr2020_write_register(ViPipe, 0x87, 0xe5); + pr2020_write_register(ViPipe, 0x88, 0x04); + pr2020_write_register(ViPipe, 0x89, 0x48); + pr2020_write_register(ViPipe, 0x8a, 0x04); + pr2020_write_register(ViPipe, 0x8b, 0x48); + pr2020_write_register(ViPipe, 0x8c, 0x05); + pr2020_write_register(ViPipe, 0x8d, 0xf0); + pr2020_write_register(ViPipe, 0x8e, 0x05); + pr2020_write_register(ViPipe, 0x8f, 0x47); + pr2020_write_register(ViPipe, 0x90, 0x03); + pr2020_write_register(ViPipe, 0x91, 0x13); + pr2020_write_register(ViPipe, 0x92, 0x73); + pr2020_write_register(ViPipe, 0x93, 0xe8); + pr2020_write_register(ViPipe, 0x94, 0x0f); + pr2020_write_register(ViPipe, 0x95, 0x5e); + pr2020_write_register(ViPipe, 0x96, 0x03); + pr2020_write_register(ViPipe, 0x97, 0xd0); + pr2020_write_register(ViPipe, 0x98, 0x17); + pr2020_write_register(ViPipe, 0x99, 0x34); + pr2020_write_register(ViPipe, 0x9a, 0x13); + pr2020_write_register(ViPipe, 0x9b, 0x56); + pr2020_write_register(ViPipe, 0x9c, 0x0b); + pr2020_write_register(ViPipe, 0x9d, 0x9a); + pr2020_write_register(ViPipe, 0x9e, 0x09); + pr2020_write_register(ViPipe, 0x9f, 0xab); + pr2020_write_register(ViPipe, 0xa0, 0x01); + pr2020_write_register(ViPipe, 0xa1, 0x74); + pr2020_write_register(ViPipe, 0xa2, 0x01); + pr2020_write_register(ViPipe, 0xa3, 0x6b); + pr2020_write_register(ViPipe, 0xa4, 0x00); + pr2020_write_register(ViPipe, 0xa5, 0xba); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0xa3); + pr2020_write_register(ViPipe, 0xa8, 0x01); + pr2020_write_register(ViPipe, 0xa9, 0x39); + pr2020_write_register(ViPipe, 0xaa, 0x01); + pr2020_write_register(ViPipe, 0xab, 0x39); + pr2020_write_register(ViPipe, 0xac, 0x00); + pr2020_write_register(ViPipe, 0xad, 0xc1); + pr2020_write_register(ViPipe, 0xae, 0x00); + pr2020_write_register(ViPipe, 0xaf, 0xc1); + pr2020_write_register(ViPipe, 0xb0, 0x04); + pr2020_write_register(ViPipe, 0xb1, 0xd4); + pr2020_write_register(ViPipe, 0xb2, 0x07); + pr2020_write_register(ViPipe, 0xb3, 0xda); + pr2020_write_register(ViPipe, 0xb4, 0x00); + pr2020_write_register(ViPipe, 0xb5, 0x17); + pr2020_write_register(ViPipe, 0xb6, 0x08); + pr2020_write_register(ViPipe, 0xb7, 0xe8); + pr2020_write_register(ViPipe, 0xb8, 0xb0); + pr2020_write_register(ViPipe, 0xb9, 0xce); + pr2020_write_register(ViPipe, 0xba, 0x90); + pr2020_write_register(ViPipe, 0xbb, 0x10); + pr2020_write_register(ViPipe, 0xbc, 0x00); + pr2020_write_register(ViPipe, 0xbd, 0x04); + pr2020_write_register(ViPipe, 0xbe, 0x02); + pr2020_write_register(ViPipe, 0xbf, 0xd0); + pr2020_write_register(ViPipe, 0xc0, 0x00); + pr2020_write_register(ViPipe, 0xc1, 0x10); + pr2020_write_register(ViPipe, 0xc2, 0x00); + pr2020_write_register(ViPipe, 0xc3, 0xf0); + + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0e); + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0f); +} + +void pr2020_set_cvbs_pal_50(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe=%d\n", ViPipe); + + //Page0 sys + pr2020_write_register(ViPipe, 0xff, 0x00); + pr2020_write_register(ViPipe, 0x10, 0x21); + pr2020_write_register(ViPipe, 0x11, 0x07); + pr2020_write_register(ViPipe, 0x12, 0x00); + pr2020_write_register(ViPipe, 0x13, 0x00); + pr2020_write_register(ViPipe, 0x14, 0x21);//b[1:0); => Select Camera Input. VinP(1), VinN(3), Differ(0). + pr2020_write_register(ViPipe, 0x15, 0x44); + pr2020_write_register(ViPipe, 0x16, 0x0d); + pr2020_write_register(ViPipe, 0x40, 0x00); + pr2020_write_register(ViPipe, 0x47, 0x36); + pr2020_write_register(ViPipe, 0x4e, 0x3f); + pr2020_write_register(ViPipe, 0x80, 0x56); + pr2020_write_register(ViPipe, 0x81, 0x0e); + pr2020_write_register(ViPipe, 0x82, 0x0d); + pr2020_write_register(ViPipe, 0x84, 0x30); + pr2020_write_register(ViPipe, 0x86, 0x20); + pr2020_write_register(ViPipe, 0x87, 0x00); + pr2020_write_register(ViPipe, 0x8a, 0x00); + pr2020_write_register(ViPipe, 0x90, 0x00); + pr2020_write_register(ViPipe, 0x91, 0x00); + pr2020_write_register(ViPipe, 0x92, 0x00); + pr2020_write_register(ViPipe, 0x94, 0xff); + pr2020_write_register(ViPipe, 0x95, 0xff); + pr2020_write_register(ViPipe, 0x96, 0xff); + pr2020_write_register(ViPipe, 0xa0, 0x00); + pr2020_write_register(ViPipe, 0xa1, 0x20); + pr2020_write_register(ViPipe, 0xa4, 0x01); + pr2020_write_register(ViPipe, 0xa5, 0xe3); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0x12); + pr2020_write_register(ViPipe, 0xa8, 0x00); + pr2020_write_register(ViPipe, 0xd0, 0x30); + pr2020_write_register(ViPipe, 0xd1, 0x08); + pr2020_write_register(ViPipe, 0xd2, 0x21); + pr2020_write_register(ViPipe, 0xd3, 0x00); + pr2020_write_register(ViPipe, 0xd8, 0x31); + pr2020_write_register(ViPipe, 0xd9, 0x08); + pr2020_write_register(ViPipe, 0xda, 0x21); + pr2020_write_register(ViPipe, 0xe0, 0x3e); + pr2020_write_register(ViPipe, 0xe1, 0x80); + pr2020_write_register(ViPipe, 0xe2, 0x38); + pr2020_write_register(ViPipe, 0xe3, 0x19); + pr2020_write_register(ViPipe, 0xe4, 0x19); + pr2020_write_register(ViPipe, 0xea, 0x01); + pr2020_write_register(ViPipe, 0xeb, 0xff); + pr2020_write_register(ViPipe, 0xf1, 0x44); + pr2020_write_register(ViPipe, 0xf2, 0x01); + + //Page1 vdec + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x00, 0xe4); + pr2020_write_register(ViPipe, 0x01, 0x61); + pr2020_write_register(ViPipe, 0x02, 0x00); + pr2020_write_register(ViPipe, 0x03, 0x57); + pr2020_write_register(ViPipe, 0x04, 0x0c); + pr2020_write_register(ViPipe, 0x05, 0x88); + pr2020_write_register(ViPipe, 0x06, 0x04); + pr2020_write_register(ViPipe, 0x07, 0xb2); + pr2020_write_register(ViPipe, 0x08, 0x44); + pr2020_write_register(ViPipe, 0x09, 0x34); + pr2020_write_register(ViPipe, 0x0a, 0x02); + pr2020_write_register(ViPipe, 0x0b, 0x14); + pr2020_write_register(ViPipe, 0x0c, 0x04); + pr2020_write_register(ViPipe, 0x0d, 0x08); + pr2020_write_register(ViPipe, 0x0e, 0x5e); + pr2020_write_register(ViPipe, 0x0f, 0x5e); + pr2020_write_register(ViPipe, 0x10, 0x26); + pr2020_write_register(ViPipe, 0x11, 0x00); + pr2020_write_register(ViPipe, 0x12, 0x22); + pr2020_write_register(ViPipe, 0x13, 0xe0); + pr2020_write_register(ViPipe, 0x14, 0xd0); + pr2020_write_register(ViPipe, 0x15, 0x16); + pr2020_write_register(ViPipe, 0x16, 0x20); + pr2020_write_register(ViPipe, 0x17, 0x00); + pr2020_write_register(ViPipe, 0x18, 0x21); + pr2020_write_register(ViPipe, 0x19, 0x4a); + pr2020_write_register(ViPipe, 0x1a, 0x20); + pr2020_write_register(ViPipe, 0x1b, 0x06); + pr2020_write_register(ViPipe, 0x1c, 0x31); + pr2020_write_register(ViPipe, 0x1d, 0x42); + pr2020_write_register(ViPipe, 0x1e, 0x50); + pr2020_write_register(ViPipe, 0x1f, 0xd0); + pr2020_write_register(ViPipe, 0x20, 0x80); + pr2020_write_register(ViPipe, 0x21, 0x75); + pr2020_write_register(ViPipe, 0x22, 0x65); + pr2020_write_register(ViPipe, 0x23, 0x83); + pr2020_write_register(ViPipe, 0x24, 0x80); + pr2020_write_register(ViPipe, 0x25, 0x80); + pr2020_write_register(ViPipe, 0x26, 0x84); + pr2020_write_register(ViPipe, 0x27, 0x80); + pr2020_write_register(ViPipe, 0x28, 0x00); + pr2020_write_register(ViPipe, 0x29, 0x5f); + pr2020_write_register(ViPipe, 0x2a, 0x20); + pr2020_write_register(ViPipe, 0x2b, 0x00); + pr2020_write_register(ViPipe, 0x2c, 0x00); + pr2020_write_register(ViPipe, 0x2d, 0x00); + pr2020_write_register(ViPipe, 0x2e, 0x00); + pr2020_write_register(ViPipe, 0x2f, 0x00); + pr2020_write_register(ViPipe, 0x30, 0x00); + pr2020_write_register(ViPipe, 0x31, 0x00); + pr2020_write_register(ViPipe, 0x32, 0xc0); + pr2020_write_register(ViPipe, 0x33, 0x20); + pr2020_write_register(ViPipe, 0x34, 0x20); + pr2020_write_register(ViPipe, 0x35, 0x10); + pr2020_write_register(ViPipe, 0x36, 0x10); + pr2020_write_register(ViPipe, 0x37, 0xc4); + pr2020_write_register(ViPipe, 0x38, 0x42); + pr2020_write_register(ViPipe, 0x39, 0x00); + pr2020_write_register(ViPipe, 0x3a, 0xac); + pr2020_write_register(ViPipe, 0x3b, 0x04); + pr2020_write_register(ViPipe, 0x3c, 0x01); + pr2020_write_register(ViPipe, 0x3d, 0x21); + pr2020_write_register(ViPipe, 0x3e, 0x06); + pr2020_write_register(ViPipe, 0x3f, 0xd5); + pr2020_write_register(ViPipe, 0x40, 0x85); + pr2020_write_register(ViPipe, 0x41, 0x55); + pr2020_write_register(ViPipe, 0x42, 0x01); + pr2020_write_register(ViPipe, 0x43, 0x31); + pr2020_write_register(ViPipe, 0x44, 0x6a); + pr2020_write_register(ViPipe, 0x45, 0x00); + pr2020_write_register(ViPipe, 0x46, 0x07); + pr2020_write_register(ViPipe, 0x47, 0xa4); + pr2020_write_register(ViPipe, 0x48, 0xa5); + pr2020_write_register(ViPipe, 0x49, 0x00); + pr2020_write_register(ViPipe, 0x4a, 0x7b); + pr2020_write_register(ViPipe, 0x4b, 0x60); + pr2020_write_register(ViPipe, 0x4c, 0x00); + pr2020_write_register(ViPipe, 0x4d, 0x47); + pr2020_write_register(ViPipe, 0x4e, 0x02); + pr2020_write_register(ViPipe, 0x4f, 0x20); + pr2020_write_register(ViPipe, 0x50, 0x01); + pr2020_write_register(ViPipe, 0x51, 0x28); + pr2020_write_register(ViPipe, 0x52, 0x40); + pr2020_write_register(ViPipe, 0x53, 0x0c); + pr2020_write_register(ViPipe, 0x54, 0x0f); + pr2020_write_register(ViPipe, 0x55, 0x8d); + pr2020_write_register(ViPipe, 0x70, 0x06); + pr2020_write_register(ViPipe, 0x71, 0x08); + pr2020_write_register(ViPipe, 0x72, 0x0a); + pr2020_write_register(ViPipe, 0x73, 0x0c); + pr2020_write_register(ViPipe, 0x74, 0x0e); + pr2020_write_register(ViPipe, 0x75, 0x10); + pr2020_write_register(ViPipe, 0x76, 0x12); + pr2020_write_register(ViPipe, 0x77, 0x14); + pr2020_write_register(ViPipe, 0x78, 0x06); + pr2020_write_register(ViPipe, 0x79, 0x08); + pr2020_write_register(ViPipe, 0x7a, 0x0a); + pr2020_write_register(ViPipe, 0x7b, 0x0c); + pr2020_write_register(ViPipe, 0x7c, 0x0e); + pr2020_write_register(ViPipe, 0x7d, 0x10); + pr2020_write_register(ViPipe, 0x7e, 0x12); + pr2020_write_register(ViPipe, 0x7f, 0x14); + pr2020_write_register(ViPipe, 0x80, 0x00); + pr2020_write_register(ViPipe, 0x81, 0x09); + pr2020_write_register(ViPipe, 0x82, 0x00); + pr2020_write_register(ViPipe, 0x83, 0x07); + pr2020_write_register(ViPipe, 0x84, 0x00); + pr2020_write_register(ViPipe, 0x85, 0x17); + pr2020_write_register(ViPipe, 0x86, 0x03); + pr2020_write_register(ViPipe, 0x87, 0xe5); + pr2020_write_register(ViPipe, 0x88, 0x05); + pr2020_write_register(ViPipe, 0x89, 0x24); + pr2020_write_register(ViPipe, 0x8a, 0x05); + pr2020_write_register(ViPipe, 0x8b, 0x24); + pr2020_write_register(ViPipe, 0x8c, 0x05); + pr2020_write_register(ViPipe, 0x8d, 0xf0); + pr2020_write_register(ViPipe, 0x8e, 0x05); + pr2020_write_register(ViPipe, 0x8f, 0x47); + pr2020_write_register(ViPipe, 0x90, 0x02); + pr2020_write_register(ViPipe, 0x91, 0xb4); + pr2020_write_register(ViPipe, 0x92, 0x73); + pr2020_write_register(ViPipe, 0x93, 0xe8); + pr2020_write_register(ViPipe, 0x94, 0x0f); + pr2020_write_register(ViPipe, 0x95, 0x5e); + pr2020_write_register(ViPipe, 0x96, 0x03); + pr2020_write_register(ViPipe, 0x97, 0xd0); + pr2020_write_register(ViPipe, 0x98, 0x17); + pr2020_write_register(ViPipe, 0x99, 0x34); + pr2020_write_register(ViPipe, 0x9a, 0x13); + pr2020_write_register(ViPipe, 0x9b, 0x56); + pr2020_write_register(ViPipe, 0x9c, 0x0b); + pr2020_write_register(ViPipe, 0x9d, 0x9a); + pr2020_write_register(ViPipe, 0x9e, 0x09); + pr2020_write_register(ViPipe, 0x9f, 0xab); + pr2020_write_register(ViPipe, 0xa0, 0x01); + pr2020_write_register(ViPipe, 0xa1, 0x74); + pr2020_write_register(ViPipe, 0xa2, 0x01); + pr2020_write_register(ViPipe, 0xa3, 0x6b); + pr2020_write_register(ViPipe, 0xa4, 0x00); + pr2020_write_register(ViPipe, 0xa5, 0xba); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0xa3); + pr2020_write_register(ViPipe, 0xa8, 0x01); + pr2020_write_register(ViPipe, 0xa9, 0x39); + pr2020_write_register(ViPipe, 0xaa, 0x01); + pr2020_write_register(ViPipe, 0xab, 0x39); + pr2020_write_register(ViPipe, 0xac, 0x00); + pr2020_write_register(ViPipe, 0xad, 0xc1); + pr2020_write_register(ViPipe, 0xae, 0x00); + pr2020_write_register(ViPipe, 0xaf, 0xc1); + pr2020_write_register(ViPipe, 0xb0, 0x05); + pr2020_write_register(ViPipe, 0xb1, 0xcc); + pr2020_write_register(ViPipe, 0xb2, 0x09); + pr2020_write_register(ViPipe, 0xb3, 0x6d); + pr2020_write_register(ViPipe, 0xb4, 0x00); + pr2020_write_register(ViPipe, 0xb5, 0x17); + pr2020_write_register(ViPipe, 0xb6, 0x08); + pr2020_write_register(ViPipe, 0xb7, 0xe8); + pr2020_write_register(ViPipe, 0xb8, 0xb0); + pr2020_write_register(ViPipe, 0xb9, 0xce); + pr2020_write_register(ViPipe, 0xba, 0x90); + pr2020_write_register(ViPipe, 0xbb, 0x10); + pr2020_write_register(ViPipe, 0xbc, 0x00); + pr2020_write_register(ViPipe, 0xbd, 0x04); + pr2020_write_register(ViPipe, 0xbe, 0x02); + pr2020_write_register(ViPipe, 0xbf, 0xd0); + pr2020_write_register(ViPipe, 0xc0, 0x00); + pr2020_write_register(ViPipe, 0xc1, 0x16); + pr2020_write_register(ViPipe, 0xc2, 0x01); + pr2020_write_register(ViPipe, 0xc3, 0x20); + + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0e); + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0f); +} + +void pr2020_set_720p_25(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe=%d\n", ViPipe); + + //Page0 sys + pr2020_write_register(ViPipe, 0xff, 0x00); + pr2020_write_register(ViPipe, 0x10, 0x82); + pr2020_write_register(ViPipe, 0x11, 0x07); + pr2020_write_register(ViPipe, 0x12, 0x00); + pr2020_write_register(ViPipe, 0x13, 0x00); + pr2020_write_register(ViPipe, 0x14, 0x21);//b[1:0); => Select Camera Input. VinP(1), VinN(3), Differ(0). + pr2020_write_register(ViPipe, 0x15, 0x44); + pr2020_write_register(ViPipe, 0x16, 0x0d); + pr2020_write_register(ViPipe, 0x40, 0x00); + pr2020_write_register(ViPipe, 0x47, 0x3a); + pr2020_write_register(ViPipe, 0x4e, 0x3f); + pr2020_write_register(ViPipe, 0x80, 0x56); + pr2020_write_register(ViPipe, 0x81, 0x0e); + pr2020_write_register(ViPipe, 0x82, 0x0d); + pr2020_write_register(ViPipe, 0x84, 0x30); + pr2020_write_register(ViPipe, 0x86, 0x20); + pr2020_write_register(ViPipe, 0x87, 0x00); + pr2020_write_register(ViPipe, 0x8a, 0x00); + pr2020_write_register(ViPipe, 0x90, 0x00); + pr2020_write_register(ViPipe, 0x91, 0x00); + pr2020_write_register(ViPipe, 0x92, 0x00); + pr2020_write_register(ViPipe, 0x94, 0xff); + pr2020_write_register(ViPipe, 0x95, 0xff); + pr2020_write_register(ViPipe, 0x96, 0xff); + pr2020_write_register(ViPipe, 0xa0, 0x00); + pr2020_write_register(ViPipe, 0xa1, 0x20); + pr2020_write_register(ViPipe, 0xa4, 0x01); + pr2020_write_register(ViPipe, 0xa5, 0xe3); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0x12); + pr2020_write_register(ViPipe, 0xa8, 0x00); + pr2020_write_register(ViPipe, 0xd0, 0x30); + pr2020_write_register(ViPipe, 0xd1, 0x08); + pr2020_write_register(ViPipe, 0xd2, 0x21); + pr2020_write_register(ViPipe, 0xd3, 0x00); + pr2020_write_register(ViPipe, 0xd8, 0x31); + pr2020_write_register(ViPipe, 0xd9, 0x08); + pr2020_write_register(ViPipe, 0xda, 0x21); + pr2020_write_register(ViPipe, 0xe0, 0x39); + pr2020_write_register(ViPipe, 0xe1, 0x90); + pr2020_write_register(ViPipe, 0xe2, 0x38); + pr2020_write_register(ViPipe, 0xe3, 0x19); + pr2020_write_register(ViPipe, 0xe4, 0x19); + pr2020_write_register(ViPipe, 0xea, 0x01); + pr2020_write_register(ViPipe, 0xeb, 0xff); + pr2020_write_register(ViPipe, 0xf1, 0x44); + pr2020_write_register(ViPipe, 0xf2, 0x01); + + //Page1 vdec + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x00, 0xe4); + pr2020_write_register(ViPipe, 0x01, 0x61); + pr2020_write_register(ViPipe, 0x02, 0x00); + pr2020_write_register(ViPipe, 0x03, 0x57); + pr2020_write_register(ViPipe, 0x04, 0x0c); + pr2020_write_register(ViPipe, 0x05, 0x88); + pr2020_write_register(ViPipe, 0x06, 0x04); + pr2020_write_register(ViPipe, 0x07, 0xb2); + pr2020_write_register(ViPipe, 0x08, 0x44); + pr2020_write_register(ViPipe, 0x09, 0x34); + pr2020_write_register(ViPipe, 0x0a, 0x02); + pr2020_write_register(ViPipe, 0x0b, 0x14); + pr2020_write_register(ViPipe, 0x0c, 0x04); + pr2020_write_register(ViPipe, 0x0d, 0x08); + pr2020_write_register(ViPipe, 0x0e, 0x5e); + pr2020_write_register(ViPipe, 0x0f, 0x5e); + pr2020_write_register(ViPipe, 0x10, 0x26); + pr2020_write_register(ViPipe, 0x11, 0x01); + pr2020_write_register(ViPipe, 0x12, 0x45); + pr2020_write_register(ViPipe, 0x13, 0x0c); + pr2020_write_register(ViPipe, 0x14, 0x00); + pr2020_write_register(ViPipe, 0x15, 0x1b); + pr2020_write_register(ViPipe, 0x16, 0xd0); + pr2020_write_register(ViPipe, 0x17, 0x00); + pr2020_write_register(ViPipe, 0x18, 0x41); + pr2020_write_register(ViPipe, 0x19, 0x46); + pr2020_write_register(ViPipe, 0x1a, 0x22); + pr2020_write_register(ViPipe, 0x1b, 0x05); + pr2020_write_register(ViPipe, 0x1c, 0xea); + pr2020_write_register(ViPipe, 0x1d, 0x45); + pr2020_write_register(ViPipe, 0x1e, 0x4c); + pr2020_write_register(ViPipe, 0x1f, 0x00); + pr2020_write_register(ViPipe, 0x20, 0x80); + pr2020_write_register(ViPipe, 0x21, 0x80); + pr2020_write_register(ViPipe, 0x22, 0x90); + pr2020_write_register(ViPipe, 0x23, 0x80); + pr2020_write_register(ViPipe, 0x24, 0x80); + pr2020_write_register(ViPipe, 0x25, 0x80); + pr2020_write_register(ViPipe, 0x26, 0x84); + pr2020_write_register(ViPipe, 0x27, 0x82); + pr2020_write_register(ViPipe, 0x28, 0x00); + pr2020_write_register(ViPipe, 0x29, 0x7d); + pr2020_write_register(ViPipe, 0x2a, 0x00); + pr2020_write_register(ViPipe, 0x2b, 0x00); + pr2020_write_register(ViPipe, 0x2c, 0x00); + pr2020_write_register(ViPipe, 0x2d, 0x00); + pr2020_write_register(ViPipe, 0x2e, 0x00); + pr2020_write_register(ViPipe, 0x2f, 0x00); + pr2020_write_register(ViPipe, 0x30, 0x00); + pr2020_write_register(ViPipe, 0x31, 0x00); + pr2020_write_register(ViPipe, 0x32, 0xc0); + pr2020_write_register(ViPipe, 0x33, 0x14); + pr2020_write_register(ViPipe, 0x34, 0x14); + pr2020_write_register(ViPipe, 0x35, 0x80); + pr2020_write_register(ViPipe, 0x36, 0x80); + pr2020_write_register(ViPipe, 0x37, 0xaa); + pr2020_write_register(ViPipe, 0x38, 0x48); + pr2020_write_register(ViPipe, 0x39, 0x08); + pr2020_write_register(ViPipe, 0x3a, 0x27); + pr2020_write_register(ViPipe, 0x3b, 0x02); + pr2020_write_register(ViPipe, 0x3c, 0x01); + pr2020_write_register(ViPipe, 0x3d, 0x23); + pr2020_write_register(ViPipe, 0x3e, 0x02); + pr2020_write_register(ViPipe, 0x3f, 0xc4); + pr2020_write_register(ViPipe, 0x40, 0x05); + pr2020_write_register(ViPipe, 0x41, 0x55); + pr2020_write_register(ViPipe, 0x42, 0x01); + pr2020_write_register(ViPipe, 0x43, 0x33); + pr2020_write_register(ViPipe, 0x44, 0x6a); + pr2020_write_register(ViPipe, 0x45, 0x00); + pr2020_write_register(ViPipe, 0x46, 0x09); + pr2020_write_register(ViPipe, 0x47, 0xe2); + pr2020_write_register(ViPipe, 0x48, 0x01); + pr2020_write_register(ViPipe, 0x49, 0x00); + pr2020_write_register(ViPipe, 0x4a, 0x7b); + pr2020_write_register(ViPipe, 0x4b, 0x60); + pr2020_write_register(ViPipe, 0x4c, 0x00); + pr2020_write_register(ViPipe, 0x4d, 0x4a); + pr2020_write_register(ViPipe, 0x4e, 0x00); + pr2020_write_register(ViPipe, 0x4f, 0x20); + pr2020_write_register(ViPipe, 0x50, 0x01); + pr2020_write_register(ViPipe, 0x51, 0x28); + pr2020_write_register(ViPipe, 0x52, 0x40); + pr2020_write_register(ViPipe, 0x53, 0x0c); + pr2020_write_register(ViPipe, 0x54, 0x0f); + pr2020_write_register(ViPipe, 0x55, 0x8d); + pr2020_write_register(ViPipe, 0x70, 0x06); + pr2020_write_register(ViPipe, 0x71, 0x08); + pr2020_write_register(ViPipe, 0x72, 0x0a); + pr2020_write_register(ViPipe, 0x73, 0x0c); + pr2020_write_register(ViPipe, 0x74, 0x0e); + pr2020_write_register(ViPipe, 0x75, 0x10); + pr2020_write_register(ViPipe, 0x76, 0x12); + pr2020_write_register(ViPipe, 0x77, 0x14); + pr2020_write_register(ViPipe, 0x78, 0x06); + pr2020_write_register(ViPipe, 0x79, 0x08); + pr2020_write_register(ViPipe, 0x7a, 0x0a); + pr2020_write_register(ViPipe, 0x7b, 0x0c); + pr2020_write_register(ViPipe, 0x7c, 0x0e); + pr2020_write_register(ViPipe, 0x7d, 0x10); + pr2020_write_register(ViPipe, 0x7e, 0x12); + pr2020_write_register(ViPipe, 0x7f, 0x14); + pr2020_write_register(ViPipe, 0x80, 0x00); + pr2020_write_register(ViPipe, 0x81, 0x09); + pr2020_write_register(ViPipe, 0x82, 0x00); + pr2020_write_register(ViPipe, 0x83, 0x07); + pr2020_write_register(ViPipe, 0x84, 0x00); + pr2020_write_register(ViPipe, 0x85, 0x17); + pr2020_write_register(ViPipe, 0x86, 0x03); + pr2020_write_register(ViPipe, 0x87, 0xe5); + pr2020_write_register(ViPipe, 0x88, 0x0a); + pr2020_write_register(ViPipe, 0x89, 0x48); + pr2020_write_register(ViPipe, 0x8a, 0x0a); + pr2020_write_register(ViPipe, 0x8b, 0x48); + pr2020_write_register(ViPipe, 0x8c, 0x0b); + pr2020_write_register(ViPipe, 0x8d, 0xe0); + pr2020_write_register(ViPipe, 0x8e, 0x05); + pr2020_write_register(ViPipe, 0x8f, 0x47); + pr2020_write_register(ViPipe, 0x90, 0x05); + pr2020_write_register(ViPipe, 0x91, 0x69); + pr2020_write_register(ViPipe, 0x92, 0x73); + pr2020_write_register(ViPipe, 0x93, 0xe8); + pr2020_write_register(ViPipe, 0x94, 0x0f); + pr2020_write_register(ViPipe, 0x95, 0x5e); + pr2020_write_register(ViPipe, 0x96, 0x07); + pr2020_write_register(ViPipe, 0x97, 0x90); + pr2020_write_register(ViPipe, 0x98, 0x17); + pr2020_write_register(ViPipe, 0x99, 0x34); + pr2020_write_register(ViPipe, 0x9a, 0x13); + pr2020_write_register(ViPipe, 0x9b, 0x56); + pr2020_write_register(ViPipe, 0x9c, 0x0b); + pr2020_write_register(ViPipe, 0x9d, 0x9a); + pr2020_write_register(ViPipe, 0x9e, 0x09); + pr2020_write_register(ViPipe, 0x9f, 0xab); + pr2020_write_register(ViPipe, 0xa0, 0x01); + pr2020_write_register(ViPipe, 0xa1, 0x74); + pr2020_write_register(ViPipe, 0xa2, 0x01); + pr2020_write_register(ViPipe, 0xa3, 0x6b); + pr2020_write_register(ViPipe, 0xa4, 0x00); + pr2020_write_register(ViPipe, 0xa5, 0xba); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0xa3); + pr2020_write_register(ViPipe, 0xa8, 0x01); + pr2020_write_register(ViPipe, 0xa9, 0x39); + pr2020_write_register(ViPipe, 0xaa, 0x01); + pr2020_write_register(ViPipe, 0xab, 0x39); + pr2020_write_register(ViPipe, 0xac, 0x00); + pr2020_write_register(ViPipe, 0xad, 0xc1); + pr2020_write_register(ViPipe, 0xae, 0x00); + pr2020_write_register(ViPipe, 0xaf, 0xc1); + pr2020_write_register(ViPipe, 0xb0, 0x0b); + pr2020_write_register(ViPipe, 0xb1, 0x99); + pr2020_write_register(ViPipe, 0xb2, 0x12); + pr2020_write_register(ViPipe, 0xb3, 0xca); + pr2020_write_register(ViPipe, 0xb4, 0x00); + pr2020_write_register(ViPipe, 0xb5, 0x17); + pr2020_write_register(ViPipe, 0xb6, 0x08); + pr2020_write_register(ViPipe, 0xb7, 0xe8); + pr2020_write_register(ViPipe, 0xb8, 0xb0); + pr2020_write_register(ViPipe, 0xb9, 0xce); + pr2020_write_register(ViPipe, 0xba, 0x90); + pr2020_write_register(ViPipe, 0xbb, 0x00); + pr2020_write_register(ViPipe, 0xbc, 0x00); + pr2020_write_register(ViPipe, 0xbd, 0x04); + pr2020_write_register(ViPipe, 0xbe, 0x05); + pr2020_write_register(ViPipe, 0xbf, 0x00); + pr2020_write_register(ViPipe, 0xc0, 0x00); + pr2020_write_register(ViPipe, 0xc1, 0x12); + pr2020_write_register(ViPipe, 0xc2, 0x02); + pr2020_write_register(ViPipe, 0xc3, 0xd0); + + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0e); + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0f); +} + +void pr2020_set_720p_30(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe=%d\n", ViPipe); + + //Page0 sys + pr2020_write_register(ViPipe, 0xff, 0x00); + pr2020_write_register(ViPipe, 0x10, 0x92); + pr2020_write_register(ViPipe, 0x11, 0x07); + pr2020_write_register(ViPipe, 0x12, 0x00); + pr2020_write_register(ViPipe, 0x13, 0x00); + pr2020_write_register(ViPipe, 0x14, 0x21);//b[1:0); => Select Camera Input. VinP(1), VinN(3), Differ(0). + pr2020_write_register(ViPipe, 0x15, 0x44); + pr2020_write_register(ViPipe, 0x16, 0x0d); + pr2020_write_register(ViPipe, 0x40, 0x00); + pr2020_write_register(ViPipe, 0x47, 0x3a); + pr2020_write_register(ViPipe, 0x4e, 0x3f); + pr2020_write_register(ViPipe, 0x80, 0x56); + pr2020_write_register(ViPipe, 0x81, 0x0e); + pr2020_write_register(ViPipe, 0x82, 0x0d); + pr2020_write_register(ViPipe, 0x84, 0x30); + pr2020_write_register(ViPipe, 0x86, 0x20); + pr2020_write_register(ViPipe, 0x87, 0x00); + pr2020_write_register(ViPipe, 0x8a, 0x00); + pr2020_write_register(ViPipe, 0x90, 0x00); + pr2020_write_register(ViPipe, 0x91, 0x00); + pr2020_write_register(ViPipe, 0x92, 0x00); + pr2020_write_register(ViPipe, 0x94, 0xff); + pr2020_write_register(ViPipe, 0x95, 0xff); + pr2020_write_register(ViPipe, 0x96, 0xff); + pr2020_write_register(ViPipe, 0xa0, 0x00); + pr2020_write_register(ViPipe, 0xa1, 0x20); + pr2020_write_register(ViPipe, 0xa4, 0x01); + pr2020_write_register(ViPipe, 0xa5, 0xe3); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0x12); + pr2020_write_register(ViPipe, 0xa8, 0x00); + pr2020_write_register(ViPipe, 0xd0, 0x30); + pr2020_write_register(ViPipe, 0xd1, 0x08); + pr2020_write_register(ViPipe, 0xd2, 0x21); + pr2020_write_register(ViPipe, 0xd3, 0x00); + pr2020_write_register(ViPipe, 0xd8, 0x31); + pr2020_write_register(ViPipe, 0xd9, 0x08); + pr2020_write_register(ViPipe, 0xda, 0x21); + pr2020_write_register(ViPipe, 0xe0, 0x39); + pr2020_write_register(ViPipe, 0xe1, 0x90); + pr2020_write_register(ViPipe, 0xe2, 0x38); + pr2020_write_register(ViPipe, 0xe3, 0x19); + pr2020_write_register(ViPipe, 0xe4, 0x19); + pr2020_write_register(ViPipe, 0xea, 0x01); + pr2020_write_register(ViPipe, 0xeb, 0xff); + pr2020_write_register(ViPipe, 0xf1, 0x44); + pr2020_write_register(ViPipe, 0xf2, 0x01); + + //Page1 vdec + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x00, 0xe4); + pr2020_write_register(ViPipe, 0x01, 0x61); + pr2020_write_register(ViPipe, 0x02, 0x00); + pr2020_write_register(ViPipe, 0x03, 0x57); + pr2020_write_register(ViPipe, 0x04, 0x0c); + pr2020_write_register(ViPipe, 0x05, 0x88); + pr2020_write_register(ViPipe, 0x06, 0x04); + pr2020_write_register(ViPipe, 0x07, 0xb2); + pr2020_write_register(ViPipe, 0x08, 0x44); + pr2020_write_register(ViPipe, 0x09, 0x34); + pr2020_write_register(ViPipe, 0x0a, 0x02); + pr2020_write_register(ViPipe, 0x0b, 0x14); + pr2020_write_register(ViPipe, 0x0c, 0x04); + pr2020_write_register(ViPipe, 0x0d, 0x08); + pr2020_write_register(ViPipe, 0x0e, 0x5e); + pr2020_write_register(ViPipe, 0x0f, 0x5e); + pr2020_write_register(ViPipe, 0x10, 0x26); + pr2020_write_register(ViPipe, 0x11, 0x00); + pr2020_write_register(ViPipe, 0x12, 0x45); + pr2020_write_register(ViPipe, 0x13, 0xfc); + pr2020_write_register(ViPipe, 0x14, 0x00); + pr2020_write_register(ViPipe, 0x15, 0x18); + pr2020_write_register(ViPipe, 0x16, 0xd0); + pr2020_write_register(ViPipe, 0x17, 0x00); + pr2020_write_register(ViPipe, 0x18, 0x41); + pr2020_write_register(ViPipe, 0x19, 0x46); + pr2020_write_register(ViPipe, 0x1a, 0x22); + pr2020_write_register(ViPipe, 0x1b, 0x05); + pr2020_write_register(ViPipe, 0x1c, 0xea); + pr2020_write_register(ViPipe, 0x1d, 0x45); + pr2020_write_register(ViPipe, 0x1e, 0x40); + pr2020_write_register(ViPipe, 0x1f, 0x00); + pr2020_write_register(ViPipe, 0x20, 0x80); + pr2020_write_register(ViPipe, 0x21, 0x80); + pr2020_write_register(ViPipe, 0x22, 0x90); + pr2020_write_register(ViPipe, 0x23, 0x80); + pr2020_write_register(ViPipe, 0x24, 0x80); + pr2020_write_register(ViPipe, 0x25, 0x80); + pr2020_write_register(ViPipe, 0x26, 0x84); + pr2020_write_register(ViPipe, 0x27, 0x82); + pr2020_write_register(ViPipe, 0x28, 0x00); + pr2020_write_register(ViPipe, 0x29, 0x7b); + pr2020_write_register(ViPipe, 0x2a, 0xa6); + pr2020_write_register(ViPipe, 0x2b, 0x00); + pr2020_write_register(ViPipe, 0x2c, 0x00); + pr2020_write_register(ViPipe, 0x2d, 0x00); + pr2020_write_register(ViPipe, 0x2e, 0x00); + pr2020_write_register(ViPipe, 0x2f, 0x00); + pr2020_write_register(ViPipe, 0x30, 0x00); + pr2020_write_register(ViPipe, 0x31, 0x00); + pr2020_write_register(ViPipe, 0x32, 0xc0); + pr2020_write_register(ViPipe, 0x33, 0x14); + pr2020_write_register(ViPipe, 0x34, 0x14); + pr2020_write_register(ViPipe, 0x35, 0x80); + pr2020_write_register(ViPipe, 0x36, 0x80); + pr2020_write_register(ViPipe, 0x37, 0xaa); + pr2020_write_register(ViPipe, 0x38, 0x48); + pr2020_write_register(ViPipe, 0x39, 0x08); + pr2020_write_register(ViPipe, 0x3a, 0x27); + pr2020_write_register(ViPipe, 0x3b, 0x02); + pr2020_write_register(ViPipe, 0x3c, 0x01); + pr2020_write_register(ViPipe, 0x3d, 0x23); + pr2020_write_register(ViPipe, 0x3e, 0x02); + pr2020_write_register(ViPipe, 0x3f, 0xc4); + pr2020_write_register(ViPipe, 0x40, 0x05); + pr2020_write_register(ViPipe, 0x41, 0x55); + pr2020_write_register(ViPipe, 0x42, 0x01); + pr2020_write_register(ViPipe, 0x43, 0x33); + pr2020_write_register(ViPipe, 0x44, 0x6a); + pr2020_write_register(ViPipe, 0x45, 0x00); + pr2020_write_register(ViPipe, 0x46, 0x09); + pr2020_write_register(ViPipe, 0x47, 0xdc); + pr2020_write_register(ViPipe, 0x48, 0xa0); + pr2020_write_register(ViPipe, 0x49, 0x00); + pr2020_write_register(ViPipe, 0x4a, 0x7b); + pr2020_write_register(ViPipe, 0x4b, 0x60); + pr2020_write_register(ViPipe, 0x4c, 0x00); + pr2020_write_register(ViPipe, 0x4d, 0x4a); + pr2020_write_register(ViPipe, 0x4e, 0x00); + pr2020_write_register(ViPipe, 0x4f, 0x20); + pr2020_write_register(ViPipe, 0x50, 0x01); + pr2020_write_register(ViPipe, 0x51, 0x28); + pr2020_write_register(ViPipe, 0x52, 0x40); + pr2020_write_register(ViPipe, 0x53, 0x0c); + pr2020_write_register(ViPipe, 0x54, 0x0f); + pr2020_write_register(ViPipe, 0x55, 0x8d); + pr2020_write_register(ViPipe, 0x70, 0x06); + pr2020_write_register(ViPipe, 0x71, 0x08); + pr2020_write_register(ViPipe, 0x72, 0x0a); + pr2020_write_register(ViPipe, 0x73, 0x0c); + pr2020_write_register(ViPipe, 0x74, 0x0e); + pr2020_write_register(ViPipe, 0x75, 0x10); + pr2020_write_register(ViPipe, 0x76, 0x12); + pr2020_write_register(ViPipe, 0x77, 0x14); + pr2020_write_register(ViPipe, 0x78, 0x06); + pr2020_write_register(ViPipe, 0x79, 0x08); + pr2020_write_register(ViPipe, 0x7a, 0x0a); + pr2020_write_register(ViPipe, 0x7b, 0x0c); + pr2020_write_register(ViPipe, 0x7c, 0x0e); + pr2020_write_register(ViPipe, 0x7d, 0x10); + pr2020_write_register(ViPipe, 0x7e, 0x12); + pr2020_write_register(ViPipe, 0x7f, 0x14); + pr2020_write_register(ViPipe, 0x80, 0x00); + pr2020_write_register(ViPipe, 0x81, 0x09); + pr2020_write_register(ViPipe, 0x82, 0x00); + pr2020_write_register(ViPipe, 0x83, 0x07); + pr2020_write_register(ViPipe, 0x84, 0x00); + pr2020_write_register(ViPipe, 0x85, 0x17); + pr2020_write_register(ViPipe, 0x86, 0x03); + pr2020_write_register(ViPipe, 0x87, 0xe5); + pr2020_write_register(ViPipe, 0x88, 0x08); + pr2020_write_register(ViPipe, 0x89, 0x91); + pr2020_write_register(ViPipe, 0x8a, 0x08); + pr2020_write_register(ViPipe, 0x8b, 0x91); + pr2020_write_register(ViPipe, 0x8c, 0x0b); + pr2020_write_register(ViPipe, 0x8d, 0xe0); + pr2020_write_register(ViPipe, 0x8e, 0x05); + pr2020_write_register(ViPipe, 0x8f, 0x47); + pr2020_write_register(ViPipe, 0x90, 0x05); + pr2020_write_register(ViPipe, 0x91, 0xa0); + pr2020_write_register(ViPipe, 0x92, 0x73); + pr2020_write_register(ViPipe, 0x93, 0xe8); + pr2020_write_register(ViPipe, 0x94, 0x0f); + pr2020_write_register(ViPipe, 0x95, 0x5e); + pr2020_write_register(ViPipe, 0x96, 0x07); + pr2020_write_register(ViPipe, 0x97, 0x90); + pr2020_write_register(ViPipe, 0x98, 0x17); + pr2020_write_register(ViPipe, 0x99, 0x34); + pr2020_write_register(ViPipe, 0x9a, 0x13); + pr2020_write_register(ViPipe, 0x9b, 0x56); + pr2020_write_register(ViPipe, 0x9c, 0x0b); + pr2020_write_register(ViPipe, 0x9d, 0x9a); + pr2020_write_register(ViPipe, 0x9e, 0x09); + pr2020_write_register(ViPipe, 0x9f, 0xab); + pr2020_write_register(ViPipe, 0xa0, 0x01); + pr2020_write_register(ViPipe, 0xa1, 0x74); + pr2020_write_register(ViPipe, 0xa2, 0x01); + pr2020_write_register(ViPipe, 0xa3, 0x6b); + pr2020_write_register(ViPipe, 0xa4, 0x00); + pr2020_write_register(ViPipe, 0xa5, 0xba); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0xa3); + pr2020_write_register(ViPipe, 0xa8, 0x01); + pr2020_write_register(ViPipe, 0xa9, 0x39); + pr2020_write_register(ViPipe, 0xaa, 0x01); + pr2020_write_register(ViPipe, 0xab, 0x39); + pr2020_write_register(ViPipe, 0xac, 0x00); + pr2020_write_register(ViPipe, 0xad, 0xc1); + pr2020_write_register(ViPipe, 0xae, 0x00); + pr2020_write_register(ViPipe, 0xaf, 0xc1); + pr2020_write_register(ViPipe, 0xb0, 0x09); + pr2020_write_register(ViPipe, 0xb1, 0xaa); + pr2020_write_register(ViPipe, 0xb2, 0x0f); + pr2020_write_register(ViPipe, 0xb3, 0xae); + pr2020_write_register(ViPipe, 0xb4, 0x00); + pr2020_write_register(ViPipe, 0xb5, 0x17); + pr2020_write_register(ViPipe, 0xb6, 0x08); + pr2020_write_register(ViPipe, 0xb7, 0xe8); + pr2020_write_register(ViPipe, 0xb8, 0xb0); + pr2020_write_register(ViPipe, 0xb9, 0xce); + pr2020_write_register(ViPipe, 0xba, 0x90); + pr2020_write_register(ViPipe, 0xbb, 0x00); + pr2020_write_register(ViPipe, 0xbc, 0x00); + pr2020_write_register(ViPipe, 0xbd, 0x04); + pr2020_write_register(ViPipe, 0xbe, 0x05); + pr2020_write_register(ViPipe, 0xbf, 0x00); + pr2020_write_register(ViPipe, 0xc0, 0x00); + pr2020_write_register(ViPipe, 0xc1, 0x18); + pr2020_write_register(ViPipe, 0xc2, 0x02); + pr2020_write_register(ViPipe, 0xc3, 0xd0); + + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0e); + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0f); +} + +void pr2020_set_1080p_25(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe=%d\n", ViPipe); + + //Page0 sys + pr2020_write_register(ViPipe, 0xff, 0x00); + pr2020_write_register(ViPipe, 0x10, 0x83); + pr2020_write_register(ViPipe, 0x11, 0x07); + pr2020_write_register(ViPipe, 0x12, 0x00); + pr2020_write_register(ViPipe, 0x13, 0x00); + pr2020_write_register(ViPipe, 0x14, 0x21);//b[1:0} => Select Camera Input. VinP(1), VinN(3), Differ(0). + pr2020_write_register(ViPipe, 0x15, 0x44); + pr2020_write_register(ViPipe, 0x16, 0x0d); + pr2020_write_register(ViPipe, 0x40, 0x00); + pr2020_write_register(ViPipe, 0x47, 0x3a); + pr2020_write_register(ViPipe, 0x4e, 0x3f); + pr2020_write_register(ViPipe, 0x80, 0x56); + pr2020_write_register(ViPipe, 0x81, 0x0e); + pr2020_write_register(ViPipe, 0x82, 0x0d); + pr2020_write_register(ViPipe, 0x84, 0x30); + pr2020_write_register(ViPipe, 0x86, 0x20); + pr2020_write_register(ViPipe, 0x87, 0x00); + pr2020_write_register(ViPipe, 0x8a, 0x00); + pr2020_write_register(ViPipe, 0x90, 0x00); + pr2020_write_register(ViPipe, 0x91, 0x00); + pr2020_write_register(ViPipe, 0x92, 0x00); + pr2020_write_register(ViPipe, 0x94, 0xff); + pr2020_write_register(ViPipe, 0x95, 0xff); + pr2020_write_register(ViPipe, 0x96, 0xff); + pr2020_write_register(ViPipe, 0xa0, 0x00); + pr2020_write_register(ViPipe, 0xa1, 0x20); + pr2020_write_register(ViPipe, 0xa4, 0x01); + pr2020_write_register(ViPipe, 0xa5, 0xe3); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0x12); + pr2020_write_register(ViPipe, 0xa8, 0x00); + pr2020_write_register(ViPipe, 0xd0, 0x30); + pr2020_write_register(ViPipe, 0xd1, 0x08); + pr2020_write_register(ViPipe, 0xd2, 0x21); + pr2020_write_register(ViPipe, 0xd3, 0x00); + pr2020_write_register(ViPipe, 0xd8, 0x30); + pr2020_write_register(ViPipe, 0xd9, 0x08); + pr2020_write_register(ViPipe, 0xda, 0x21); + pr2020_write_register(ViPipe, 0xe0, 0x35); + pr2020_write_register(ViPipe, 0xe1, 0x80);//[6] 0:cb-y-cr-y 1:y-cb-y-cr + pr2020_write_register(ViPipe, 0xe2, 0x18); + pr2020_write_register(ViPipe, 0xe3, 0x00); + pr2020_write_register(ViPipe, 0xe4, 0x00); + pr2020_write_register(ViPipe, 0xea, 0x01); + pr2020_write_register(ViPipe, 0xeb, 0xff); + pr2020_write_register(ViPipe, 0xf1, 0x44); + pr2020_write_register(ViPipe, 0xf2, 0x01); + + //Page1 vdec + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x00, 0xe4); + pr2020_write_register(ViPipe, 0x01, 0x61); + pr2020_write_register(ViPipe, 0x02, 0x00); + pr2020_write_register(ViPipe, 0x03, 0x57); + pr2020_write_register(ViPipe, 0x04, 0x0c); + pr2020_write_register(ViPipe, 0x05, 0x88); + pr2020_write_register(ViPipe, 0x06, 0x04); + pr2020_write_register(ViPipe, 0x07, 0xb2); + pr2020_write_register(ViPipe, 0x08, 0x44); + pr2020_write_register(ViPipe, 0x09, 0x34); + pr2020_write_register(ViPipe, 0x0a, 0x02); + pr2020_write_register(ViPipe, 0x0b, 0x14); + pr2020_write_register(ViPipe, 0x0c, 0x04); + pr2020_write_register(ViPipe, 0x0d, 0x08); + pr2020_write_register(ViPipe, 0x0e, 0x5e); + pr2020_write_register(ViPipe, 0x0f, 0x5e); + pr2020_write_register(ViPipe, 0x10, 0x26); + pr2020_write_register(ViPipe, 0x11, 0x00); + pr2020_write_register(ViPipe, 0x12, 0x87); + pr2020_write_register(ViPipe, 0x13, 0x24); + pr2020_write_register(ViPipe, 0x14, 0x80); + pr2020_write_register(ViPipe, 0x15, 0x2a); + pr2020_write_register(ViPipe, 0x16, 0x38); + pr2020_write_register(ViPipe, 0x17, 0x00); + pr2020_write_register(ViPipe, 0x18, 0x80); + pr2020_write_register(ViPipe, 0x19, 0x48); + pr2020_write_register(ViPipe, 0x1a, 0x6c); + pr2020_write_register(ViPipe, 0x1b, 0x05); + pr2020_write_register(ViPipe, 0x1c, 0x61); + pr2020_write_register(ViPipe, 0x1d, 0x07); + pr2020_write_register(ViPipe, 0x1e, 0x7e); + pr2020_write_register(ViPipe, 0x1f, 0x80); + pr2020_write_register(ViPipe, 0x20, 0x80); + pr2020_write_register(ViPipe, 0x21, 0x80); + pr2020_write_register(ViPipe, 0x22, 0x90); + pr2020_write_register(ViPipe, 0x23, 0x80); + pr2020_write_register(ViPipe, 0x24, 0x80); + pr2020_write_register(ViPipe, 0x25, 0x80); + pr2020_write_register(ViPipe, 0x26, 0x84); + pr2020_write_register(ViPipe, 0x27, 0x82); + pr2020_write_register(ViPipe, 0x28, 0x00); + pr2020_write_register(ViPipe, 0x29, 0xff); + pr2020_write_register(ViPipe, 0x2a, 0xff); + pr2020_write_register(ViPipe, 0x2b, 0x00); + pr2020_write_register(ViPipe, 0x2c, 0x00); + pr2020_write_register(ViPipe, 0x2d, 0x00); + pr2020_write_register(ViPipe, 0x2e, 0x00); + pr2020_write_register(ViPipe, 0x2f, 0x00); + pr2020_write_register(ViPipe, 0x30, 0x00); + pr2020_write_register(ViPipe, 0x31, 0x00); + pr2020_write_register(ViPipe, 0x32, 0xc0); + pr2020_write_register(ViPipe, 0x33, 0x14); + pr2020_write_register(ViPipe, 0x34, 0x14); + pr2020_write_register(ViPipe, 0x35, 0x80); + pr2020_write_register(ViPipe, 0x36, 0x80); + pr2020_write_register(ViPipe, 0x37, 0xad); + pr2020_write_register(ViPipe, 0x38, 0x4b); + pr2020_write_register(ViPipe, 0x39, 0x08); + pr2020_write_register(ViPipe, 0x3a, 0x21); + pr2020_write_register(ViPipe, 0x3b, 0x02); + pr2020_write_register(ViPipe, 0x3c, 0x01); + pr2020_write_register(ViPipe, 0x3d, 0x23); + pr2020_write_register(ViPipe, 0x3e, 0x05); + pr2020_write_register(ViPipe, 0x3f, 0xc8); + pr2020_write_register(ViPipe, 0x40, 0x05); + pr2020_write_register(ViPipe, 0x41, 0x55); + pr2020_write_register(ViPipe, 0x42, 0x01); + pr2020_write_register(ViPipe, 0x43, 0x38); + pr2020_write_register(ViPipe, 0x44, 0x6a); + pr2020_write_register(ViPipe, 0x45, 0x00); + pr2020_write_register(ViPipe, 0x46, 0x14); + pr2020_write_register(ViPipe, 0x47, 0xb0); + pr2020_write_register(ViPipe, 0x48, 0xdf); + pr2020_write_register(ViPipe, 0x49, 0x00); + pr2020_write_register(ViPipe, 0x4a, 0x7b); + pr2020_write_register(ViPipe, 0x4b, 0x60); + pr2020_write_register(ViPipe, 0x4c, 0x00); + pr2020_write_register(ViPipe, 0x4d, 0x26); + pr2020_write_register(ViPipe, 0x4e, 0x00); + pr2020_write_register(ViPipe, 0x4f, 0x20);//RK:0x24 + pr2020_write_register(ViPipe, 0x50, 0x01); + pr2020_write_register(ViPipe, 0x51, 0x28); + pr2020_write_register(ViPipe, 0x52, 0x40); + pr2020_write_register(ViPipe, 0x53, 0x0c); + pr2020_write_register(ViPipe, 0x54, 0x0f); + pr2020_write_register(ViPipe, 0x55, 0x8d); + pr2020_write_register(ViPipe, 0x70, 0x06); + pr2020_write_register(ViPipe, 0x71, 0x08); + pr2020_write_register(ViPipe, 0x72, 0x0a); + pr2020_write_register(ViPipe, 0x73, 0x0c); + pr2020_write_register(ViPipe, 0x74, 0x0e); + pr2020_write_register(ViPipe, 0x75, 0x10); + pr2020_write_register(ViPipe, 0x76, 0x12); + pr2020_write_register(ViPipe, 0x77, 0x14); + pr2020_write_register(ViPipe, 0x78, 0x06); + pr2020_write_register(ViPipe, 0x79, 0x08); + pr2020_write_register(ViPipe, 0x7a, 0x0a); + pr2020_write_register(ViPipe, 0x7b, 0x0c); + pr2020_write_register(ViPipe, 0x7c, 0x0e); + pr2020_write_register(ViPipe, 0x7d, 0x10); + pr2020_write_register(ViPipe, 0x7e, 0x12); + pr2020_write_register(ViPipe, 0x7f, 0x14); + pr2020_write_register(ViPipe, 0x80, 0x00); + pr2020_write_register(ViPipe, 0x81, 0x09); + pr2020_write_register(ViPipe, 0x82, 0x00); + pr2020_write_register(ViPipe, 0x83, 0x07); + pr2020_write_register(ViPipe, 0x84, 0x00); + pr2020_write_register(ViPipe, 0x85, 0x17); + pr2020_write_register(ViPipe, 0x86, 0x03); + pr2020_write_register(ViPipe, 0x87, 0xe5); + pr2020_write_register(ViPipe, 0x88, 0x05); + pr2020_write_register(ViPipe, 0x89, 0x24); + pr2020_write_register(ViPipe, 0x8a, 0x05); + pr2020_write_register(ViPipe, 0x8b, 0x24); + pr2020_write_register(ViPipe, 0x8c, 0x08); + pr2020_write_register(ViPipe, 0x8d, 0xe8); + pr2020_write_register(ViPipe, 0x8e, 0x05); + pr2020_write_register(ViPipe, 0x8f, 0x47); + pr2020_write_register(ViPipe, 0x90, 0x02); + pr2020_write_register(ViPipe, 0x91, 0xb4); + pr2020_write_register(ViPipe, 0x92, 0x73); + pr2020_write_register(ViPipe, 0x93, 0xe8); + pr2020_write_register(ViPipe, 0x94, 0x0f); + pr2020_write_register(ViPipe, 0x95, 0x5e); + pr2020_write_register(ViPipe, 0x96, 0x03); + pr2020_write_register(ViPipe, 0x97, 0xd0); + pr2020_write_register(ViPipe, 0x98, 0x17); + pr2020_write_register(ViPipe, 0x99, 0x34); + pr2020_write_register(ViPipe, 0x9a, 0x13); + pr2020_write_register(ViPipe, 0x9b, 0x56); + pr2020_write_register(ViPipe, 0x9c, 0x0b); + pr2020_write_register(ViPipe, 0x9d, 0x9a); + pr2020_write_register(ViPipe, 0x9e, 0x09); + pr2020_write_register(ViPipe, 0x9f, 0xab); + pr2020_write_register(ViPipe, 0xa0, 0x01); + pr2020_write_register(ViPipe, 0xa1, 0x74); + pr2020_write_register(ViPipe, 0xa2, 0x01); + pr2020_write_register(ViPipe, 0xa3, 0x6b); + pr2020_write_register(ViPipe, 0xa4, 0x00); + pr2020_write_register(ViPipe, 0xa5, 0xba); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0xa3); + pr2020_write_register(ViPipe, 0xa8, 0x01); + pr2020_write_register(ViPipe, 0xa9, 0x39); + pr2020_write_register(ViPipe, 0xaa, 0x01); + pr2020_write_register(ViPipe, 0xab, 0x39); + pr2020_write_register(ViPipe, 0xac, 0x00); + pr2020_write_register(ViPipe, 0xad, 0xc1); + pr2020_write_register(ViPipe, 0xae, 0x00); + pr2020_write_register(ViPipe, 0xaf, 0xc1); + pr2020_write_register(ViPipe, 0xb0, 0x05); + pr2020_write_register(ViPipe, 0xb1, 0xcc); + pr2020_write_register(ViPipe, 0xb2, 0x09); + pr2020_write_register(ViPipe, 0xb3, 0x6d); + pr2020_write_register(ViPipe, 0xb4, 0x00); + pr2020_write_register(ViPipe, 0xb5, 0x17); + pr2020_write_register(ViPipe, 0xb6, 0x08); + pr2020_write_register(ViPipe, 0xb7, 0xe8); + pr2020_write_register(ViPipe, 0xb8, 0xb0); + pr2020_write_register(ViPipe, 0xb9, 0xce); + pr2020_write_register(ViPipe, 0xba, 0x90); + pr2020_write_register(ViPipe, 0xbb, 0x00); + pr2020_write_register(ViPipe, 0xbc, 0x00); + pr2020_write_register(ViPipe, 0xbd, 0x04); + pr2020_write_register(ViPipe, 0xbe, 0x07); + pr2020_write_register(ViPipe, 0xbf, 0x80); + pr2020_write_register(ViPipe, 0xc0, 0x00); + pr2020_write_register(ViPipe, 0xc1, 0x20); + pr2020_write_register(ViPipe, 0xc2, 0x04); + pr2020_write_register(ViPipe, 0xc3, 0x38); + + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0e); + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0f); +} + +void pr2020_set_1080p_30(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe=%d\n", ViPipe); + + //Page0 sys + pr2020_write_register(ViPipe, 0xff, 0x00); + pr2020_write_register(ViPipe, 0x10, 0x93); + pr2020_write_register(ViPipe, 0x11, 0x07); + pr2020_write_register(ViPipe, 0x12, 0x00); + pr2020_write_register(ViPipe, 0x13, 0x00); + pr2020_write_register(ViPipe, 0x14, 0x21);//b[1:0} => Select Camera Input. VinP(1), VinN(3), Differ(0). + pr2020_write_register(ViPipe, 0x15, 0x44); + pr2020_write_register(ViPipe, 0x16, 0x0d); + pr2020_write_register(ViPipe, 0x40, 0x00); + pr2020_write_register(ViPipe, 0x47, 0x3a); + pr2020_write_register(ViPipe, 0x4e, 0x3f); + pr2020_write_register(ViPipe, 0x80, 0x56); + pr2020_write_register(ViPipe, 0x81, 0x0e); + pr2020_write_register(ViPipe, 0x82, 0x0d); + pr2020_write_register(ViPipe, 0x84, 0x30); + pr2020_write_register(ViPipe, 0x86, 0x20); + pr2020_write_register(ViPipe, 0x87, 0x00); + pr2020_write_register(ViPipe, 0x8a, 0x00); + pr2020_write_register(ViPipe, 0x90, 0x00); + pr2020_write_register(ViPipe, 0x91, 0x00); + pr2020_write_register(ViPipe, 0x92, 0x00); + pr2020_write_register(ViPipe, 0x94, 0xff); + pr2020_write_register(ViPipe, 0x95, 0xff); + pr2020_write_register(ViPipe, 0x96, 0xff); + pr2020_write_register(ViPipe, 0xa0, 0x00); + pr2020_write_register(ViPipe, 0xa1, 0x20); + pr2020_write_register(ViPipe, 0xa4, 0x01); + pr2020_write_register(ViPipe, 0xa5, 0xe3); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0x12); + pr2020_write_register(ViPipe, 0xa8, 0x00); + pr2020_write_register(ViPipe, 0xd0, 0x30); + pr2020_write_register(ViPipe, 0xd1, 0x08); + pr2020_write_register(ViPipe, 0xd2, 0x21); + pr2020_write_register(ViPipe, 0xd3, 0x00); + pr2020_write_register(ViPipe, 0xd8, 0x30); + pr2020_write_register(ViPipe, 0xd9, 0x08); + pr2020_write_register(ViPipe, 0xda, 0x21); + pr2020_write_register(ViPipe, 0xe0, 0x35); + pr2020_write_register(ViPipe, 0xe1, 0x80); + pr2020_write_register(ViPipe, 0xe2, 0x18); + pr2020_write_register(ViPipe, 0xe3, 0x00); + pr2020_write_register(ViPipe, 0xe4, 0x00); + pr2020_write_register(ViPipe, 0xea, 0x01); + pr2020_write_register(ViPipe, 0xeb, 0xff); + pr2020_write_register(ViPipe, 0xf1, 0x44); + pr2020_write_register(ViPipe, 0xf2, 0x01); + + //Page1 vdec + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x00, 0xe4); + pr2020_write_register(ViPipe, 0x01, 0x61); + pr2020_write_register(ViPipe, 0x02, 0x00); + pr2020_write_register(ViPipe, 0x03, 0x57); + pr2020_write_register(ViPipe, 0x04, 0x0c); + pr2020_write_register(ViPipe, 0x05, 0x88); + pr2020_write_register(ViPipe, 0x06, 0x04); + pr2020_write_register(ViPipe, 0x07, 0xb2); + pr2020_write_register(ViPipe, 0x08, 0x44); + pr2020_write_register(ViPipe, 0x09, 0x34); + pr2020_write_register(ViPipe, 0x0a, 0x02); + pr2020_write_register(ViPipe, 0x0b, 0x14); + pr2020_write_register(ViPipe, 0x0c, 0x04); + pr2020_write_register(ViPipe, 0x0d, 0x08); + pr2020_write_register(ViPipe, 0x0e, 0x5e); + pr2020_write_register(ViPipe, 0x0f, 0x5e); + pr2020_write_register(ViPipe, 0x10, 0x26); + pr2020_write_register(ViPipe, 0x11, 0x00); + pr2020_write_register(ViPipe, 0x12, 0x87); + pr2020_write_register(ViPipe, 0x13, 0x2c); + pr2020_write_register(ViPipe, 0x14, 0x80); + pr2020_write_register(ViPipe, 0x15, 0x28); + pr2020_write_register(ViPipe, 0x16, 0x38); + pr2020_write_register(ViPipe, 0x17, 0x00); + pr2020_write_register(ViPipe, 0x18, 0x80); + pr2020_write_register(ViPipe, 0x19, 0x48); + pr2020_write_register(ViPipe, 0x1a, 0x6c); + pr2020_write_register(ViPipe, 0x1b, 0x05); + pr2020_write_register(ViPipe, 0x1c, 0x61); + pr2020_write_register(ViPipe, 0x1d, 0x07); + pr2020_write_register(ViPipe, 0x1e, 0x7e); + pr2020_write_register(ViPipe, 0x1f, 0x80); + pr2020_write_register(ViPipe, 0x20, 0x80); + pr2020_write_register(ViPipe, 0x21, 0x80); + pr2020_write_register(ViPipe, 0x22, 0x90); + pr2020_write_register(ViPipe, 0x23, 0x80); + pr2020_write_register(ViPipe, 0x24, 0x80); + pr2020_write_register(ViPipe, 0x25, 0x80); + pr2020_write_register(ViPipe, 0x26, 0x84); + pr2020_write_register(ViPipe, 0x27, 0x82); + pr2020_write_register(ViPipe, 0x28, 0x00); + pr2020_write_register(ViPipe, 0x29, 0xff); + pr2020_write_register(ViPipe, 0x2a, 0xff); + pr2020_write_register(ViPipe, 0x2b, 0x00); + pr2020_write_register(ViPipe, 0x2c, 0x00); + pr2020_write_register(ViPipe, 0x2d, 0x00); + pr2020_write_register(ViPipe, 0x2e, 0x00); + pr2020_write_register(ViPipe, 0x2f, 0x00); + pr2020_write_register(ViPipe, 0x30, 0x00); + pr2020_write_register(ViPipe, 0x31, 0x00); + pr2020_write_register(ViPipe, 0x32, 0xc0); + pr2020_write_register(ViPipe, 0x33, 0x14); + pr2020_write_register(ViPipe, 0x34, 0x14); + pr2020_write_register(ViPipe, 0x35, 0x80); + pr2020_write_register(ViPipe, 0x36, 0x80); + pr2020_write_register(ViPipe, 0x37, 0xad); + pr2020_write_register(ViPipe, 0x38, 0x4b); + pr2020_write_register(ViPipe, 0x39, 0x08); + pr2020_write_register(ViPipe, 0x3a, 0x21); + pr2020_write_register(ViPipe, 0x3b, 0x02); + pr2020_write_register(ViPipe, 0x3c, 0x01); + pr2020_write_register(ViPipe, 0x3d, 0x23); + pr2020_write_register(ViPipe, 0x3e, 0x05); + pr2020_write_register(ViPipe, 0x3f, 0xc8); + pr2020_write_register(ViPipe, 0x40, 0x05); + pr2020_write_register(ViPipe, 0x41, 0x55); + pr2020_write_register(ViPipe, 0x42, 0x01); + pr2020_write_register(ViPipe, 0x43, 0x38); + pr2020_write_register(ViPipe, 0x44, 0x6a); + pr2020_write_register(ViPipe, 0x45, 0x00); + pr2020_write_register(ViPipe, 0x46, 0x14); + pr2020_write_register(ViPipe, 0x47, 0xb2); + pr2020_write_register(ViPipe, 0x48, 0xbc); + pr2020_write_register(ViPipe, 0x49, 0x00); + pr2020_write_register(ViPipe, 0x4a, 0x7b); + pr2020_write_register(ViPipe, 0x4b, 0x60); + pr2020_write_register(ViPipe, 0x4c, 0x00); + pr2020_write_register(ViPipe, 0x4d, 0x26); + pr2020_write_register(ViPipe, 0x4e, 0x00); + pr2020_write_register(ViPipe, 0x4f, 0x20);//RK:0x24 + pr2020_write_register(ViPipe, 0x50, 0x01); + pr2020_write_register(ViPipe, 0x51, 0x28); + pr2020_write_register(ViPipe, 0x52, 0x40); + pr2020_write_register(ViPipe, 0x53, 0x0c); + pr2020_write_register(ViPipe, 0x54, 0x0f); + pr2020_write_register(ViPipe, 0x55, 0x8d); + pr2020_write_register(ViPipe, 0x70, 0x06); + pr2020_write_register(ViPipe, 0x71, 0x08); + pr2020_write_register(ViPipe, 0x72, 0x0a); + pr2020_write_register(ViPipe, 0x73, 0x0c); + pr2020_write_register(ViPipe, 0x74, 0x0e); + pr2020_write_register(ViPipe, 0x75, 0x10); + pr2020_write_register(ViPipe, 0x76, 0x12); + pr2020_write_register(ViPipe, 0x77, 0x14); + pr2020_write_register(ViPipe, 0x78, 0x06); + pr2020_write_register(ViPipe, 0x79, 0x08); + pr2020_write_register(ViPipe, 0x7a, 0x0a); + pr2020_write_register(ViPipe, 0x7b, 0x0c); + pr2020_write_register(ViPipe, 0x7c, 0x0e); + pr2020_write_register(ViPipe, 0x7d, 0x10); + pr2020_write_register(ViPipe, 0x7e, 0x12); + pr2020_write_register(ViPipe, 0x7f, 0x14); + pr2020_write_register(ViPipe, 0x80, 0x00); + pr2020_write_register(ViPipe, 0x81, 0x09); + pr2020_write_register(ViPipe, 0x82, 0x00); + pr2020_write_register(ViPipe, 0x83, 0x07); + pr2020_write_register(ViPipe, 0x84, 0x00); + pr2020_write_register(ViPipe, 0x85, 0x17); + pr2020_write_register(ViPipe, 0x86, 0x03); + pr2020_write_register(ViPipe, 0x87, 0xe5); + pr2020_write_register(ViPipe, 0x88, 0x04); + pr2020_write_register(ViPipe, 0x89, 0x48); + pr2020_write_register(ViPipe, 0x8a, 0x04); + pr2020_write_register(ViPipe, 0x8b, 0x48); + pr2020_write_register(ViPipe, 0x8c, 0x08); + pr2020_write_register(ViPipe, 0x8d, 0xe8); + pr2020_write_register(ViPipe, 0x8e, 0x05); + pr2020_write_register(ViPipe, 0x8f, 0x47); + pr2020_write_register(ViPipe, 0x90, 0x03); + pr2020_write_register(ViPipe, 0x91, 0x13); + pr2020_write_register(ViPipe, 0x92, 0x73); + pr2020_write_register(ViPipe, 0x93, 0xe8); + pr2020_write_register(ViPipe, 0x94, 0x0f); + pr2020_write_register(ViPipe, 0x95, 0x5e); + pr2020_write_register(ViPipe, 0x96, 0x03); + pr2020_write_register(ViPipe, 0x97, 0xd0); + pr2020_write_register(ViPipe, 0x98, 0x17); + pr2020_write_register(ViPipe, 0x99, 0x34); + pr2020_write_register(ViPipe, 0x9a, 0x13); + pr2020_write_register(ViPipe, 0x9b, 0x56); + pr2020_write_register(ViPipe, 0x9c, 0x0b); + pr2020_write_register(ViPipe, 0x9d, 0x9a); + pr2020_write_register(ViPipe, 0x9e, 0x09); + pr2020_write_register(ViPipe, 0x9f, 0xab); + pr2020_write_register(ViPipe, 0xa0, 0x01); + pr2020_write_register(ViPipe, 0xa1, 0x74); + pr2020_write_register(ViPipe, 0xa2, 0x01); + pr2020_write_register(ViPipe, 0xa3, 0x6b); + pr2020_write_register(ViPipe, 0xa4, 0x00); + pr2020_write_register(ViPipe, 0xa5, 0xba); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0xa3); + pr2020_write_register(ViPipe, 0xa8, 0x01); + pr2020_write_register(ViPipe, 0xa9, 0x39); + pr2020_write_register(ViPipe, 0xaa, 0x01); + pr2020_write_register(ViPipe, 0xab, 0x39); + pr2020_write_register(ViPipe, 0xac, 0x00); + pr2020_write_register(ViPipe, 0xad, 0xc1); + pr2020_write_register(ViPipe, 0xae, 0x00); + pr2020_write_register(ViPipe, 0xaf, 0xc1); + pr2020_write_register(ViPipe, 0xb0, 0x04); + pr2020_write_register(ViPipe, 0xb1, 0xd4); + pr2020_write_register(ViPipe, 0xb2, 0x07); + pr2020_write_register(ViPipe, 0xb3, 0xda); + pr2020_write_register(ViPipe, 0xb4, 0x00); + pr2020_write_register(ViPipe, 0xb5, 0x17); + pr2020_write_register(ViPipe, 0xb6, 0x08); + pr2020_write_register(ViPipe, 0xb7, 0xe8); + pr2020_write_register(ViPipe, 0xb8, 0xb0); + pr2020_write_register(ViPipe, 0xb9, 0xce); + pr2020_write_register(ViPipe, 0xba, 0x90); + pr2020_write_register(ViPipe, 0xbb, 0x00); + pr2020_write_register(ViPipe, 0xbc, 0x00); + pr2020_write_register(ViPipe, 0xbd, 0x04); + pr2020_write_register(ViPipe, 0xbe, 0x07); + pr2020_write_register(ViPipe, 0xbf, 0x80); + pr2020_write_register(ViPipe, 0xc0, 0x00); + pr2020_write_register(ViPipe, 0xc1, 0x20); + pr2020_write_register(ViPipe, 0xc2, 0x04); + pr2020_write_register(ViPipe, 0xc3, 0x38); + + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0e); + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0f); +} + +#if (PR2020_AUTO_DETECT) +void pr2000_chip_init(VI_PIPE ViPipe) +{ + CVI_U8 lockstatus = 0; + CVI_U8 detvideo = 0; + CVI_U8 temp = 0; + + lockstatus = pr2020_read_register(ViPipe, 0x01); + detvideo = pr2020_read_register(ViPipe, 0x00); + temp = pr2020_read_register(ViPipe, 0x10); + CVI_TRACE_SNS(CVI_DBG_INFO, "detvideo = 0x%2x, lockstatus = 0x%2x, signal_type = %d, temp = 0x%2x!!!\n", + detvideo, lockstatus, signal_type, temp); + if (((lockstatus & 0x18) == 0x18) && ((detvideo & 0x08) == 0x08)) { //camera plug in + //for test start + if ((detvideo & 0x03) == 0x00) { //NTSC + if (signal_type != PR2020_MODE_720H_NTSC) {//shold set reg again + pr2020_write_register(ViPipe, 0xff, 0x00); + temp = pr2020_read_register(ViPipe, 0x11); + if (temp != 0x00) + pr2020_write_register(ViPipe, 0x11, 0x00); + delay_ms(200); + pr2020_set_cvbs_ntsc_60(ViPipe); + signal_type = PR2020_MODE_720H_NTSC; + CVI_TRACE_SNS(CVI_DBG_INFO, "pr2020 download NTSC reg!\n"); + } + } else if ((detvideo & 0x03) == 0x01) { //PAL + if (signal_type != PR2020_MODE_720H_PAL) {//shold set reg again + pr2020_write_register(ViPipe, 0xff, 0x00); + temp = pr2020_read_register(ViPipe, 0x11); + if (temp != 0x00) + pr2020_write_register(ViPipe, 0x11, 0x00); + delay_ms(200); + pr2020_set_cvbs_pal_50(ViPipe); + signal_type = PR2020_MODE_720H_PAL; + CVI_TRACE_SNS(CVI_DBG_INFO, "pr2020 download PAL reg!\n"); + } + } else if ((detvideo & 0x03) == 0x02) { //720p + if ((detvideo & 0x30) == 0x00) { //25fps + if (signal_type != PR2020_MODE_720P_25) { //shold set reg again + pr2020_write_register(ViPipe, 0xff, 0x00); + temp = pr2020_read_register(ViPipe, 0x11); + if (temp != 0x00) + pr2020_write_register(ViPipe, 0x11, 0x00); + delay_ms(200); + pr2020_set_720p_25(ViPipe); + signal_type = PR2020_MODE_720P_25; + CVI_TRACE_SNS(CVI_DBG_INFO, "pr2020 download 720P 25fps reg!\n"); + } + } else if ((detvideo & 0x30) == 0x10) { //30fps + if (signal_type != PR2020_MODE_720P_30) { //shold set reg again + pr2020_write_register(ViPipe, 0xff, 0x00); + temp = pr2020_read_register(ViPipe, 0x11); + if (temp != 0x00) + pr2020_write_register(ViPipe, 0x11, 0x00); + delay_ms(200); + pr2020_set_720p_30(ViPipe); + signal_type = PR2020_MODE_720P_30; + CVI_TRACE_SNS(CVI_DBG_INFO, "pr2020 download 720P 30fps reg!\n"); + } + } else if ((detvideo & 0x30) == 0x20) { //50fps + signal_type = PR2020_MODE_NONE; + CVI_TRACE_SNS(CVI_DBG_INFO, "detect video fmt is 720P 50fps\n"); + } else if ((detvideo & 0x30) == 0x30) { //60fps + signal_type = PR2020_MODE_NONE; + CVI_TRACE_SNS(CVI_DBG_INFO, "detect video fmt is 720P 60fps\n"); + } + } else if ((detvideo & 0x03) == 0x03) { //1080p + if ((detvideo & 0x30) == 0x00) { //25fps + if (signal_type != PR2020_MODE_1080P_25) { //shold set reg again + pr2020_write_register(ViPipe, 0xff, 0x00); + temp = pr2020_read_register(ViPipe, 0x11); + if (temp != 0x00) + pr2020_write_register(ViPipe, 0x11, 0x00); + delay_ms(200); + pr2020_set_1080p_25(ViPipe); + signal_type = PR2020_MODE_1080P_25; + CVI_TRACE_SNS(CVI_DBG_INFO, "pr2020 download full hd 1080p 25fps reg!\n"); + } + } else if ((detvideo & 0x30) == 0x10) { //30fps + if (signal_type != PR2020_MODE_1080P_30) { //shold set reg again + pr2020_write_register(ViPipe, 0xff, 0x00); + temp = pr2020_read_register(ViPipe, 0x11); + if (temp != 0x00) + pr2020_write_register(ViPipe, 0x11, 0x00); + delay_ms(200); + pr2020_set_1080p_30(ViPipe); + signal_type = PR2020_MODE_1080P_30; + CVI_TRACE_SNS(CVI_DBG_INFO, "pr2020 download full hd 1080p 30fps reg!\n"); + } + } + } else { + CVI_TRACE_SNS(CVI_DBG_INFO, "detect nothing!!!\n"); + signal_type = PR2020_MODE_NONE; + } + pr2020_write_register(ViPipe, 0xff, 0x00); +#if 0 + //for test end + //read camera plug and signal state + //mdelay(100); + CVI_TRACE_SNS(CVI_DBG_INFO, "pr2020 read reg 0x%2x, 0x%2x, 0x%2x, 0x%2x, 0x%2x\n", + pr2020_read_register(ViPipe, 0xff), + pr2020_read_register(ViPipe, 0x00), + pr2020_read_register(ViPipe, 0x01), + pr2020_read_register(ViPipe, 0x10), + pr2020_read_register(ViPipe, 0x11)); + +#endif + } else { + pr2020_write_register(ViPipe, 0xff, 0x00); + pr2020_write_register(ViPipe, 0x11, 0x00); + signal_type = PR2020_MODE_NONE; + CVI_TRACE_SNS(CVI_DBG_INFO, "pr2020 has no signal!\n"); + } +} + +static void *pr2020_device_auto_detect(void *arg) +{ + VI_PIPE ViPipe = *(CVI_U8 *)arg; + PR2020_MODE_E signal_type_old = signal_type; + + free(arg); + while (1) { + delay_ms(500); //500ms + pr2000_chip_init(ViPipe); //do it day and night + if (signal_type_old != signal_type) { + signal_type_old = signal_type; + CVI_VI_Trig_AHD(ViPipe, 1); + } + } + return NULL; +} +#endif + +void pr2020_init(VI_PIPE ViPipe) +{ + if (pr2020_sys_init(ViPipe) != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "PR2020 sys init fail\n"); + return; + } + + delay_ms(20); + + if (pr2020_i2c_init(ViPipe) != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "PR2020 i2c init fail\n"); + return; + } + + // check sensor chip id + pr2020_write_register(ViPipe, 0xff, 0x00); + if (((pr2020_read_register(ViPipe, 0xfc) << 8) | (pr2020_read_register(ViPipe, 0xfd))) != 0x2000) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read PR2020 chip id fail\n"); + return; + } + + CVI_TRACE_SNS(CVI_DBG_INFO, "Loading Pixelplus PR2020 sensor\n"); + + pr2020_write_register(ViPipe, 0xff, 0x00);//reset + pr2020_write_register(ViPipe, 0x11, 0x00); + + pr2020_fw_init(ViPipe); + + signal_type = g_pastPr2020[ViPipe]->u8ImgMode; + if (signal_type == PR2020_MODE_720P_25) { + pr2020_set_720p_25(ViPipe); + } else if (signal_type == PR2020_MODE_720P_30) { + pr2020_set_720p_30(ViPipe); + } else if (signal_type == PR2020_MODE_1080P_25) { + pr2020_set_1080p_25(ViPipe); + } else if (signal_type == PR2020_MODE_1080P_30) { + pr2020_set_1080p_30(ViPipe); + } + CVI_TRACE_SNS(CVI_DBG_INFO, "signal_type=%d\n", signal_type); + // wait for signal to stabilize + delay_ms(800); + pr2020_write_register(ViPipe, 0xff, 0x00);//page0 +#if PR2020_AUTO_DETECT + CVI_U8 *arg = malloc(sizeof(*arg)); + + *arg = ViPipe; + if (pthread_create(&g_pr2020_thid, NULL, pr2020_device_auto_detect, arg) != 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "PR2020 auto detect function fail!\n"); + } +#endif +} + +void pr2020_exit(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "Exit Pixelplus PR2020 Sensor\n"); + + if (g_pr2020_thid) + pthread_kill(g_pr2020_thid, SIGQUIT); + + pr2020_i2c_exit(ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2100/Makefile b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2100/Makefile new file mode 100644 index 000000000..4b21c77e0 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2100/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_pr2100.a +TARGET_SO = $(MW_LIB)/libsns_pr2100.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2100/pr2100_cmos.c b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2100/pr2100_cmos.c new file mode 100644 index 000000000..f2dcfe8ea --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2100/pr2100_cmos.c @@ -0,0 +1,314 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_isp.h" + +#include "pr2100_cmos_ex.h" +#include "pr2100_cmos_param.h" + +/**************************************************************************** + * global variables * + ****************************************************************************/ +ISP_SNS_COMMBUS_U g_aunPr2100_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_STATE_S *g_pastPr2100[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define PR2100_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastPr2100[dev]) +#define PR2100_SENSOR_SET_CTX(dev, pstCtx) (g_pastPr2100[dev] = pstCtx) +#define PR2100_SENSOR_RESET_CTX(dev) (g_pastPr2100[dev] = CVI_NULL) + +#define PR2100_RES_IS_2M(w, h) ((w) <= 1920 && (h) <= 1080) +#define PR2100_ID 2100 + +CVI_U16 g_au16Pr2100_BdgMuxMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const PR2100_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + PR2100_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astPr2100_mode[pstSnsState->u8ImgMode]; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + PR2100_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstCfg0 = &pstSnsState->astSyncInfo[0]; + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + PR2100_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + + if (pstSensorImageMode->f32Fps <= 30) { + if (PR2100_RES_IS_2M(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + switch (g_au16Pr2100_BdgMuxMode[ViPipe]) { + case SNS_BDG_MUX_NONE: + u8SensorImageMode = PR2100_MODE_1080P; + break; + case SNS_BDG_MUX_2: + u8SensorImageMode = PR2100_MODE_1080P_2CH; + break; + case SNS_BDG_MUX_3: + case SNS_BDG_MUX_4: + u8SensorImageMode = PR2100_MODE_1080P_4CH; + break; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + PR2100_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->u8ImgMode = PR2100_MODE_1080P; + pstSnsState->enWDRMode = WDR_MODE_NONE; +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + PR2100_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &pr2100_multi_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astPr2100_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astPr2100_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + + if (pstSnsState->u8ImgMode == PR2100_MODE_1080P) { + pstRxAttr->mac_clk = RX_MAC_CLK_400M; + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + pstRxAttr->mipi_attr.demux.demux_en = 0; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &pr2100_multi_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = pr2100_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = pr2100_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 pr2100_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunPr2100_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + PR2100_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + PR2100_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + PR2100_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + PR2100_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + (void) pstAeLib; + (void) pstAwbLib; + + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = PR2100_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + (void) pstAeLib; + (void) pstAwbLib; + + CVI_S32 s32Ret; + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, PR2100_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + g_au16Pr2100_BdgMuxMode[ViPipe] = pstInitAttr->enSnsBdgMuxMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsPR2100_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = CVI_NULL, + .pfnRestart = CVI_NULL, + .pfnMirrorFlip = CVI_NULL, + .pfnWriteReg = pr2100_write_register, + .pfnReadReg = pr2100_read_register, + .pfnSetBusInfo = pr2100_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = CVI_NULL, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2100/pr2100_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2100/pr2100_cmos_ex.h new file mode 100644 index 000000000..3bb5e7495 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2100/pr2100_cmos_ex.h @@ -0,0 +1,65 @@ +#ifndef __PR2100_CMOS_EX_H_ +#define __PR2100_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +typedef enum _PR2100_MODE_E { + PR2100_MODE_NONE, + PR2100_MODE_1080P, + PR2100_MODE_1080P_2CH, + PR2100_MODE_1080P_4CH, + PR2100_MODE_NUM +} PR2100_MODE_E; + +typedef struct _PR2100_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + char name[64]; +} PR2100_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastPr2100[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunPr2100_BusInfo[]; +extern const CVI_U8 pr2100_i2c_addr; +extern const CVI_U32 pr2100_addr_byte; +extern const CVI_U32 pr2100_data_byte; +extern void pr2100_init(VI_PIPE ViPipe); +extern void pr2100_exit(VI_PIPE ViPipe); +extern void pr2100_standby(VI_PIPE ViPipe); +extern void pr2100_restart(VI_PIPE ViPipe); +extern int pr2100_write_register(VI_PIPE ViPipe, int addr, int data); +extern int pr2100_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __PR2100_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2100/pr2100_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2100/pr2100_cmos_param.h new file mode 100644 index 000000000..c0413d8ad --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2100/pr2100_cmos_param.h @@ -0,0 +1,109 @@ +#ifndef __PR2100_CMOS_PARAM_H_ +#define __PR2100_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "pr2100_cmos_ex.h" + +static const PR2100_MODE_S g_astPr2100_mode[PR2100_MODE_NUM] = { + [PR2100_MODE_1080P] = { + .name = "1080p25", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + }, + [PR2100_MODE_1080P_2CH] = { + .name = "1080p25_2ch", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + }, + [PR2100_MODE_1080P_4CH] = { + .name = "1080p25_4ch", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + }, +}; + +struct combo_dev_attr_s pr2100_multi_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_600M, + .mipi_attr = { + .raw_data_type = YUV422_8BIT, + .lane_id = {0, 1, 2, 3, 4}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + .demux = { + .demux_en = 1, + .vc_mapping = {0, 1, 2, 3}, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_NONE, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __PR2100_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2100/pr2100_sensor_ctrl.c b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2100/pr2100_sensor_ctrl.c new file mode 100644 index 000000000..77c52ab7c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/pixelplus_pr2100/pr2100_sensor_ctrl.c @@ -0,0 +1,2431 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include +#include "cvi_sns_ctrl.h" +#include "pr2100_cmos_ex.h" +#include +#include + +static void pr2100_set_1080p(VI_PIPE ViPipe); +static void pr2100_set_1080p_2ch(VI_PIPE ViPipe); +static void pr2100_set_1080p_4ch(VI_PIPE ViPipe); + +const CVI_U8 pr2100_master_i2c_addr = 0x5C; /* I2C slave address of PR2100 master chip*/ +const CVI_U8 pr2100_slave_i2c_addr = 0x5F; /* I2C slave address of PR2100 slave chip*/ +const CVI_U32 pr2100_addr_byte = 1; +const CVI_U32 pr2100_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; +static VI_PIPE slave_pipe = (VI_MAX_PIPE_NUM - 1); + +#define PR2100_TEST_PATTERN 0 +#define PR2100_SLAVE_TEST_PATTERN 0 + +#if (PR2100_TEST_PATTERN) +//1920x1080 offset 0x0 0x1FA400 0x278D00 +// 0 : White eb 80 80 +// 1 : Yellow d2 10 92 +// 2 : Cyan aa a6 10 +// 3 : Green 91 36 22 +// 4 : Magenta 6a ca de +// 5 : Red 51 5a f0 +// 6 : Blue +// 7 : Black +// 8 : Color Bar +// 9 : Ramp +// 10 : Inverse Color Bar +// 11 : Combination Pattern +#define output_pattern_ch0 (0x8 | 0x80) // color bar +#define output_pattern_ch1 (0x8 | 0xA0) // reverse color bar +#define output_pattern_ch2 (0x8 | 0x80) // color bar +#define output_pattern_ch3 (0x8 | 0xA0) // reverse color bar +#else +#define output_pattern_ch0 (0x00) +#define output_pattern_ch1 (0x00) +#define output_pattern_ch2 (0x00) +#define output_pattern_ch3 (0x00) +#endif + +/*gpio*/ +enum CVI_GPIO_NUM_E { +CVI_GPIOD_00 = 404, +CVI_GPIOD_01, CVI_GPIOD_02, CVI_GPIOD_03, CVI_GPIOD_04, CVI_GPIOD_05, +CVI_GPIOD_06, CVI_GPIOD_07, CVI_GPIOD_08, CVI_GPIOD_09, CVI_GPIOD_10, +CVI_GPIOD_11, +CVI_GPIOC_00 = 416, +CVI_GPIOC_01, CVI_GPIOC_02, CVI_GPIOC_03, CVI_GPIOC_04, CVI_GPIOC_05, +CVI_GPIOC_06, CVI_GPIOC_07, CVI_GPIOC_08, CVI_GPIOC_09, CVI_GPIOC_10, +CVI_GPIOC_11, CVI_GPIOC_12, CVI_GPIOC_13, CVI_GPIOC_14, CVI_GPIOC_15, +CVI_GPIOC_16, CVI_GPIOC_17, CVI_GPIOC_18, CVI_GPIOC_19, CVI_GPIOC_20, +CVI_GPIOC_21, CVI_GPIOC_22, CVI_GPIOC_23, CVI_GPIOC_24, CVI_GPIOC_25, +CVI_GPIOC_26, CVI_GPIOC_27, CVI_GPIOC_28, CVI_GPIOC_29, CVI_GPIOC_30, +CVI_GPIOC_31, +CVI_GPIOB_00 = 448, +CVI_GPIOB_01, CVI_GPIOB_02, CVI_GPIOB_03, CVI_GPIOB_04, CVI_GPIOB_05, +CVI_GPIOB_06, CVI_GPIOB_07, CVI_GPIOB_08, CVI_GPIOB_09, CVI_GPIOB_10, +CVI_GPIOB_11, CVI_GPIOB_12, CVI_GPIOB_13, CVI_GPIOB_14, CVI_GPIOB_15, +CVI_GPIOB_16, CVI_GPIOB_17, CVI_GPIOB_18, CVI_GPIOB_19, CVI_GPIOB_20, +CVI_GPIOB_21, CVI_GPIOB_22, CVI_GPIOB_23, CVI_GPIOB_24, CVI_GPIOB_25, +CVI_GPIOB_26, CVI_GPIOB_27, CVI_GPIOB_28, CVI_GPIOB_29, CVI_GPIOB_30, +CVI_GPIOB_31, +CVI_GPIOA_00 = 480, +CVI_GPIOA_01, CVI_GPIOA_02, CVI_GPIOA_03, CVI_GPIOA_04, CVI_GPIOA_05, +CVI_GPIOA_06, CVI_GPIOA_07, CVI_GPIOA_08, CVI_GPIOA_09, CVI_GPIOA_10, +CVI_GPIOA_11, CVI_GPIOA_12, CVI_GPIOA_13, CVI_GPIOA_14, CVI_GPIOA_15, +CVI_GPIOA_16, CVI_GPIOA_17, CVI_GPIOA_18, CVI_GPIOA_19, CVI_GPIOA_20, +CVI_GPIOA_21, CVI_GPIOA_22, CVI_GPIOA_23, CVI_GPIOA_24, CVI_GPIOA_25, +CVI_GPIOA_26, CVI_GPIOA_27, CVI_GPIOA_28, CVI_GPIOA_29, CVI_GPIOA_30, +CVI_GPIOA_31, +}; + +#define CVI_GPIO_MIN CVI_GPIOD_00 +#define CVI_GPIO_MAX CVI_GPIOA_31 + +#define SYSFS_GPIO_DIR "/sys/class/gpio" +#define MAX_BUF 64 + +static int PR2100_GPIO_Export(unsigned int gpio) +{ + int fd, len; + char buf[MAX_BUF]; + + fd = open(SYSFS_GPIO_DIR"/export", O_WRONLY); + if (fd < 0) { + perror("gpio/export"); + return fd; + } + + len = snprintf(buf, sizeof(buf), "%d", gpio); + write(fd, buf, len); + close(fd); + + return 0; +} + +static int PR2100_GPIO_SetDirection(unsigned int gpio, unsigned int out_flag) +{ + int fd; + char buf[MAX_BUF]; + + snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR"/gpio%d/direction", gpio); + if (access(buf, 0) == -1) + PR2100_GPIO_Export(gpio); + + fd = open(buf, O_WRONLY); + if (fd < 0) { + perror("gpio/direction"); + return fd; + } + //printf("mark %d , %s\n",out_flag, buf); + if (out_flag) + write(fd, "out", 4); + else + write(fd, "in", 3); + + close(fd); + return 0; +} + +static int PR2100_GPIO_SetValue(unsigned int gpio, unsigned int value) +{ + int fd; + char buf[MAX_BUF]; + + snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR"/gpio%d/value", gpio); + if (access(buf, 0) == -1) + PR2100_GPIO_Export(gpio); + + PR2100_GPIO_SetDirection(gpio, 1); //output + + fd = open(buf, O_WRONLY); + if (fd < 0) { + perror("gpio/set-value"); + return fd; + } + + if (value) + write(fd, "1", 2); + else + write(fd, "0", 2); + + close(fd); + return 0; +} + +int pr2100_sys_init(VI_PIPE ViPipe) +{ + (void) ViPipe; + + //CAM_PEN + if (PR2100_GPIO_SetValue(CVI_GPIOA_06, 1) != 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "set power down gpio error!\n"); + return CVI_FAILURE; + } +#if 0 + //SENSOR0_RSTN + if (PR2100_GPIO_SetValue(CVI_GPIOD_07, 1) != 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "set reset gpio error!\n"); + return CVI_FAILURE; + } + + //BACK_DET + if (PR2100_GPIO_SetValue(CVI_GPIOD_01, 1) != 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "set back detect gpio error!\n"); + return CVI_FAILURE; + } +#endif + return CVI_SUCCESS; +} + +int pr2100_i2c_init(VI_PIPE ViPipe, CVI_U8 i2c_addr) +{ + int ret; + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + + u8DevNum = g_aunPr2100_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + CVI_TRACE_SNS(CVI_DBG_INFO, "open %s\n", acDevFile); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int pr2100_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int pr2100_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return 0; + + if (pr2100_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, pr2100_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, pr2100_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (pr2100_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + CVI_TRACE_SNS(CVI_DBG_INFO, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int pr2100_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (pr2100_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + if (pr2100_data_byte == 2) + buf[idx++] = (data >> 8) & 0xff; + + // add data byte 0 + buf[idx++] = data & 0xff; + + ret = write(g_fd[ViPipe], buf, pr2100_addr_byte + pr2100_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + CVI_TRACE_SNS(CVI_DBG_INFO, "i2c w 0x%x 0x%x\n", addr, data); + +#if 0 // read back checing + ret = pr2100_read_register(ViPipe, addr); + if (ret != data) + CVI_TRACE_SNS(CVI_DBG_INFO, "i2c readback-check fail, 0x%x != 0x%x\n", ret, data); +#endif + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void pr2100_init(VI_PIPE ViPipe) +{ + CVI_U8 u8ImgMode; + + u8ImgMode = g_pastPr2100[ViPipe]->u8ImgMode; + if (ViPipe) // only init ch0 + return; + + if (pr2100_sys_init(ViPipe) != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "PR2100 sys init fail\n"); + return; + } + + delay_ms(20); + + if (pr2100_i2c_init(ViPipe, pr2100_master_i2c_addr) != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "PR2100 master i2c init fail\n"); + return; + } + + // check sensor chip id + pr2100_write_register(ViPipe, 0xff, 0x00); + if (((pr2100_read_register(ViPipe, 0xfc) << 8) | + (pr2100_read_register(ViPipe, 0xfd))) != 0x2100) { + CVI_TRACE_SNS(CVI_DBG_ERR, "PR2100 master chip id check fail\n"); + return; + } + + CVI_TRACE_SNS(CVI_DBG_INFO, "Loading Pixelplus PR2100 sensor\n"); + + switch (u8ImgMode) { + case PR2100_MODE_1080P: + pr2100_set_1080p(ViPipe); + break; + case PR2100_MODE_1080P_2CH: + pr2100_set_1080p_2ch(ViPipe); + break; + case PR2100_MODE_1080P_4CH: + g_aunPr2100_BusInfo[slave_pipe].s8I2cDev = g_aunPr2100_BusInfo[ViPipe].s8I2cDev; + if (pr2100_i2c_init(slave_pipe, pr2100_slave_i2c_addr) != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "PR2100 slave i2c init fail\n"); + break; + } + pr2100_write_register(slave_pipe, 0xff, 0x00); + if (((pr2100_read_register(slave_pipe, 0xfc) << 8) | + (pr2100_read_register(slave_pipe, 0xfd))) != 0x2100) { + CVI_TRACE_SNS(CVI_DBG_ERR, "PR2100 slave chip id check fail\n"); + break; + } + pr2100_set_1080p_4ch(ViPipe); + break; + default: + break; + } + + // wait for signal to stabilize + delay_ms(800); + pr2100_write_register(ViPipe, 0xff, 0x00);//page0 +} + +void pr2100_exit(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "Exit Pixelplus PR2100 Sensor\n"); + + pr2100_i2c_exit(ViPipe); + + if (g_pastPr2100[ViPipe]->u8ImgMode == PR2100_MODE_1080P_4CH) + pr2100_i2c_exit(slave_pipe); +} + +static void pr2100_set_1080p(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "1CH ViPipe=%d\n", ViPipe); + pr2100_write_register(ViPipe, 0xff, 0x00);//Page0 + pr2100_write_register(ViPipe, 0xc0, 0x21); + pr2100_write_register(ViPipe, 0xc1, 0x21); + pr2100_write_register(ViPipe, 0xc2, 0x21); + pr2100_write_register(ViPipe, 0xc3, 0x21); + pr2100_write_register(ViPipe, 0xc4, 0x21); + pr2100_write_register(ViPipe, 0xc5, 0x21); + pr2100_write_register(ViPipe, 0xc6, 0x21); + pr2100_write_register(ViPipe, 0xc7, 0x21); + pr2100_write_register(ViPipe, 0xc8, 0x21); + pr2100_write_register(ViPipe, 0xc9, 0x01); + pr2100_write_register(ViPipe, 0xca, 0x01); + pr2100_write_register(ViPipe, 0xcb, 0x01); + pr2100_write_register(ViPipe, 0xd0, 0x06); + pr2100_write_register(ViPipe, 0xd1, 0x23); + pr2100_write_register(ViPipe, 0xd2, 0x21); + pr2100_write_register(ViPipe, 0xd3, 0x44); + pr2100_write_register(ViPipe, 0xd4, 0x06); + pr2100_write_register(ViPipe, 0xd5, 0x23); + pr2100_write_register(ViPipe, 0xd6, 0x21); + pr2100_write_register(ViPipe, 0xd7, 0x44); + pr2100_write_register(ViPipe, 0xd8, 0x06); + pr2100_write_register(ViPipe, 0xd9, 0x22); + pr2100_write_register(ViPipe, 0xda, 0x2c); + pr2100_write_register(ViPipe, 0x11, 0x0f); + pr2100_write_register(ViPipe, 0x12, 0x00); + pr2100_write_register(ViPipe, 0x13, 0x00); + pr2100_write_register(ViPipe, 0x14, 0x21); + pr2100_write_register(ViPipe, 0x15, 0x44); + pr2100_write_register(ViPipe, 0x16, 0x0d); + pr2100_write_register(ViPipe, 0x31, 0x0f); + pr2100_write_register(ViPipe, 0x32, 0x00); + pr2100_write_register(ViPipe, 0x33, 0x00); + pr2100_write_register(ViPipe, 0x34, 0x21); + pr2100_write_register(ViPipe, 0x35, 0x44); + pr2100_write_register(ViPipe, 0x36, 0x0d); + pr2100_write_register(ViPipe, 0xf3, 0x06); + pr2100_write_register(ViPipe, 0xf4, 0x66); + pr2100_write_register(ViPipe, 0xff, 0x01);//Page1 + pr2100_write_register(ViPipe, 0x00, 0xe4); + pr2100_write_register(ViPipe, 0x01, 0x61); + pr2100_write_register(ViPipe, 0x02, 0x00); + pr2100_write_register(ViPipe, 0x03, 0x56); + pr2100_write_register(ViPipe, 0x04, 0x0c); + pr2100_write_register(ViPipe, 0x05, 0x88); + pr2100_write_register(ViPipe, 0x06, 0x04); + pr2100_write_register(ViPipe, 0x07, 0xb2); + pr2100_write_register(ViPipe, 0x08, 0x44); + pr2100_write_register(ViPipe, 0x09, 0x34); + pr2100_write_register(ViPipe, 0x0a, 0x02); + pr2100_write_register(ViPipe, 0x0b, 0x14); + pr2100_write_register(ViPipe, 0x0c, 0x04); + pr2100_write_register(ViPipe, 0x0d, 0x08); + pr2100_write_register(ViPipe, 0x0e, 0x5e); + pr2100_write_register(ViPipe, 0x0f, 0x5e); + pr2100_write_register(ViPipe, 0x2c, 0x00); + pr2100_write_register(ViPipe, 0x2d, 0x00); + pr2100_write_register(ViPipe, 0x2e, 0x00); + pr2100_write_register(ViPipe, 0x2f, 0x00); + pr2100_write_register(ViPipe, 0x30, 0x00); + pr2100_write_register(ViPipe, 0x31, 0x00); + pr2100_write_register(ViPipe, 0x32, 0xc0); + pr2100_write_register(ViPipe, 0x3b, 0x02); + pr2100_write_register(ViPipe, 0x3c, 0x01); + pr2100_write_register(ViPipe, 0x4f, 0x00); + pr2100_write_register(ViPipe, 0x51, 0x28); + pr2100_write_register(ViPipe, 0x52, 0x40); + pr2100_write_register(ViPipe, 0x53, 0x0c); + pr2100_write_register(ViPipe, 0x54, 0x0f); + pr2100_write_register(ViPipe, 0x55, 0x8d); + pr2100_write_register(ViPipe, 0x70, 0x06); + pr2100_write_register(ViPipe, 0x71, 0x08); + pr2100_write_register(ViPipe, 0x72, 0x0a); + pr2100_write_register(ViPipe, 0x73, 0x0c); + pr2100_write_register(ViPipe, 0x74, 0x0e); + pr2100_write_register(ViPipe, 0x75, 0x10); + pr2100_write_register(ViPipe, 0x76, 0x12); + pr2100_write_register(ViPipe, 0x77, 0x14); + pr2100_write_register(ViPipe, 0x78, 0x06); + pr2100_write_register(ViPipe, 0x79, 0x08); + pr2100_write_register(ViPipe, 0x7a, 0x0a); + pr2100_write_register(ViPipe, 0x7b, 0x0c); + pr2100_write_register(ViPipe, 0x7c, 0x0e); + pr2100_write_register(ViPipe, 0x7d, 0x10); + pr2100_write_register(ViPipe, 0x7e, 0x12); + pr2100_write_register(ViPipe, 0x7f, 0x14); + pr2100_write_register(ViPipe, 0xff, 0x02);//Page2 + pr2100_write_register(ViPipe, 0x00, 0xe4); + pr2100_write_register(ViPipe, 0x01, 0x61); + pr2100_write_register(ViPipe, 0x02, 0x00); + pr2100_write_register(ViPipe, 0x03, 0x56); + pr2100_write_register(ViPipe, 0x04, 0x0c); + pr2100_write_register(ViPipe, 0x05, 0x88); + pr2100_write_register(ViPipe, 0x06, 0x04); + pr2100_write_register(ViPipe, 0x07, 0xb2); + pr2100_write_register(ViPipe, 0x08, 0x44); + pr2100_write_register(ViPipe, 0x09, 0x34); + pr2100_write_register(ViPipe, 0x0a, 0x02); + pr2100_write_register(ViPipe, 0x0b, 0x14); + pr2100_write_register(ViPipe, 0x0c, 0x04); + pr2100_write_register(ViPipe, 0x0d, 0x08); + pr2100_write_register(ViPipe, 0x0e, 0x5e); + pr2100_write_register(ViPipe, 0x0f, 0x5e); + pr2100_write_register(ViPipe, 0x2c, 0x00); + pr2100_write_register(ViPipe, 0x2d, 0x00); + pr2100_write_register(ViPipe, 0x2e, 0x00); + pr2100_write_register(ViPipe, 0x2f, 0x00); + pr2100_write_register(ViPipe, 0x30, 0x00); + pr2100_write_register(ViPipe, 0x31, 0x00); + pr2100_write_register(ViPipe, 0x32, 0xc0); + pr2100_write_register(ViPipe, 0x3b, 0x02); + pr2100_write_register(ViPipe, 0x3c, 0x01); + pr2100_write_register(ViPipe, 0x4f, 0x00); + pr2100_write_register(ViPipe, 0x51, 0x28); + pr2100_write_register(ViPipe, 0x52, 0x40); + pr2100_write_register(ViPipe, 0x53, 0x0c); + pr2100_write_register(ViPipe, 0x54, 0x0f); + pr2100_write_register(ViPipe, 0x55, 0x8d); + pr2100_write_register(ViPipe, 0x70, 0x06); + pr2100_write_register(ViPipe, 0x71, 0x08); + pr2100_write_register(ViPipe, 0x72, 0x0a); + pr2100_write_register(ViPipe, 0x73, 0x0c); + pr2100_write_register(ViPipe, 0x74, 0x0e); + pr2100_write_register(ViPipe, 0x75, 0x10); + pr2100_write_register(ViPipe, 0x76, 0x12); + pr2100_write_register(ViPipe, 0x77, 0x14); + pr2100_write_register(ViPipe, 0x78, 0x06); + pr2100_write_register(ViPipe, 0x79, 0x08); + pr2100_write_register(ViPipe, 0x7a, 0x0a); + pr2100_write_register(ViPipe, 0x7b, 0x0c); + pr2100_write_register(ViPipe, 0x7c, 0x0e); + pr2100_write_register(ViPipe, 0x7d, 0x10); + pr2100_write_register(ViPipe, 0x7e, 0x12); + pr2100_write_register(ViPipe, 0x7f, 0x14); + pr2100_write_register(ViPipe, 0xff, 0x00);//Page0 + pr2100_write_register(ViPipe, 0x14, 0x21); + pr2100_write_register(ViPipe, 0xff, 0x06);//Page6 + pr2100_write_register(ViPipe, 0x04, 0x50); + pr2100_write_register(ViPipe, 0xff, 0x00);//Page0 + pr2100_write_register(ViPipe, 0xeb, 0x01); + pr2100_write_register(ViPipe, 0xf0, 0x03); + pr2100_write_register(ViPipe, 0xf1, 0xff); + pr2100_write_register(ViPipe, 0xea, 0x00); + // pr2100_write_register(ViPipe, 0xe3, 0x04);//Cb-Y-Cr-Y + pr2100_write_register(ViPipe, 0xe3, 0xc4);//Y-Cb-Y-Cr + pr2100_write_register(ViPipe, 0xff, 0x01);//Page1 + pr2100_write_register(ViPipe, 0x50, 0x21); + pr2100_write_register(ViPipe, 0x4f, 0x00); + pr2100_write_register(ViPipe, 0x50, 0x21); + pr2100_write_register(ViPipe, 0x4f, 0x20); + pr2100_write_register(ViPipe, 0xff, 0x02);//Page2 + pr2100_write_register(ViPipe, 0x50, 0x21); + pr2100_write_register(ViPipe, 0x4f, 0x00); + pr2100_write_register(ViPipe, 0x50, 0x21); + pr2100_write_register(ViPipe, 0x4f, 0x20); + pr2100_write_register(ViPipe, 0xff, 0x01);//Page1 + pr2100_write_register(ViPipe, 0xd1, 0x10); + pr2100_write_register(ViPipe, 0xff, 0x00);//Page0 + pr2100_write_register(ViPipe, 0xe8, 0x00); + pr2100_write_register(ViPipe, 0xe9, 0x10); + pr2100_write_register(ViPipe, 0xff, 0x01);//Page1 + pr2100_write_register(ViPipe, 0xcd, 0x08); + pr2100_write_register(ViPipe, 0x4f, 0x2c); + pr2100_write_register(ViPipe, 0xff, 0x02);//Page2 + pr2100_write_register(ViPipe, 0xd1, 0x10); + pr2100_write_register(ViPipe, 0xff, 0x00);//Page0 + pr2100_write_register(ViPipe, 0xe9, 0x00); + pr2100_write_register(ViPipe, 0xe9, 0x00); + pr2100_write_register(ViPipe, 0xff, 0x02);//Page2 + pr2100_write_register(ViPipe, 0xcd, 0x08); + pr2100_write_register(ViPipe, 0x4f, 0x2c); + pr2100_write_register(ViPipe, 0xff, 0x00);//Page0 + pr2100_write_register(ViPipe, 0xe4, 0x20); + pr2100_write_register(ViPipe, 0xe5, 0x64); + pr2100_write_register(ViPipe, 0xe6, 0x20); + pr2100_write_register(ViPipe, 0xe7, 0x64); + pr2100_write_register(ViPipe, 0xe2, 0x00); + pr2100_write_register(ViPipe, 0xff, 0x06);//Page6 + pr2100_write_register(ViPipe, 0x04, 0x10); + pr2100_write_register(ViPipe, 0x05, 0x04); + pr2100_write_register(ViPipe, 0x06, 0x00); + pr2100_write_register(ViPipe, 0x07, 0x00); + pr2100_write_register(ViPipe, 0x08, 0xc9); + pr2100_write_register(ViPipe, 0x36, 0x0f); + pr2100_write_register(ViPipe, 0x37, 0x00); + pr2100_write_register(ViPipe, 0x38, 0x0f); + pr2100_write_register(ViPipe, 0x39, 0x00); + pr2100_write_register(ViPipe, 0x3a, 0x0f); + pr2100_write_register(ViPipe, 0x3b, 0x00); + pr2100_write_register(ViPipe, 0x3c, 0x0f); + pr2100_write_register(ViPipe, 0x3d, 0x00); + pr2100_write_register(ViPipe, 0x46, 0x1e); + pr2100_write_register(ViPipe, 0x47, 0x5e); + pr2100_write_register(ViPipe, 0x48, 0x9e); + pr2100_write_register(ViPipe, 0x49, 0xde); + pr2100_write_register(ViPipe, 0x1c, 0x09); + pr2100_write_register(ViPipe, 0x1d, 0x08); + pr2100_write_register(ViPipe, 0x1e, 0x09); + pr2100_write_register(ViPipe, 0x1f, 0x11); + pr2100_write_register(ViPipe, 0x20, 0x0c); + pr2100_write_register(ViPipe, 0x21, 0x28); + pr2100_write_register(ViPipe, 0x22, 0x0b); + pr2100_write_register(ViPipe, 0x23, 0x01); + pr2100_write_register(ViPipe, 0x24, 0x12); + pr2100_write_register(ViPipe, 0x25, 0x82); + pr2100_write_register(ViPipe, 0x26, 0x11); + pr2100_write_register(ViPipe, 0x27, 0x11); + pr2100_write_register(ViPipe, 0x04, 0x50); + pr2100_write_register(ViPipe, 0xff, 0x05);//Page5 + pr2100_write_register(ViPipe, 0x09, 0x00); + pr2100_write_register(ViPipe, 0x0a, 0x03); + pr2100_write_register(ViPipe, 0x0e, 0x80); + pr2100_write_register(ViPipe, 0x0f, 0x10); + pr2100_write_register(ViPipe, 0x11, 0x80); + pr2100_write_register(ViPipe, 0x12, 0x6e); + pr2100_write_register(ViPipe, 0x13, 0x00); + pr2100_write_register(ViPipe, 0x14, 0x6e); + pr2100_write_register(ViPipe, 0x15, 0x00); + pr2100_write_register(ViPipe, 0x16, 0x00); + pr2100_write_register(ViPipe, 0x17, 0x00); + pr2100_write_register(ViPipe, 0x18, 0x00); + pr2100_write_register(ViPipe, 0x19, 0x00); + pr2100_write_register(ViPipe, 0x1a, 0x00); + pr2100_write_register(ViPipe, 0x1b, 0x00); + pr2100_write_register(ViPipe, 0x1c, 0x00); + pr2100_write_register(ViPipe, 0x1d, 0x00); + pr2100_write_register(ViPipe, 0x1e, 0x00); + pr2100_write_register(ViPipe, 0x20, 0x88); + pr2100_write_register(ViPipe, 0x21, 0x07); + pr2100_write_register(ViPipe, 0x22, 0x80); + pr2100_write_register(ViPipe, 0x23, 0x04); + pr2100_write_register(ViPipe, 0x24, 0x38); + pr2100_write_register(ViPipe, 0x25, 0x0f); + pr2100_write_register(ViPipe, 0x26, 0x00); + pr2100_write_register(ViPipe, 0x27, 0x0f); + pr2100_write_register(ViPipe, 0x28, 0x00); + pr2100_write_register(ViPipe, 0x29, 0x0b); + pr2100_write_register(ViPipe, 0x2a, 0x40); + pr2100_write_register(ViPipe, 0x30, 0x18); + pr2100_write_register(ViPipe, 0x31, 0x07); + pr2100_write_register(ViPipe, 0x32, 0x80); + pr2100_write_register(ViPipe, 0x33, 0x04); + pr2100_write_register(ViPipe, 0x34, 0x38); + pr2100_write_register(ViPipe, 0x35, 0x0f); + pr2100_write_register(ViPipe, 0x36, 0x00); + pr2100_write_register(ViPipe, 0x37, 0x0f); + pr2100_write_register(ViPipe, 0x38, 0x00); + pr2100_write_register(ViPipe, 0x39, 0x07); + pr2100_write_register(ViPipe, 0x3a, 0x80); + pr2100_write_register(ViPipe, 0x40, 0x28); + pr2100_write_register(ViPipe, 0x41, 0x07); + pr2100_write_register(ViPipe, 0x42, 0x80); + pr2100_write_register(ViPipe, 0x43, 0x04); + pr2100_write_register(ViPipe, 0x44, 0x38); + pr2100_write_register(ViPipe, 0x45, 0x0f); + pr2100_write_register(ViPipe, 0x46, 0x00); + pr2100_write_register(ViPipe, 0x47, 0x0f); + pr2100_write_register(ViPipe, 0x48, 0x00); + pr2100_write_register(ViPipe, 0x49, 0x03); + pr2100_write_register(ViPipe, 0x4a, 0xc0); + pr2100_write_register(ViPipe, 0x50, 0x38); + pr2100_write_register(ViPipe, 0x51, 0x07); + pr2100_write_register(ViPipe, 0x52, 0x80); + pr2100_write_register(ViPipe, 0x53, 0x04); + pr2100_write_register(ViPipe, 0x54, 0x38); + pr2100_write_register(ViPipe, 0x55, 0x0f); + pr2100_write_register(ViPipe, 0x56, 0x00); + pr2100_write_register(ViPipe, 0x57, 0x0f); + pr2100_write_register(ViPipe, 0x58, 0x00); + pr2100_write_register(ViPipe, 0x59, 0x00); + pr2100_write_register(ViPipe, 0x5a, 0x00); + pr2100_write_register(ViPipe, 0x60, 0x05); + pr2100_write_register(ViPipe, 0x61, 0x28); + pr2100_write_register(ViPipe, 0x62, 0x05); + pr2100_write_register(ViPipe, 0x63, 0x28); + pr2100_write_register(ViPipe, 0x64, 0x05); + pr2100_write_register(ViPipe, 0x65, 0x28); + pr2100_write_register(ViPipe, 0x66, 0x05); + pr2100_write_register(ViPipe, 0x67, 0x28); + pr2100_write_register(ViPipe, 0x68, 0xff); + pr2100_write_register(ViPipe, 0x69, 0xff); + pr2100_write_register(ViPipe, 0x6a, 0xff); + pr2100_write_register(ViPipe, 0x6b, 0xff); + pr2100_write_register(ViPipe, 0x6c, 0xff); + pr2100_write_register(ViPipe, 0x6d, 0xff); + pr2100_write_register(ViPipe, 0x6e, 0xff); + pr2100_write_register(ViPipe, 0x6f, 0xff); + pr2100_write_register(ViPipe, 0x10, 0xb3); + pr2100_write_register(ViPipe, 0xff, 0x00);//Page0 + pr2100_write_register(ViPipe, 0x80, 0x80); + pr2100_write_register(ViPipe, 0x81, 0x0e); + pr2100_write_register(ViPipe, 0x82, 0x0d); + pr2100_write_register(ViPipe, 0x84, 0xf0); + pr2100_write_register(ViPipe, 0x8a, 0x00); + pr2100_write_register(ViPipe, 0x90, 0x00); + pr2100_write_register(ViPipe, 0x91, 0x00); + pr2100_write_register(ViPipe, 0x94, 0xff); + pr2100_write_register(ViPipe, 0x95, 0xff); + pr2100_write_register(ViPipe, 0xa0, 0x33); + pr2100_write_register(ViPipe, 0xb0, 0x33); + pr2100_write_register(ViPipe, 0xff, 0x01);//Page1 + pr2100_write_register(ViPipe, 0x80, 0x00); + pr2100_write_register(ViPipe, 0x81, 0x09); + pr2100_write_register(ViPipe, 0x82, 0x00); + pr2100_write_register(ViPipe, 0x83, 0x07); + pr2100_write_register(ViPipe, 0x84, 0x00); + pr2100_write_register(ViPipe, 0x85, 0x17); + pr2100_write_register(ViPipe, 0x86, 0x03); + pr2100_write_register(ViPipe, 0x87, 0xe5); + pr2100_write_register(ViPipe, 0x88, 0x05); + pr2100_write_register(ViPipe, 0x89, 0x24); + pr2100_write_register(ViPipe, 0x8a, 0x05); + pr2100_write_register(ViPipe, 0x8b, 0x24); + pr2100_write_register(ViPipe, 0x8c, 0x08); + pr2100_write_register(ViPipe, 0x8d, 0xe8); + pr2100_write_register(ViPipe, 0x8e, 0x05); + pr2100_write_register(ViPipe, 0x8f, 0x47); + pr2100_write_register(ViPipe, 0x90, 0x02); + pr2100_write_register(ViPipe, 0x91, 0xb4); + pr2100_write_register(ViPipe, 0x92, 0x73); + pr2100_write_register(ViPipe, 0x93, 0xe8); + pr2100_write_register(ViPipe, 0x94, 0x0f); + pr2100_write_register(ViPipe, 0x95, 0x5e); + pr2100_write_register(ViPipe, 0x96, 0x03); + pr2100_write_register(ViPipe, 0x97, 0xd0); + pr2100_write_register(ViPipe, 0x98, 0x17); + pr2100_write_register(ViPipe, 0x99, 0x34); + pr2100_write_register(ViPipe, 0x9a, 0x13); + pr2100_write_register(ViPipe, 0x9b, 0x56); + pr2100_write_register(ViPipe, 0x9c, 0x0b); + pr2100_write_register(ViPipe, 0x9d, 0x9a); + pr2100_write_register(ViPipe, 0x9e, 0x09); + pr2100_write_register(ViPipe, 0x9f, 0xab); + pr2100_write_register(ViPipe, 0xa0, 0x01); + pr2100_write_register(ViPipe, 0xa1, 0x74); + pr2100_write_register(ViPipe, 0xa2, 0x01); + pr2100_write_register(ViPipe, 0xa3, 0x6b); + pr2100_write_register(ViPipe, 0xa4, 0x00); + pr2100_write_register(ViPipe, 0xa5, 0xba); + pr2100_write_register(ViPipe, 0xa6, 0x00); + pr2100_write_register(ViPipe, 0xa7, 0xa3); + pr2100_write_register(ViPipe, 0xa8, 0x01); + pr2100_write_register(ViPipe, 0xa9, 0x39); + pr2100_write_register(ViPipe, 0xaa, 0x01); + pr2100_write_register(ViPipe, 0xab, 0x39); + pr2100_write_register(ViPipe, 0xac, 0x00); + pr2100_write_register(ViPipe, 0xad, 0xc1); + pr2100_write_register(ViPipe, 0xae, 0x00); + pr2100_write_register(ViPipe, 0xaf, 0xc1); + pr2100_write_register(ViPipe, 0xb0, 0x05); + pr2100_write_register(ViPipe, 0xb1, 0xcc); + pr2100_write_register(ViPipe, 0xb2, 0x09); + pr2100_write_register(ViPipe, 0xb3, 0x6d); + pr2100_write_register(ViPipe, 0xb4, 0x00); + pr2100_write_register(ViPipe, 0xb5, 0x17); + pr2100_write_register(ViPipe, 0xb6, 0x08); + pr2100_write_register(ViPipe, 0xb7, 0xe8); + pr2100_write_register(ViPipe, 0xb8, 0xb0); + pr2100_write_register(ViPipe, 0xb9, 0xce); + pr2100_write_register(ViPipe, 0xba, 0x90); + pr2100_write_register(ViPipe, 0xbb, 0x00); + pr2100_write_register(ViPipe, 0xbc, 0x00); + pr2100_write_register(ViPipe, 0xbd, 0x04); + pr2100_write_register(ViPipe, 0xbe, 0x07); + pr2100_write_register(ViPipe, 0xbf, 0x80); + pr2100_write_register(ViPipe, 0xc0, 0x00); + pr2100_write_register(ViPipe, 0xc1, 0x00); + pr2100_write_register(ViPipe, 0xc2, 0x44); + pr2100_write_register(ViPipe, 0xc3, 0x38); + pr2100_write_register(ViPipe, 0xc4, output_pattern_ch0); + pr2100_write_register(ViPipe, 0xc9, 0x00); + pr2100_write_register(ViPipe, 0xca, 0x02); + pr2100_write_register(ViPipe, 0xcb, 0x07); + pr2100_write_register(ViPipe, 0xcc, 0x80); + pr2100_write_register(ViPipe, 0xce, 0x20); + pr2100_write_register(ViPipe, 0xcf, 0x04); + pr2100_write_register(ViPipe, 0xd0, 0x38); + pr2100_write_register(ViPipe, 0xd1, 0x00); + pr2100_write_register(ViPipe, 0xd2, 0x00); + pr2100_write_register(ViPipe, 0xd3, 0x00); + pr2100_write_register(ViPipe, 0xff, 0x00);//Page0 + pr2100_write_register(ViPipe, 0x10, 0x83); + pr2100_write_register(ViPipe, 0x12, 0x00); + pr2100_write_register(ViPipe, 0xe0, 0x05); + pr2100_write_register(ViPipe, 0xff, 0x01);//Page1 + pr2100_write_register(ViPipe, 0x10, 0x26); + pr2100_write_register(ViPipe, 0x11, 0x00); + pr2100_write_register(ViPipe, 0x12, 0x87); + pr2100_write_register(ViPipe, 0x13, 0x24); + pr2100_write_register(ViPipe, 0x14, 0x80); + pr2100_write_register(ViPipe, 0x15, 0x2a); + pr2100_write_register(ViPipe, 0x16, 0x38); + pr2100_write_register(ViPipe, 0x17, 0x00); + pr2100_write_register(ViPipe, 0x18, 0x80); + pr2100_write_register(ViPipe, 0x19, 0x48); + pr2100_write_register(ViPipe, 0x1a, 0x6c); + pr2100_write_register(ViPipe, 0x1b, 0x05); + pr2100_write_register(ViPipe, 0x1c, 0x61); + pr2100_write_register(ViPipe, 0x1d, 0x07); + pr2100_write_register(ViPipe, 0x1e, 0x7e); + pr2100_write_register(ViPipe, 0x1f, 0x80); + pr2100_write_register(ViPipe, 0x20, 0x80); + pr2100_write_register(ViPipe, 0x21, 0x80); + pr2100_write_register(ViPipe, 0x22, 0x90); + pr2100_write_register(ViPipe, 0x23, 0x80); + pr2100_write_register(ViPipe, 0x24, 0x80); + pr2100_write_register(ViPipe, 0x25, 0x80); + pr2100_write_register(ViPipe, 0x26, 0x84); + pr2100_write_register(ViPipe, 0x27, 0x82); + pr2100_write_register(ViPipe, 0x28, 0x00); + pr2100_write_register(ViPipe, 0x29, 0xff); + pr2100_write_register(ViPipe, 0x2a, 0xff); + pr2100_write_register(ViPipe, 0x2b, 0x00); + pr2100_write_register(ViPipe, 0x2c, 0x00); + pr2100_write_register(ViPipe, 0x2e, 0x00); + pr2100_write_register(ViPipe, 0x33, 0x14); + pr2100_write_register(ViPipe, 0x34, 0x14); + pr2100_write_register(ViPipe, 0x35, 0x80); + pr2100_write_register(ViPipe, 0x36, 0x80); + pr2100_write_register(ViPipe, 0x37, 0xad); + pr2100_write_register(ViPipe, 0x38, 0x4b); + pr2100_write_register(ViPipe, 0x39, 0x08); + pr2100_write_register(ViPipe, 0x3a, 0x21); + pr2100_write_register(ViPipe, 0x3b, 0x02); + pr2100_write_register(ViPipe, 0x3d, 0x23); + pr2100_write_register(ViPipe, 0x3e, 0x05); + pr2100_write_register(ViPipe, 0x3f, 0xc8); + pr2100_write_register(ViPipe, 0x40, 0x05); + pr2100_write_register(ViPipe, 0x41, 0x55); + pr2100_write_register(ViPipe, 0x42, 0x01); + pr2100_write_register(ViPipe, 0x43, 0x38); + pr2100_write_register(ViPipe, 0x44, 0x6a); + pr2100_write_register(ViPipe, 0x45, 0x00); + pr2100_write_register(ViPipe, 0x46, 0x14); + pr2100_write_register(ViPipe, 0x47, 0xb0); + pr2100_write_register(ViPipe, 0x48, 0xdf); + pr2100_write_register(ViPipe, 0x49, 0x00); + pr2100_write_register(ViPipe, 0x4a, 0x7b); + pr2100_write_register(ViPipe, 0x4b, 0x60); + pr2100_write_register(ViPipe, 0x4c, 0x00); + pr2100_write_register(ViPipe, 0x4d, 0x26); + pr2100_write_register(ViPipe, 0x4e, 0x00); + pr2100_write_register(ViPipe, 0x50, 0x21); + pr2100_write_register(ViPipe, 0x54, 0x0e); + pr2100_write_register(ViPipe, 0x54, 0x0f); +} + +static void pr2100_set_1080p_2ch(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "2CH ViPipe=%d\n", ViPipe); + + pr2100_write_register(ViPipe, 0xFF, 0x00); + pr2100_write_register(ViPipe, 0x10, 0x83); //MAN_IFMT0 + pr2100_write_register(ViPipe, 0x11, 0x0f); //MAN_EQ_DC_GN0 + pr2100_write_register(ViPipe, 0x12, 0x00); //MAN_EQ_AC_GN0 + pr2100_write_register(ViPipe, 0x13, 0x00); //VADC_EQ_BAND0 + pr2100_write_register(ViPipe, 0x14, 0x21); //VADC_CTRL0_0 + pr2100_write_register(ViPipe, 0x15, 0x44); //VADC_CTRL1_0 + pr2100_write_register(ViPipe, 0x16, 0x0d); //VADC_CTRL2_0 + pr2100_write_register(ViPipe, 0x30, 0x83); //MAN_IFMT1 + pr2100_write_register(ViPipe, 0x31, 0x0f); //MAN_EQ_DC_GN1 + pr2100_write_register(ViPipe, 0x32, 0x00); //MAN_EQ_AC_GN1 + pr2100_write_register(ViPipe, 0x33, 0x00); //VADC_EQ_BAND1 + pr2100_write_register(ViPipe, 0x34, 0x21); //VADC_CTRL0_1 + pr2100_write_register(ViPipe, 0x35, 0x44); //VADC_CTRL1_1 + pr2100_write_register(ViPipe, 0x36, 0x0d); //VADC_CTRL2_1 + pr2100_write_register(ViPipe, 0x80, 0x80); //IRQ_CTRL + pr2100_write_register(ViPipe, 0x81, 0x0e); //IRQ_SYNC_PERIOD + pr2100_write_register(ViPipe, 0x82, 0x0d); //WAKE0_PERIOD + pr2100_write_register(ViPipe, 0x84, 0xf0); //IRQ_NOVID_MD + pr2100_write_register(ViPipe, 0x8a, 0x00); //WAKE1_PERIOD + pr2100_write_register(ViPipe, 0x90, 0x00); //IRQENA_WAKE + pr2100_write_register(ViPipe, 0x91, 0x00); //IRQENA_GPIO + pr2100_write_register(ViPipe, 0x94, 0xff); //IRQCLR_WAKE + pr2100_write_register(ViPipe, 0x95, 0xff); //IRQCLR_GPIO + pr2100_write_register(ViPipe, 0xa0, 0x33); //IRQENA_VFD0 + pr2100_write_register(ViPipe, 0xb0, 0x33); //IRQENA_VFD1 + pr2100_write_register(ViPipe, 0xc0, 0x21); //MPP_CTRL0 + pr2100_write_register(ViPipe, 0xc1, 0x21); //MPP_CTRL1 + pr2100_write_register(ViPipe, 0xc2, 0x21); //MPP_CTRL2 + pr2100_write_register(ViPipe, 0xc3, 0x21); //MPP_CTRL3 + pr2100_write_register(ViPipe, 0xc4, 0x21); //MPP_CTRL4 + pr2100_write_register(ViPipe, 0xc5, 0x21); //MPP_CTRL5 + pr2100_write_register(ViPipe, 0xc6, 0x21); //MPP_CTRL6 + pr2100_write_register(ViPipe, 0xc7, 0x21); //MPP_CTRL7 + pr2100_write_register(ViPipe, 0xc8, 0x21); //MPP_CTRL8 + pr2100_write_register(ViPipe, 0xc9, 0x01); //MPP_CTRL9 + pr2100_write_register(ViPipe, 0xca, 0x01); //MPP_CTRLA + pr2100_write_register(ViPipe, 0xcb, 0x01); //MPP_CTRLB + pr2100_write_register(ViPipe, 0xd0, 0x06); //PLL0_CON0 + pr2100_write_register(ViPipe, 0xd1, 0x23); //PLL0_CON1 + pr2100_write_register(ViPipe, 0xd2, 0x21); //PLL0_CON2 + pr2100_write_register(ViPipe, 0xd3, 0x44); //PLL0_CON3 + pr2100_write_register(ViPipe, 0xd4, 0x06); //PLL1_CON0 + pr2100_write_register(ViPipe, 0xd5, 0x23); //PLL1_CON1 + pr2100_write_register(ViPipe, 0xd6, 0x21); //PLL1_CON2 + pr2100_write_register(ViPipe, 0xd7, 0x44); //PLL1_CON3 + pr2100_write_register(ViPipe, 0xd8, 0x06); //PLL2_CON0 + pr2100_write_register(ViPipe, 0xd9, 0x22); //PLL2_CON1 + pr2100_write_register(ViPipe, 0xda, 0x2c); //PLL2_CON2 + pr2100_write_register(ViPipe, 0xe0, 0x05); //LATCH_EN_CON0 + pr2100_write_register(ViPipe, 0xe1, 0x05); //LATCH_EN_CON1 + pr2100_write_register(ViPipe, 0xe2, 0x00); //OUT_FMT + pr2100_write_register(ViPipe, 0xe3, 0xc4); //CHID_NUM, Y-Cb-Y-Cr + pr2100_write_register(ViPipe, 0xe4, 0x20); //CH_SEL0 + pr2100_write_register(ViPipe, 0xe5, 0x64); //CH_SEL1 + pr2100_write_register(ViPipe, 0xe6, 0x20); //CH_SEL2 + pr2100_write_register(ViPipe, 0xe7, 0x64); //CH_SEL3 + pr2100_write_register(ViPipe, 0xe8, 0x00); //VDCKP_PHASE + pr2100_write_register(ViPipe, 0xe9, 0x00); //VDCKN_PHASE + pr2100_write_register(ViPipe, 0xea, 0x00); //CLK_PWDN + pr2100_write_register(ViPipe, 0xeb, 0x01); //MIPI_DATA_EN + pr2100_write_register(ViPipe, 0xf0, 0x03); //PAR_OE_M + pr2100_write_register(ViPipe, 0xf1, 0xff); //PAR_OE_L + pr2100_write_register(ViPipe, 0xf3, 0x06); //PAD_MPP_CTL + pr2100_write_register(ViPipe, 0xf4, 0x66); //PAD_VD_CTL + + pr2100_write_register(ViPipe, 0xFF, 0x01); + pr2100_write_register(ViPipe, 0x00, 0xe4); //VID_CON0 + pr2100_write_register(ViPipe, 0x01, 0x61); //GAINFIT0 + pr2100_write_register(ViPipe, 0x02, 0x00); //PEDFIT0 + pr2100_write_register(ViPipe, 0x03, 0x56); //CLAMP_CON0 + pr2100_write_register(ViPipe, 0x04, 0x0c); //HPLL_CON0_0 + pr2100_write_register(ViPipe, 0x05, 0x88); //HPLL_CON1_0 + pr2100_write_register(ViPipe, 0x06, 0x04); //HPLL_CON2_0 + pr2100_write_register(ViPipe, 0x07, 0xb2); //HPLL_CON3_0 + pr2100_write_register(ViPipe, 0x08, 0x44); //HPLL_CON4_0 + pr2100_write_register(ViPipe, 0x09, 0x34); //HPLL_CON5_0 + pr2100_write_register(ViPipe, 0x0a, 0x02); //HPLL_CON6_0 + pr2100_write_register(ViPipe, 0x0b, 0x14); //STD_POS0_0 + pr2100_write_register(ViPipe, 0x0c, 0x04); //STD_POS1_0 + pr2100_write_register(ViPipe, 0x0d, 0x08); //STD_POS2_0 + pr2100_write_register(ViPipe, 0x0e, 0x5e); //STD_SLICE0_0 + pr2100_write_register(ViPipe, 0x0f, 0x5e); //STD_SLICE1_0 + pr2100_write_register(ViPipe, 0x10, 0x26); //STD_SLICE2_0 + pr2100_write_register(ViPipe, 0x11, 0x00); //HDELAY_MSB0 + pr2100_write_register(ViPipe, 0x12, 0x87); //HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0x13, 0x24); //HDELAY_LSB0 + pr2100_write_register(ViPipe, 0x14, 0x80); //HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x15, 0x2a); //VDELAY0 + pr2100_write_register(ViPipe, 0x16, 0x38); //VACTIVE0 + pr2100_write_register(ViPipe, 0x17, 0x00); //CBG_DELAY_MSB0 + pr2100_write_register(ViPipe, 0x18, 0x80); //CBG_ACTIVE_MSB0 + pr2100_write_register(ViPipe, 0x19, 0x48); //CBG_DELAY_LSB0 + pr2100_write_register(ViPipe, 0x1a, 0x6c); //CBG_ACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x1b, 0x05); //VSMASK_INV_STRT0 + pr2100_write_register(ViPipe, 0x1c, 0x61); //VSMASK_INV_END0 + pr2100_write_register(ViPipe, 0x1d, 0x07); //CBP_DELAY_MSB0 + pr2100_write_register(ViPipe, 0x1e, 0x7e); //CBP_DELAY_LSB0 + pr2100_write_register(ViPipe, 0x1f, 0x80); //HSCL_ACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x20, 0x80); //CONT0 + pr2100_write_register(ViPipe, 0x21, 0x80); //BRGT0 + pr2100_write_register(ViPipe, 0x22, 0x90); //SAT0 + pr2100_write_register(ViPipe, 0x23, 0x80); //HUE0 + pr2100_write_register(ViPipe, 0x24, 0x80); //CB_GAIN0 + pr2100_write_register(ViPipe, 0x25, 0x80); //CR_GAIN0 + pr2100_write_register(ViPipe, 0x26, 0x84); //CB_OFF0 + pr2100_write_register(ViPipe, 0x27, 0x82); //CR_OFF0 + pr2100_write_register(ViPipe, 0x28, 0x00); //Y_OUT_GAIN0 + pr2100_write_register(ViPipe, 0x29, 0xff); //DOWN_HSCL_MSB0 + pr2100_write_register(ViPipe, 0x2a, 0xff); //DOWN_HSCL_LSB0 + pr2100_write_register(ViPipe, 0x2b, 0x00); //MAN_HSCL_ADD0_0 + pr2100_write_register(ViPipe, 0x2c, 0x00); //MAN_HSCL_ADD1_0 + pr2100_write_register(ViPipe, 0x2d, 0x00); //MAN_HSCL_ADD2_0 + pr2100_write_register(ViPipe, 0x2e, 0x00); //MAN_OUTFMT_ADD0_0 + pr2100_write_register(ViPipe, 0x2f, 0x00); //MAN_OUTFMT_ADD1_0 + pr2100_write_register(ViPipe, 0x30, 0x00); //MAN_OUTFMT_ADD2_0 + pr2100_write_register(ViPipe, 0x31, 0x00); //MAN_COMB_MD0 + pr2100_write_register(ViPipe, 0x32, 0xc0); //COMB_CRL_MD0 + pr2100_write_register(ViPipe, 0x33, 0x14); //COMB_CVBS_CRL0_0 + pr2100_write_register(ViPipe, 0x34, 0x14); //COMB_CVBS_CRL1_0 + pr2100_write_register(ViPipe, 0x35, 0x80); //COMB_CVBS_CRL2_0 + pr2100_write_register(ViPipe, 0x36, 0x80); //COMB_CVBS_CRL3_0 + pr2100_write_register(ViPipe, 0x37, 0xad); //HD_Y_NOTCH_MD0 + pr2100_write_register(ViPipe, 0x38, 0x4b); //HD_COMB_FLT_MD0 + pr2100_write_register(ViPipe, 0x39, 0x08); //Y_DYN_PEAK_GN0 + pr2100_write_register(ViPipe, 0x3a, 0x21); //HD_Y_LPF_MD0 + pr2100_write_register(ViPipe, 0x3b, 0x02); //Y_HPF_CORE_MIN0 + pr2100_write_register(ViPipe, 0x3c, 0x01); //Y_HPF_CORE_STEP0 + pr2100_write_register(ViPipe, 0x3d, 0x23); //CORE_CON0 + pr2100_write_register(ViPipe, 0x3e, 0x05); //MAN_CLPF_MD0 + pr2100_write_register(ViPipe, 0x3f, 0xc8); //HD_CTI_CON0 + pr2100_write_register(ViPipe, 0x40, 0x05); //C_LOOP_CON0_0 + pr2100_write_register(ViPipe, 0x41, 0x55); //C_LOOP_CON1_0 + pr2100_write_register(ViPipe, 0x42, 0x01); //C_LOOP_CON2_0 + pr2100_write_register(ViPipe, 0x43, 0x38); //C_LOOP_CON3_0 + pr2100_write_register(ViPipe, 0x44, 0x6a); //C_HUE_CVI0_0 + pr2100_write_register(ViPipe, 0x45, 0x00); //C_HUE_CVI1_0 + pr2100_write_register(ViPipe, 0x46, 0x14); //C_PHASE_REF0_0 + pr2100_write_register(ViPipe, 0x47, 0xb0); //C_PHASE_REF1_0 + pr2100_write_register(ViPipe, 0x48, 0xdf); //C_PHASE_REF2_0 + pr2100_write_register(ViPipe, 0x49, 0x00); //G_GAIN_REF0_0 + pr2100_write_register(ViPipe, 0x4a, 0x7b); //G_GAIN_REF1_0 + pr2100_write_register(ViPipe, 0x4b, 0x60); //MAN_C_GAIN_VAL0_0 + pr2100_write_register(ViPipe, 0x4c, 0x00); //MAN_C_GAIN_VAL1_0 + pr2100_write_register(ViPipe, 0x4d, 0x26); //YC_DELAY0 + pr2100_write_register(ViPipe, 0x4e, 0x00); //HD_HALF_MD0 + pr2100_write_register(ViPipe, 0x4f, 0x2c); //OUTFMT_CON0 + pr2100_write_register(ViPipe, 0x50, 0x21); //TST_EQ_POS0_0 + pr2100_write_register(ViPipe, 0x51, 0x28); //TST_EQ_POS1_0 + pr2100_write_register(ViPipe, 0x52, 0x40); //TST_EQ_POS2_0 + pr2100_write_register(ViPipe, 0x53, 0x0c); //TST_VID_DEC0 + pr2100_write_register(ViPipe, 0x54, 0x0f); //TST_VID_RST0 + pr2100_write_register(ViPipe, 0x55, 0x8d); //PTZ_SLICE_LVL0 + pr2100_write_register(ViPipe, 0x70, 0x06); //COMB_VCRL_VTH1_0 + pr2100_write_register(ViPipe, 0x71, 0x08); //COMB_VCRL_VTH2_0 + pr2100_write_register(ViPipe, 0x72, 0x0a); //COMB_VCRL_VTH3_0 + pr2100_write_register(ViPipe, 0x73, 0x0c); //COMB_VCRL_VTH4_0 + pr2100_write_register(ViPipe, 0x74, 0x0e); //COMB_VCRL_VTH5_0 + pr2100_write_register(ViPipe, 0x75, 0x10); //COMB_VCRL_VTH6_0 + pr2100_write_register(ViPipe, 0x76, 0x12); //COMB_VCRL_VTH7_0 + pr2100_write_register(ViPipe, 0x77, 0x14); //COMB_VCRL_VTH8_0 + pr2100_write_register(ViPipe, 0x78, 0x06); //COMB_VMIX_VTH1_0 + pr2100_write_register(ViPipe, 0x79, 0x08); //COMB_VMIX_VTH2_0 + pr2100_write_register(ViPipe, 0x7a, 0x0a); //COMB_VMIX_VTH3_0 + pr2100_write_register(ViPipe, 0x7b, 0x0c); //COMB_VMIX_VTH4_0 + pr2100_write_register(ViPipe, 0x7c, 0x0e); //COMB_VMIX_VTH5_0 + pr2100_write_register(ViPipe, 0x7d, 0x10); //COMB_VMIX_VTH6_0 + pr2100_write_register(ViPipe, 0x7e, 0x12); //COMB_VMIX_VTH7_0 + pr2100_write_register(ViPipe, 0x7f, 0x14); //COMB_VMIX_VTH8_0 + pr2100_write_register(ViPipe, 0x80, 0x00); //STD_VPOS_PVI_960MSB0 + pr2100_write_register(ViPipe, 0x81, 0x09); //STD_VPOS_PVI_960LSB0 + pr2100_write_register(ViPipe, 0x82, 0x00); //STD_VPOS_CVI_960MSB0 + pr2100_write_register(ViPipe, 0x83, 0x07); //STD_VPOS_CVI_960LSB0 + pr2100_write_register(ViPipe, 0x84, 0x00); //STD_VPOS_AHD_960MSB0 + pr2100_write_register(ViPipe, 0x85, 0x17); //STD_VPOS_AHD_960LSB0 + pr2100_write_register(ViPipe, 0x86, 0x03); //STD_VPOS_TVI_960MSB0 + pr2100_write_register(ViPipe, 0x87, 0xe5); //STD_VPOS_TVI_960LSB0 + pr2100_write_register(ViPipe, 0x88, 0x05); //STD_HPOS_PVI_960MSB0 + pr2100_write_register(ViPipe, 0x89, 0x24); //STD_HPOS_PVI_960LSB0 + pr2100_write_register(ViPipe, 0x8a, 0x05); //STD_HPOS_CVI_960MSB0 + pr2100_write_register(ViPipe, 0x8b, 0x24); //STD_HPOS_CVI_960LSB0 + pr2100_write_register(ViPipe, 0x8c, 0x08); //STD_HPOS_AHD_960MSB0 + pr2100_write_register(ViPipe, 0x8d, 0xe8); //STD_HPOS_AHD_960LSB0 + pr2100_write_register(ViPipe, 0x8e, 0x05); //STD_HPOS_TVI_960MSB0 + pr2100_write_register(ViPipe, 0x8f, 0x47); //STD_HPOS_TVI_960LSB0 + pr2100_write_register(ViPipe, 0x90, 0x02); //VSYNC_ACCUM_960MSB0 + pr2100_write_register(ViPipe, 0x91, 0xb4); //VSYNC_ACCUM_960LSB0 + pr2100_write_register(ViPipe, 0x92, 0x73); //VLINE_MAX_960_MSB0 + pr2100_write_register(ViPipe, 0x93, 0xe8); //VLINE_MAX_960_LSB0 + pr2100_write_register(ViPipe, 0x94, 0x0f); //SLICE_VSYNC0 + pr2100_write_register(ViPipe, 0x95, 0x5e); //STD_SLICE_AHD0 + pr2100_write_register(ViPipe, 0x96, 0x03); //HACT_SIZE_960_MSB0 + pr2100_write_register(ViPipe, 0x97, 0xd0); //HACT_SIZE_960_LSB0 + pr2100_write_register(ViPipe, 0x98, 0x17); //HPERIOD_960P25MSB0 + pr2100_write_register(ViPipe, 0x99, 0x34); //HPERIOD_960P25LSB0 + pr2100_write_register(ViPipe, 0x9a, 0x13); //HPERIOD_960P30MSB0 + pr2100_write_register(ViPipe, 0x9b, 0x56); //HPERIOD_960P30LSB0 + pr2100_write_register(ViPipe, 0x9c, 0x0b); //HPERIOD_960P50MSB0 + pr2100_write_register(ViPipe, 0x9d, 0x9a); //HPERIOD_960P50LSB0 + pr2100_write_register(ViPipe, 0x9e, 0x09); //HPERIOD_960P60MSB0 + pr2100_write_register(ViPipe, 0x9f, 0xab); //HPERIOD_960P60LSB0 + pr2100_write_register(ViPipe, 0xa0, 0x01); //VALY_STRT_960P25MSB0 + pr2100_write_register(ViPipe, 0xa1, 0x74); //VALY_STRT_960P25LSB0 + pr2100_write_register(ViPipe, 0xa2, 0x01); //VALY_STRT_960P30MSB0 + pr2100_write_register(ViPipe, 0xa3, 0x6b); //VALY_STRT_960P30LSB0 + pr2100_write_register(ViPipe, 0xa4, 0x00); //VALY_STRT_960P50MSB0 + pr2100_write_register(ViPipe, 0xa5, 0xba); //VALY_STRT_960P50LSB0 + pr2100_write_register(ViPipe, 0xa6, 0x00); //VALY_STRT_960P60MSB0 + pr2100_write_register(ViPipe, 0xa7, 0xa3); //VALY_STRT_960P60LSB0 + pr2100_write_register(ViPipe, 0xa8, 0x01); //PED_STRT_960P25MSB0 + pr2100_write_register(ViPipe, 0xa9, 0x39); //PED_STRT_960P25LSB0 + pr2100_write_register(ViPipe, 0xaa, 0x01); //PED_STRT_960P30MSB0 + pr2100_write_register(ViPipe, 0xab, 0x39); //PED_STRT_960P30LSB0 + pr2100_write_register(ViPipe, 0xac, 0x00); //PED_STRT_960P50MSB0 + pr2100_write_register(ViPipe, 0xad, 0xc1); //PED_STRT_960P50LSB0 + pr2100_write_register(ViPipe, 0xae, 0x00); //PED_STRT_960P60MSB0 + pr2100_write_register(ViPipe, 0xaf, 0xc1); //PED_STRT_960P60LSB0 + pr2100_write_register(ViPipe, 0xb0, 0x05); //COMB_MEM_960PMSB0 + pr2100_write_register(ViPipe, 0xb1, 0xcc); //COMB_MEM_960PLSB0 + pr2100_write_register(ViPipe, 0xb2, 0x09); //C_JIT_GAIN_960PMSB0 + pr2100_write_register(ViPipe, 0xb3, 0x6d); //C_JIT_GAIN_960PLSB0 + pr2100_write_register(ViPipe, 0xb4, 0x00); //STD_VPOS_AHD_MSB0 + pr2100_write_register(ViPipe, 0xb5, 0x17); //STD_VPOS_AHD_LSB0 + pr2100_write_register(ViPipe, 0xb6, 0x08); //STD_HPOS_AHD_MSB0 + pr2100_write_register(ViPipe, 0xb7, 0xe8); //STD_HPOS_AHD_LSB0 + pr2100_write_register(ViPipe, 0xb8, 0xb0); //STD_TVI_OFFSET_25F0 + pr2100_write_register(ViPipe, 0xb9, 0xce); //STD_TVI_OFFSET_30F0 + pr2100_write_register(ViPipe, 0xba, 0x90); //STD_TVI_OFFSET_960P0 + pr2100_write_register(ViPipe, 0xbb, 0x00); //EXT_SYNC_CON0 + pr2100_write_register(ViPipe, 0xbc, 0x00); //VOSYNC_HDELAY_MSB0 + pr2100_write_register(ViPipe, 0xbd, 0x04); //VOSYNC_HDELAY_LSB0 + pr2100_write_register(ViPipe, 0xbe, 0x07); //VOSYNC_HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xbf, 0x80); //VOSYNC_HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xc0, 0x00); //VOSYNC_VDELAY_MSB0 + pr2100_write_register(ViPipe, 0xc1, 0x00); //VOSYNC_VDELAY_LSB0 + #if PR2100_TEST_PATTERN + pr2100_write_register(ViPipe, 0xc2, 0x44); + pr2100_write_register(ViPipe, 0xc3, 0x38); + #else + pr2100_write_register(ViPipe, 0xc2, 0x04); //VOSYNC_VACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xc3, 0x39); //VOSYNC_VACTIVE_LSB0 + #endif + pr2100_write_register(ViPipe, 0xc4, output_pattern_ch0); + pr2100_write_register(ViPipe, 0xc9, 0x00); //VISYNC_HDELAY_MSB0 + pr2100_write_register(ViPipe, 0xca, 0x02); //VISYNC_HDELAY_LSB0 + pr2100_write_register(ViPipe, 0xcb, 0x07); //VISYNC_HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xcc, 0x80); //VISYNC_HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xcd, 0x08); //VISYNC_VDELAY_MSB0 + pr2100_write_register(ViPipe, 0xce, 0x20); //VISYNC_VDELAY_LSB0 + pr2100_write_register(ViPipe, 0xcf, 0x04); //VISYNC_VACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xd0, 0x38); //VISYNC_VACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xd1, 0x00); //MIPI_DATA_FLD_CON_0 + pr2100_write_register(ViPipe, 0xd2, 0x00); //MIPI_DATA_ODD_VAL_0 + pr2100_write_register(ViPipe, 0xd3, 0x00); //MIPI_DATA_EVEN_VAL_0 + + pr2100_write_register(ViPipe, 0xFF, 0x02); + pr2100_write_register(ViPipe, 0x00, 0xe4); //VID_CON1 + pr2100_write_register(ViPipe, 0x01, 0x61); //GAINFIT1 + pr2100_write_register(ViPipe, 0x02, 0x00); //PEDFIT1 + pr2100_write_register(ViPipe, 0x03, 0x56); //CLAMP_CON1 + pr2100_write_register(ViPipe, 0x04, 0x0c); //HPLL_CON0_1 + pr2100_write_register(ViPipe, 0x05, 0x88); //HPLL_CON1_1 + pr2100_write_register(ViPipe, 0x06, 0x04); //HPLL_CON2_1 + pr2100_write_register(ViPipe, 0x07, 0xb2); //HPLL_CON3_1 + pr2100_write_register(ViPipe, 0x08, 0x44); //HPLL_CON4_1 + pr2100_write_register(ViPipe, 0x09, 0x34); //HPLL_CON5_1 + pr2100_write_register(ViPipe, 0x0a, 0x02); //HPLL_CON6_1 + pr2100_write_register(ViPipe, 0x0b, 0x14); //STD_POS0_1 + pr2100_write_register(ViPipe, 0x0c, 0x04); //STD_POS1_1 + pr2100_write_register(ViPipe, 0x0d, 0x08); //STD_POS2_1 + pr2100_write_register(ViPipe, 0x0e, 0x5e); //STD_SLICE0_1 + pr2100_write_register(ViPipe, 0x0f, 0x5e); //STD_SLICE1_1 + pr2100_write_register(ViPipe, 0x10, 0x26); //STD_SLICE2_1 + pr2100_write_register(ViPipe, 0x11, 0x00); //HDELAY_MSB1 + pr2100_write_register(ViPipe, 0x12, 0x87); //HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0x13, 0x24); //HDELAY_LSB1 + pr2100_write_register(ViPipe, 0x14, 0x80); //HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x15, 0x2a); //VDELAY1 + pr2100_write_register(ViPipe, 0x16, 0x38); //VACTIVE1 + pr2100_write_register(ViPipe, 0x17, 0x00); //CBG_DELAY_MSB1 + pr2100_write_register(ViPipe, 0x18, 0x80); //CBG_ACTIVE_MSB1 + pr2100_write_register(ViPipe, 0x19, 0x48); //CBG_DELAY_LSB1 + pr2100_write_register(ViPipe, 0x1a, 0x6c); //CBG_ACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x1b, 0x05); //VSMASK_INV_STRT1 + pr2100_write_register(ViPipe, 0x1c, 0x61); //VSMASK_INV_END1 + pr2100_write_register(ViPipe, 0x1d, 0x07); //CBP_DELAY_MSB1 + pr2100_write_register(ViPipe, 0x1e, 0x7e); //CBP_DELAY_LSB1 + pr2100_write_register(ViPipe, 0x1f, 0x80); //HSCL_ACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x20, 0x80); //CONT1 + pr2100_write_register(ViPipe, 0x21, 0x80); //BRGT1 + pr2100_write_register(ViPipe, 0x22, 0x90); //SAT1 + pr2100_write_register(ViPipe, 0x23, 0x80); //HUE1 + pr2100_write_register(ViPipe, 0x24, 0x80); //CB_GAIN1 + pr2100_write_register(ViPipe, 0x25, 0x80); //CR_GAIN1 + pr2100_write_register(ViPipe, 0x26, 0x84); //CB_OFF1 + pr2100_write_register(ViPipe, 0x27, 0x82); //CR_OFF1 + pr2100_write_register(ViPipe, 0x28, 0x00); //Y_OUT_GAIN1 + pr2100_write_register(ViPipe, 0x29, 0xff); //DOWN_HSCL_MSB1 + pr2100_write_register(ViPipe, 0x2a, 0xff); //DOWN_HSCL_LSB1 + pr2100_write_register(ViPipe, 0x2b, 0x00); //MAN_HSCL_ADD0_1 + pr2100_write_register(ViPipe, 0x2c, 0x00); //MAN_HSCL_ADD1_1 + pr2100_write_register(ViPipe, 0x2d, 0x00); //MAN_HSCL_ADD2_1 + pr2100_write_register(ViPipe, 0x2e, 0x00); //MAN_OUTFMT_ADD0_1 + pr2100_write_register(ViPipe, 0x2f, 0x00); //MAN_OUTFMT_ADD1_1 + pr2100_write_register(ViPipe, 0x30, 0x00); //MAN_OUTFMT_ADD2_1 + pr2100_write_register(ViPipe, 0x31, 0x00); //MAN_COMB_MD1 + pr2100_write_register(ViPipe, 0x32, 0xc0); //COMB_CRL_MD1 + pr2100_write_register(ViPipe, 0x33, 0x14); //COMB_CVBS_CRL0_1 + pr2100_write_register(ViPipe, 0x34, 0x14); //COMB_CVBS_CRL1_1 + pr2100_write_register(ViPipe, 0x35, 0x80); //COMB_CVBS_CRL2_1 + pr2100_write_register(ViPipe, 0x36, 0x80); //COMB_CVBS_CRL3_1 + pr2100_write_register(ViPipe, 0x37, 0xad); //HD_Y_NOTCH_MD1 + pr2100_write_register(ViPipe, 0x38, 0x4b); //HD_COMB_FLT_MD1 + pr2100_write_register(ViPipe, 0x39, 0x08); //Y_DYN_PEAK_GN1 + pr2100_write_register(ViPipe, 0x3a, 0x21); //HD_Y_LPF_MD1 + pr2100_write_register(ViPipe, 0x3b, 0x02); //Y_HPF_CORE_MIN1 + pr2100_write_register(ViPipe, 0x3c, 0x01); //Y_HPF_CORE_STEP1 + pr2100_write_register(ViPipe, 0x3d, 0x23); //CORE_CON1 + pr2100_write_register(ViPipe, 0x3e, 0x05); //MAN_CLPF_MD1 + pr2100_write_register(ViPipe, 0x3f, 0xc8); //HD_CTI_CON1 + pr2100_write_register(ViPipe, 0x40, 0x05); //C_LOOP_CON0_1 + pr2100_write_register(ViPipe, 0x41, 0x55); //C_LOOP_CON1_1 + pr2100_write_register(ViPipe, 0x42, 0x01); //C_LOOP_CON2_1 + pr2100_write_register(ViPipe, 0x43, 0x38); //C_LOOP_CON3_1 + pr2100_write_register(ViPipe, 0x44, 0x6a); //C_HUE_CVI0_1 + pr2100_write_register(ViPipe, 0x45, 0x00); //C_HUE_CVI1_1 + pr2100_write_register(ViPipe, 0x46, 0x14); //C_PHASE_REF0_1 + pr2100_write_register(ViPipe, 0x47, 0xb0); //C_PHASE_REF1_1 + pr2100_write_register(ViPipe, 0x48, 0xdf); //C_PHASE_REF2_1 + pr2100_write_register(ViPipe, 0x49, 0x00); //G_GAIN_REF0_1 + pr2100_write_register(ViPipe, 0x4a, 0x7b); //G_GAIN_REF1_1 + pr2100_write_register(ViPipe, 0x4b, 0x60); //MAN_C_GAIN_VAL0_1 + pr2100_write_register(ViPipe, 0x4c, 0x00); //MAN_C_GAIN_VAL1_1 + pr2100_write_register(ViPipe, 0x4d, 0x26); //YC_DELAY1 + pr2100_write_register(ViPipe, 0x4e, 0x00); //HD_HALF_MD1 + pr2100_write_register(ViPipe, 0x4f, 0x2c); //OUTFMT_CON1 + pr2100_write_register(ViPipe, 0x50, 0x21); //TST_EQ_POS0_1 + pr2100_write_register(ViPipe, 0x51, 0x28); //TST_EQ_POS1_1 + pr2100_write_register(ViPipe, 0x52, 0x40); //TST_EQ_POS2_1 + pr2100_write_register(ViPipe, 0x53, 0x0c); //TST_VID_DEC1 + pr2100_write_register(ViPipe, 0x54, 0x0f); //TST_VID_RST1 + pr2100_write_register(ViPipe, 0x55, 0x8d); //PTZ_SLICE_LVL1 + pr2100_write_register(ViPipe, 0x70, 0x06); //COMB_VCRL_VTH1_1 + pr2100_write_register(ViPipe, 0x71, 0x08); //COMB_VCRL_VTH2_1 + pr2100_write_register(ViPipe, 0x72, 0x0a); //COMB_VCRL_VTH3_1 + pr2100_write_register(ViPipe, 0x73, 0x0c); //COMB_VCRL_VTH4_1 + pr2100_write_register(ViPipe, 0x74, 0x0e); //COMB_VCRL_VTH5_1 + pr2100_write_register(ViPipe, 0x75, 0x10); //COMB_VCRL_VTH6_1 + pr2100_write_register(ViPipe, 0x76, 0x12); //COMB_VCRL_VTH7_1 + pr2100_write_register(ViPipe, 0x77, 0x14); //COMB_VCRL_VTH8_1 + pr2100_write_register(ViPipe, 0x78, 0x06); //COMB_VMIX_VTH1_1 + pr2100_write_register(ViPipe, 0x79, 0x08); //COMB_VMIX_VTH2_1 + pr2100_write_register(ViPipe, 0x7a, 0x0a); //COMB_VMIX_VTH3_1 + pr2100_write_register(ViPipe, 0x7b, 0x0c); //COMB_VMIX_VTH4_1 + pr2100_write_register(ViPipe, 0x7c, 0x0e); //COMB_VMIX_VTH5_1 + pr2100_write_register(ViPipe, 0x7d, 0x10); //COMB_VMIX_VTH6_1 + pr2100_write_register(ViPipe, 0x7e, 0x12); //COMB_VMIX_VTH7_1 + pr2100_write_register(ViPipe, 0x7f, 0x14); //COMB_VMIX_VTH8_1 + pr2100_write_register(ViPipe, 0x80, 0x00); //STD_VPOS_PVI_960MSB1 + pr2100_write_register(ViPipe, 0x81, 0x09); //STD_VPOS_PVI_960LSB1 + pr2100_write_register(ViPipe, 0x82, 0x00); //STD_VPOS_CVI_960MSB1 + pr2100_write_register(ViPipe, 0x83, 0x07); //STD_VPOS_CVI_960LSB1 + pr2100_write_register(ViPipe, 0x84, 0x00); //STD_VPOS_AHD_960MSB1 + pr2100_write_register(ViPipe, 0x85, 0x17); //STD_VPOS_AHD_960LSB1 + pr2100_write_register(ViPipe, 0x86, 0x03); //STD_VPOS_TVI_960MSB1 + pr2100_write_register(ViPipe, 0x87, 0xe5); //STD_VPOS_TVI_960LSB1 + pr2100_write_register(ViPipe, 0x88, 0x05); //STD_HPOS_PVI_960MSB1 + pr2100_write_register(ViPipe, 0x89, 0x24); //STD_HPOS_PVI_960LSB1 + pr2100_write_register(ViPipe, 0x8a, 0x05); //STD_HPOS_CVI_960MSB1 + pr2100_write_register(ViPipe, 0x8b, 0x24); //STD_HPOS_CVI_960LSB1 + pr2100_write_register(ViPipe, 0x8c, 0x08); //STD_HPOS_AHD_960MSB1 + pr2100_write_register(ViPipe, 0x8d, 0xe8); //STD_HPOS_AHD_960LSB1 + pr2100_write_register(ViPipe, 0x8e, 0x05); //STD_HPOS_TVI_960MSB1 + pr2100_write_register(ViPipe, 0x8f, 0x47); //STD_HPOS_TVI_960LSB1 + pr2100_write_register(ViPipe, 0x90, 0x02); //VSYNC_ACCUM_960MSB1 + pr2100_write_register(ViPipe, 0x91, 0xb4); //VSYNC_ACCUM_960LSB1 + pr2100_write_register(ViPipe, 0x92, 0x73); //VLINE_MAX_960_MSB1 + pr2100_write_register(ViPipe, 0x93, 0xe8); //VLINE_MAX_960_LSB1 + pr2100_write_register(ViPipe, 0x94, 0x0f); //SLICE_VSYNC1 + pr2100_write_register(ViPipe, 0x95, 0x5e); //STD_SLICE_AHD1 + pr2100_write_register(ViPipe, 0x96, 0x03); //HACT_SIZE_960_MSB1 + pr2100_write_register(ViPipe, 0x97, 0xd0); //HACT_SIZE_960_LSB1 + pr2100_write_register(ViPipe, 0x98, 0x17); //HPERIOD_960P25MSB1 + pr2100_write_register(ViPipe, 0x99, 0x34); //HPERIOD_960P25LSB1 + pr2100_write_register(ViPipe, 0x9a, 0x13); //HPERIOD_960P30MSB1 + pr2100_write_register(ViPipe, 0x9b, 0x56); //HPERIOD_960P30LSB1 + pr2100_write_register(ViPipe, 0x9c, 0x0b); //HPERIOD_960P50MSB1 + pr2100_write_register(ViPipe, 0x9d, 0x9a); //HPERIOD_960P50LSB1 + pr2100_write_register(ViPipe, 0x9e, 0x09); //HPERIOD_960P60MSB1 + pr2100_write_register(ViPipe, 0x9f, 0xab); //HPERIOD_960P60LSB1 + pr2100_write_register(ViPipe, 0xa0, 0x01); //VALY_STRT_960P25MSB1 + pr2100_write_register(ViPipe, 0xa1, 0x74); //VALY_STRT_960P25LSB1 + pr2100_write_register(ViPipe, 0xa2, 0x01); //VALY_STRT_960P30MSB1 + pr2100_write_register(ViPipe, 0xa3, 0x6b); //VALY_STRT_960P30LSB1 + pr2100_write_register(ViPipe, 0xa4, 0x00); //VALY_STRT_960P50MSB1 + pr2100_write_register(ViPipe, 0xa5, 0xba); //VALY_STRT_960P50LSB1 + pr2100_write_register(ViPipe, 0xa6, 0x00); //VALY_STRT_960P60MSB1 + pr2100_write_register(ViPipe, 0xa7, 0xa3); //VALY_STRT_960P60LSB1 + pr2100_write_register(ViPipe, 0xa8, 0x01); //PED_STRT_960P25MSB1 + pr2100_write_register(ViPipe, 0xa9, 0x39); //PED_STRT_960P25LSB1 + pr2100_write_register(ViPipe, 0xaa, 0x01); //PED_STRT_960P30MSB1 + pr2100_write_register(ViPipe, 0xab, 0x39); //PED_STRT_960P30LSB1 + pr2100_write_register(ViPipe, 0xac, 0x00); //PED_STRT_960P50MSB1 + pr2100_write_register(ViPipe, 0xad, 0xc1); //PED_STRT_960P50LSB1 + pr2100_write_register(ViPipe, 0xae, 0x00); //PED_STRT_960P60MSB1 + pr2100_write_register(ViPipe, 0xaf, 0xc1); //PED_STRT_960P60LSB1 + pr2100_write_register(ViPipe, 0xb0, 0x05); //COMB_MEM_960PMSB1 + pr2100_write_register(ViPipe, 0xb1, 0xcc); //COMB_MEM_960PLSB1 + pr2100_write_register(ViPipe, 0xb2, 0x09); //C_JIT_GAIN_960PMSB1 + pr2100_write_register(ViPipe, 0xb3, 0x6d); //C_JIT_GAIN_960PLSB1 + pr2100_write_register(ViPipe, 0xb4, 0x00); //STD_VPOS_AHD_MSB1 + pr2100_write_register(ViPipe, 0xb5, 0x17); //STD_VPOS_AHD_LSB1 + pr2100_write_register(ViPipe, 0xb6, 0x08); //STD_HPOS_AHD_MSB1 + pr2100_write_register(ViPipe, 0xb7, 0xe8); //STD_HPOS_AHD_LSB1 + pr2100_write_register(ViPipe, 0xb8, 0xb0); //STD_TVI_OFFSET_25F1 + pr2100_write_register(ViPipe, 0xb9, 0xce); //STD_TVI_OFFSET_30F1 + pr2100_write_register(ViPipe, 0xba, 0x90); //STD_TVI_OFFSET_960P1 + pr2100_write_register(ViPipe, 0xbb, 0x00); //EXT_SYNC_CON1 + pr2100_write_register(ViPipe, 0xbc, 0x00); //VOSYNC_HDELAY_MSB1 + pr2100_write_register(ViPipe, 0xbd, 0x04); //VOSYNC_HDELAY_LSB1 + pr2100_write_register(ViPipe, 0xbe, 0x07); //VOSYNC_HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xbf, 0x80); //VOSYNC_HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xc0, 0x00); //VOSYNC_VDELAY_MSB1 + pr2100_write_register(ViPipe, 0xc1, 0x00); //VOSYNC_VDELAY_LSB1 + #if PR2100_TEST_PATTERN + pr2100_write_register(ViPipe, 0xc2, 0x44); + pr2100_write_register(ViPipe, 0xc3, 0x38); + #else + pr2100_write_register(ViPipe, 0xc2, 0x04); //VOSYNC_VACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xc3, 0x39); //VOSYNC_VACTIVE_LSB1 + #endif + pr2100_write_register(ViPipe, 0xc4, output_pattern_ch1); + pr2100_write_register(ViPipe, 0xc9, 0x00); //VISYNC_HDELAY_MSB1 + pr2100_write_register(ViPipe, 0xca, 0x02); //VISYNC_HDELAY_LSB1 + pr2100_write_register(ViPipe, 0xcb, 0x07); //VISYNC_HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xcc, 0x80); //VISYNC_HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xcd, 0x08); //VISYNC_VDELAY_MSB1 + pr2100_write_register(ViPipe, 0xce, 0x20); //VISYNC_VDELAY_LSB1 + pr2100_write_register(ViPipe, 0xcf, 0x04); //VISYNC_VACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xd0, 0x38); //VISYNC_VACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xd1, 0x00); //MIPI_DATA_FLD_CON_1 + pr2100_write_register(ViPipe, 0xd2, 0x00); //MIPI_DATA_ODD_VAL_1 + pr2100_write_register(ViPipe, 0xd3, 0x00); //MIPI_DATA_EVEN_VAL_1 + + pr2100_write_register(ViPipe, 0xFF, 0x05); + pr2100_write_register(ViPipe, 0x09, 0x00); //REF_CH_STRT + pr2100_write_register(ViPipe, 0x0a, 0x03); //REF_CH_VDLY + pr2100_write_register(ViPipe, 0x0e, 0x80); //VBLK_CODE + pr2100_write_register(ViPipe, 0x0f, 0x10); //VBLK_CODE + pr2100_write_register(ViPipe, 0x10, 0xb3); //MTX_CTRL + pr2100_write_register(ViPipe, 0x11, 0x90); //MTX_LONG_DLY_H + pr2100_write_register(ViPipe, 0x12, 0x6e); //MTX_LONG_DLY_L + pr2100_write_register(ViPipe, 0x13, 0x00); //MTX_SHORT_DLY_H + pr2100_write_register(ViPipe, 0x14, 0x6e); //MTX_SHORT_DLY_L + pr2100_write_register(ViPipe, 0x15, 0x00); //REF_OFFSET + pr2100_write_register(ViPipe, 0x16, 0x00); //REF_FE_HDLY + pr2100_write_register(ViPipe, 0x17, 0x00); //REF_FE_HDLY + pr2100_write_register(ViPipe, 0x18, 0x00); //REF_FS_HDLY + pr2100_write_register(ViPipe, 0x19, 0x00); //REF_FS_HDLY + pr2100_write_register(ViPipe, 0x1a, 0x00); //REF_HTOTAL + pr2100_write_register(ViPipe, 0x1b, 0x00); //REF_HTOTAL + pr2100_write_register(ViPipe, 0x1c, 0x00); //REF_VTOTAL + pr2100_write_register(ViPipe, 0x1d, 0x00); //REF_VTOTAL + pr2100_write_register(ViPipe, 0x1e, 0x00); //CHID_MD + pr2100_write_register(ViPipe, 0x20, 0x88); //MTX_CH0_CTRL + pr2100_write_register(ViPipe, 0x21, 0x07); //MTX_CH0_HSIZE + pr2100_write_register(ViPipe, 0x22, 0x80); //MTX_CH0_HSIZE + pr2100_write_register(ViPipe, 0x23, 0x04); //MTX_CH0_VSIZE + pr2100_write_register(ViPipe, 0x24, 0x38); //MTX_CH0_VSIZE + pr2100_write_register(ViPipe, 0x25, 0x0f); //CH0_FS_OS_H + pr2100_write_register(ViPipe, 0x26, 0x00); //CH0_FS_OS_L + pr2100_write_register(ViPipe, 0x27, 0x0f); //CH0_FE_OS_H + pr2100_write_register(ViPipe, 0x28, 0x00); //CH0_FE_OS_L + pr2100_write_register(ViPipe, 0x29, 0x0b); //REF_CH0_VS_OS + pr2100_write_register(ViPipe, 0x2a, 0x40); //REF_CH0_VS_OS + pr2100_write_register(ViPipe, 0x30, 0x98); //MTX_CH1_CTRL + pr2100_write_register(ViPipe, 0x31, 0x07); //MTX_CH1_HSIZE + pr2100_write_register(ViPipe, 0x32, 0x80); //MTX_CH1_HSIZE + pr2100_write_register(ViPipe, 0x33, 0x04); //MTX_CH1_VSIZE + pr2100_write_register(ViPipe, 0x34, 0x38); //MTX_CH1_VSIZE + pr2100_write_register(ViPipe, 0x35, 0x0f); //CH1_FS_OS_H + pr2100_write_register(ViPipe, 0x36, 0x00); //CH1_FS_OS_L + pr2100_write_register(ViPipe, 0x37, 0x0f); //CH1_FE_OS_H + pr2100_write_register(ViPipe, 0x38, 0x00); //CH1_FE_OS_L + pr2100_write_register(ViPipe, 0x39, 0x07); //REF_CH1_VS_OS + pr2100_write_register(ViPipe, 0x3a, 0x80); //REF_CH1_VS_OS + pr2100_write_register(ViPipe, 0x40, 0x28); //MTX_CH2_CTRL + pr2100_write_register(ViPipe, 0x41, 0x07); //MTX_CH2_HSIZE + pr2100_write_register(ViPipe, 0x42, 0x80); //MTX_CH2_HSIZE + pr2100_write_register(ViPipe, 0x43, 0x04); //MTX_CH2_VSIZE + pr2100_write_register(ViPipe, 0x44, 0x38); //MTX_CH2_VSIZE + pr2100_write_register(ViPipe, 0x45, 0x0f); //CH2_FS_OS_H + pr2100_write_register(ViPipe, 0x46, 0x00); //CH2_FS_OS_L + pr2100_write_register(ViPipe, 0x47, 0x0f); //CH2_FE_OS_H + pr2100_write_register(ViPipe, 0x48, 0x00); //CH2_FE_OS_L + pr2100_write_register(ViPipe, 0x49, 0x03); //REF_CH2_VS_OS + pr2100_write_register(ViPipe, 0x4a, 0xc0); //REF_CH2_VS_OS + pr2100_write_register(ViPipe, 0x50, 0x38); //MTX_CH3_CTRL + pr2100_write_register(ViPipe, 0x51, 0x07); //MTX_CH3_HSIZE + pr2100_write_register(ViPipe, 0x52, 0x80); //MTX_CH3_HSIZE + pr2100_write_register(ViPipe, 0x53, 0x04); //MTX_CH3_VSIZE + pr2100_write_register(ViPipe, 0x54, 0x38); //MTX_CH3_VSIZE + pr2100_write_register(ViPipe, 0x55, 0x0f); //CH3_FS_OS_H + pr2100_write_register(ViPipe, 0x56, 0x00); //CH3_FS_OS_L + pr2100_write_register(ViPipe, 0x57, 0x0f); //CH3_FE_OS_H + pr2100_write_register(ViPipe, 0x58, 0x00); //CH3_FE_OS_L + pr2100_write_register(ViPipe, 0x59, 0x00); //REF_CH3_VS_OS + pr2100_write_register(ViPipe, 0x5a, 0x00); //REF_CH3_VS_OS + pr2100_write_register(ViPipe, 0x60, 0x05); //CH0_HWIDTH[13:8] + pr2100_write_register(ViPipe, 0x61, 0x28); //CH0_HWIDTH [7:0] + pr2100_write_register(ViPipe, 0x62, 0x05); //CH1_HWIDTH[13:8] + pr2100_write_register(ViPipe, 0x63, 0x28); //CH1_HWIDTH [7:0] + pr2100_write_register(ViPipe, 0x64, 0x05); //CH2_HWIDTH[13:8] + pr2100_write_register(ViPipe, 0x65, 0x28); //CH2_HWIDTH [7:0] + pr2100_write_register(ViPipe, 0x66, 0x05); //CH3_HWIDTH[13:8] + pr2100_write_register(ViPipe, 0x67, 0x28); //CH3_HWIDTH [7:0] + pr2100_write_register(ViPipe, 0x68, 0xff); //CH0_VRATE[15:8] + pr2100_write_register(ViPipe, 0x69, 0xff); //CH0_VRATE[7:0] + pr2100_write_register(ViPipe, 0x6a, 0xff); //CH1_VRATE[15:8] + pr2100_write_register(ViPipe, 0x6b, 0xff); //CH1_VRATE[7:0] + pr2100_write_register(ViPipe, 0x6c, 0xff); //CH2_VRATE[15:8] + pr2100_write_register(ViPipe, 0x6d, 0xff); //CH2_VRATE[7:0] + pr2100_write_register(ViPipe, 0x6e, 0xff); //CH3_VRATE[15:8] + pr2100_write_register(ViPipe, 0x6f, 0xff); //CH3_VRATE[7:0] + + pr2100_write_register(ViPipe, 0xFF, 0x06); + pr2100_write_register(ViPipe, 0x04, 0x10); //MIPI_CONTROL_0 + pr2100_write_register(ViPipe, 0x05, 0x04); //MIPI_CONTROL_1 + pr2100_write_register(ViPipe, 0x06, 0x00); //MIPI_CONTROL_2 + pr2100_write_register(ViPipe, 0x07, 0x00); //MIPI_CONTROL_3 + pr2100_write_register(ViPipe, 0x08, 0xc9); //MIPI_CONTROL_4 + pr2100_write_register(ViPipe, 0x1c, 0x09); //MIPI_T_LPX + pr2100_write_register(ViPipe, 0x1d, 0x08); //MIPI_T_CLK_PREPARE + pr2100_write_register(ViPipe, 0x1e, 0x09); //MIPI_T_HS_PREPARE + pr2100_write_register(ViPipe, 0x1f, 0x11); //MIPI_T_HS_ZERO + pr2100_write_register(ViPipe, 0x20, 0x0c); //MIPI_T_HS_TRAIL + pr2100_write_register(ViPipe, 0x21, 0x28); //MIPI_T_CLK_ZERO + pr2100_write_register(ViPipe, 0x22, 0x0b); //MIPI_T_CLK_TRAIL + pr2100_write_register(ViPipe, 0x23, 0x01); //MIPI_T_CLK_PRE + pr2100_write_register(ViPipe, 0x24, 0x12); //MIPI_T_CLK_POST + pr2100_write_register(ViPipe, 0x25, 0x82); //MIPI_T_WAKEUP + pr2100_write_register(ViPipe, 0x26, 0x11); //MIPI_T_HSEXIT + pr2100_write_register(ViPipe, 0x27, 0x11); //MIPI_T_CLK_HSEXIT + pr2100_write_register(ViPipe, 0x36, 0x0f); //MIPI_PKT_SIZE0_H + pr2100_write_register(ViPipe, 0x37, 0x00); //MIPI_PKT_SIZE0_L + pr2100_write_register(ViPipe, 0x38, 0x0f); //MIPI_PKT_SIZE1_H + pr2100_write_register(ViPipe, 0x39, 0x00); //MIPI_PKT_SIZE1_L + pr2100_write_register(ViPipe, 0x3a, 0x0f); //MIPI_PKT_SIZE2_H + pr2100_write_register(ViPipe, 0x3b, 0x00); //MIPI_PKT_SIZE2_L + pr2100_write_register(ViPipe, 0x3c, 0x0f); //MIPI_PKT_SIZE3_H + pr2100_write_register(ViPipe, 0x3d, 0x00); //MIPI_PKT_SIZE3_L + pr2100_write_register(ViPipe, 0x46, 0x1e); //MIPI_DATA_ID0 + pr2100_write_register(ViPipe, 0x47, 0x5e); //MIPI_DATA_ID1 + pr2100_write_register(ViPipe, 0x48, 0x9e); //MIPI_DATA_ID2 + pr2100_write_register(ViPipe, 0x49, 0xde); //MIPI_DATA_ID3 + pr2100_write_register(ViPipe, 0x04, 0x50); //MIPI_CONTROL_0 +} + +static void pr2100_set_1080p_4ch_slave(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "4CH Slave ViPipe=%d\n", ViPipe); + //chip id : 0x5d-(ch:0)Set vdec [Camera:3(HDA), videoResolution:11(video_1920x1080p25)] + + pr2100_write_register(ViPipe, 0xFF, 0x00); + pr2100_write_register(ViPipe, 0x10, 0x83); //MAN_IFMT0 + pr2100_write_register(ViPipe, 0x11, 0x0f); //MAN_EQ_DC_GN0 + pr2100_write_register(ViPipe, 0x12, 0x00); //MAN_EQ_AC_GN0 + pr2100_write_register(ViPipe, 0x13, 0x00); //VADC_EQ_BAND0 + pr2100_write_register(ViPipe, 0x14, 0x21); //VADC_CTRL0_0 + pr2100_write_register(ViPipe, 0x15, 0x44); //VADC_CTRL1_0 + pr2100_write_register(ViPipe, 0x16, 0x0d); //VADC_CTRL2_0 + pr2100_write_register(ViPipe, 0x30, 0x83); //MAN_IFMT1 + pr2100_write_register(ViPipe, 0x31, 0x0f); //MAN_EQ_DC_GN1 + pr2100_write_register(ViPipe, 0x32, 0x00); //MAN_EQ_AC_GN1 + pr2100_write_register(ViPipe, 0x33, 0x00); //VADC_EQ_BAND1 + pr2100_write_register(ViPipe, 0x34, 0x21); //VADC_CTRL0_1 + pr2100_write_register(ViPipe, 0x35, 0x44); //VADC_CTRL1_1 + pr2100_write_register(ViPipe, 0x36, 0x0d); //VADC_CTRL2_1 + pr2100_write_register(ViPipe, 0x80, 0x80); //IRQ_CTRL + pr2100_write_register(ViPipe, 0x81, 0x0e); //IRQ_SYNC_PERIOD + pr2100_write_register(ViPipe, 0x82, 0x0d); //WAKE0_PERIOD + pr2100_write_register(ViPipe, 0x84, 0xf0); //IRQ_NOVID_MD + pr2100_write_register(ViPipe, 0x8a, 0x00); //WAKE1_PERIOD + pr2100_write_register(ViPipe, 0x90, 0x00); //IRQENA_WAKE + pr2100_write_register(ViPipe, 0x91, 0x00); //IRQENA_GPIO + pr2100_write_register(ViPipe, 0x94, 0xff); //IRQCLR_WAKE + pr2100_write_register(ViPipe, 0x95, 0xff); //IRQCLR_GPIO + pr2100_write_register(ViPipe, 0xa0, 0x33); //IRQENA_VFD0 + pr2100_write_register(ViPipe, 0xb0, 0x33); //IRQENA_VFD1 + pr2100_write_register(ViPipe, 0xc0, 0x20); //MPP_CTRL0 + pr2100_write_register(ViPipe, 0xc1, 0x20); //MPP_CTRL1 + pr2100_write_register(ViPipe, 0xc2, 0x20); //MPP_CTRL2 + pr2100_write_register(ViPipe, 0xc3, 0x20); //MPP_CTRL3 + pr2100_write_register(ViPipe, 0xc4, 0x20); //MPP_CTRL4 + pr2100_write_register(ViPipe, 0xc5, 0x20); //MPP_CTRL5 + pr2100_write_register(ViPipe, 0xc6, 0x20); //MPP_CTRL6 + pr2100_write_register(ViPipe, 0xc7, 0x20); //MPP_CTRL7 + pr2100_write_register(ViPipe, 0xc8, 0x20); //MPP_CTRL8 + pr2100_write_register(ViPipe, 0xc9, 0x04); //MPP_CTRL9 + pr2100_write_register(ViPipe, 0xca, 0x04); //MPP_CTRLA + pr2100_write_register(ViPipe, 0xcb, 0x04); //MPP_CTRLB + pr2100_write_register(ViPipe, 0xd0, 0x06); //PLL0_CON0 + pr2100_write_register(ViPipe, 0xd1, 0x23); //PLL0_CON1 + pr2100_write_register(ViPipe, 0xd2, 0x21); //PLL0_CON2 + pr2100_write_register(ViPipe, 0xd3, 0x44); //PLL0_CON3 + pr2100_write_register(ViPipe, 0xd4, 0x06); //PLL1_CON0 + pr2100_write_register(ViPipe, 0xd5, 0x23); //PLL1_CON1 + pr2100_write_register(ViPipe, 0xd6, 0x21); //PLL1_CON2 + pr2100_write_register(ViPipe, 0xd7, 0x61); //PLL1_CON3 + pr2100_write_register(ViPipe, 0xd8, 0x86); //PLL2_CON0 + pr2100_write_register(ViPipe, 0xd9, 0x23); //PLL2_CON1 + pr2100_write_register(ViPipe, 0xda, 0x21); //PLL2_CON2 + pr2100_write_register(ViPipe, 0xe0, 0x05); //LATCH_EN_CON0 + pr2100_write_register(ViPipe, 0xe1, 0x05); //LATCH_EN_CON1 + pr2100_write_register(ViPipe, 0xe2, 0x14); //OUT_FMT + pr2100_write_register(ViPipe, 0xe3, 0xc4); //CHID_NUM, Y-Cb-Y-Cr + pr2100_write_register(ViPipe, 0xe4, 0x20); //CH_SEL0 + pr2100_write_register(ViPipe, 0xe5, 0x64); //CH_SEL1 + pr2100_write_register(ViPipe, 0xe6, 0x02); //CH_SEL2 + pr2100_write_register(ViPipe, 0xe7, 0x64); //CH_SEL3 + pr2100_write_register(ViPipe, 0xe8, 0x08); //VDCKP_PHASE + pr2100_write_register(ViPipe, 0xe9, 0x08); //VDCKN_PHASE + pr2100_write_register(ViPipe, 0xea, 0x10); //CLK_PWDN + pr2100_write_register(ViPipe, 0xeb, 0x00); //MIPI_DATA_EN + pr2100_write_register(ViPipe, 0xf0, 0x02); //PAR_OE_M + pr2100_write_register(ViPipe, 0xf1, 0x00); //PAR_OE_L + pr2100_write_register(ViPipe, 0xf3, 0x04); //PAD_MPP_CTL + pr2100_write_register(ViPipe, 0xf4, 0x44); //PAD_VD_CTL + + pr2100_write_register(ViPipe, 0xFF, 0x01); + pr2100_write_register(ViPipe, 0x00, 0xe4); //VID_CON0 + pr2100_write_register(ViPipe, 0x01, 0x61); //GAINFIT0 + pr2100_write_register(ViPipe, 0x02, 0x00); //PEDFIT0 + pr2100_write_register(ViPipe, 0x03, 0x56); //CLAMP_CON0 + pr2100_write_register(ViPipe, 0x04, 0x0c); //HPLL_CON0_0 + pr2100_write_register(ViPipe, 0x05, 0x88); //HPLL_CON1_0 + pr2100_write_register(ViPipe, 0x06, 0x04); //HPLL_CON2_0 + pr2100_write_register(ViPipe, 0x07, 0xb2); //HPLL_CON3_0 + pr2100_write_register(ViPipe, 0x08, 0x44); //HPLL_CON4_0 + pr2100_write_register(ViPipe, 0x09, 0x34); //HPLL_CON5_0 + pr2100_write_register(ViPipe, 0x0a, 0x02); //HPLL_CON6_0 + pr2100_write_register(ViPipe, 0x0b, 0x14); //STD_POS0_0 + pr2100_write_register(ViPipe, 0x0c, 0x04); //STD_POS1_0 + pr2100_write_register(ViPipe, 0x0d, 0x08); //STD_POS2_0 + pr2100_write_register(ViPipe, 0x0e, 0x5e); //STD_SLICE0_0 + pr2100_write_register(ViPipe, 0x0f, 0x5e); //STD_SLICE1_0 + pr2100_write_register(ViPipe, 0x10, 0x26); //STD_SLICE2_0 + pr2100_write_register(ViPipe, 0x11, 0x00); //HDELAY_MSB0 + pr2100_write_register(ViPipe, 0x12, 0x87); //HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0x13, 0x24); //HDELAY_LSB0 + pr2100_write_register(ViPipe, 0x14, 0x80); //HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x15, 0x2a); //VDELAY0 + pr2100_write_register(ViPipe, 0x16, 0x38); //VACTIVE0 + pr2100_write_register(ViPipe, 0x17, 0x00); //CBG_DELAY_MSB0 + pr2100_write_register(ViPipe, 0x18, 0x80); //CBG_ACTIVE_MSB0 + pr2100_write_register(ViPipe, 0x19, 0x48); //CBG_DELAY_LSB0 + pr2100_write_register(ViPipe, 0x1a, 0x6c); //CBG_ACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x1b, 0x05); //VSMASK_INV_STRT0 + pr2100_write_register(ViPipe, 0x1c, 0x61); //VSMASK_INV_END0 + pr2100_write_register(ViPipe, 0x1d, 0x07); //CBP_DELAY_MSB0 + pr2100_write_register(ViPipe, 0x1e, 0x7e); //CBP_DELAY_LSB0 + pr2100_write_register(ViPipe, 0x1f, 0x80); //HSCL_ACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x20, 0x80); //CONT0 + pr2100_write_register(ViPipe, 0x21, 0x80); //BRGT0 + pr2100_write_register(ViPipe, 0x22, 0x90); //SAT0 + pr2100_write_register(ViPipe, 0x23, 0x80); //HUE0 + pr2100_write_register(ViPipe, 0x24, 0x80); //CB_GAIN0 + pr2100_write_register(ViPipe, 0x25, 0x80); //CR_GAIN0 + pr2100_write_register(ViPipe, 0x26, 0x84); //CB_OFF0 + pr2100_write_register(ViPipe, 0x27, 0x82); //CR_OFF0 + pr2100_write_register(ViPipe, 0x28, 0x00); //Y_OUT_GAIN0 + pr2100_write_register(ViPipe, 0x29, 0xff); //DOWN_HSCL_MSB0 + pr2100_write_register(ViPipe, 0x2a, 0xff); //DOWN_HSCL_LSB0 + pr2100_write_register(ViPipe, 0x2b, 0x00); //MAN_HSCL_ADD0_0 + pr2100_write_register(ViPipe, 0x2c, 0x00); //MAN_HSCL_ADD1_0 + pr2100_write_register(ViPipe, 0x2d, 0x00); //MAN_HSCL_ADD2_0 + pr2100_write_register(ViPipe, 0x2e, 0x00); //MAN_OUTFMT_ADD0_0 + pr2100_write_register(ViPipe, 0x2f, 0x00); //MAN_OUTFMT_ADD1_0 + pr2100_write_register(ViPipe, 0x30, 0x00); //MAN_OUTFMT_ADD2_0 + pr2100_write_register(ViPipe, 0x31, 0x00); //MAN_COMB_MD0 + pr2100_write_register(ViPipe, 0x32, 0xc0); //COMB_CRL_MD0 + pr2100_write_register(ViPipe, 0x33, 0x14); //COMB_CVBS_CRL0_0 + pr2100_write_register(ViPipe, 0x34, 0x14); //COMB_CVBS_CRL1_0 + pr2100_write_register(ViPipe, 0x35, 0x80); //COMB_CVBS_CRL2_0 + pr2100_write_register(ViPipe, 0x36, 0x80); //COMB_CVBS_CRL3_0 + pr2100_write_register(ViPipe, 0x37, 0xad); //HD_Y_NOTCH_MD0 + pr2100_write_register(ViPipe, 0x38, 0x4b); //HD_COMB_FLT_MD0 + pr2100_write_register(ViPipe, 0x39, 0x08); //Y_DYN_PEAK_GN0 + pr2100_write_register(ViPipe, 0x3a, 0x21); //HD_Y_LPF_MD0 + pr2100_write_register(ViPipe, 0x3b, 0x02); //Y_HPF_CORE_MIN0 + pr2100_write_register(ViPipe, 0x3c, 0x01); //Y_HPF_CORE_STEP0 + pr2100_write_register(ViPipe, 0x3d, 0x23); //CORE_CON0 + pr2100_write_register(ViPipe, 0x3e, 0x05); //MAN_CLPF_MD0 + pr2100_write_register(ViPipe, 0x3f, 0xc8); //HD_CTI_CON0 + pr2100_write_register(ViPipe, 0x40, 0x05); //C_LOOP_CON0_0 + pr2100_write_register(ViPipe, 0x41, 0x55); //C_LOOP_CON1_0 + pr2100_write_register(ViPipe, 0x42, 0x01); //C_LOOP_CON2_0 + pr2100_write_register(ViPipe, 0x43, 0x38); //C_LOOP_CON3_0 + pr2100_write_register(ViPipe, 0x44, 0x6a); //C_HUE_CVI0_0 + pr2100_write_register(ViPipe, 0x45, 0x00); //C_HUE_CVI1_0 + pr2100_write_register(ViPipe, 0x46, 0x14); //C_PHASE_REF0_0 + pr2100_write_register(ViPipe, 0x47, 0xb0); //C_PHASE_REF1_0 + pr2100_write_register(ViPipe, 0x48, 0xdf); //C_PHASE_REF2_0 + pr2100_write_register(ViPipe, 0x49, 0x00); //G_GAIN_REF0_0 + pr2100_write_register(ViPipe, 0x4a, 0x7b); //G_GAIN_REF1_0 + pr2100_write_register(ViPipe, 0x4b, 0x60); //MAN_C_GAIN_VAL0_0 + pr2100_write_register(ViPipe, 0x4c, 0x00); //MAN_C_GAIN_VAL1_0 + pr2100_write_register(ViPipe, 0x4d, 0x26); //YC_DELAY0 + pr2100_write_register(ViPipe, 0x4e, 0x00); //HD_HALF_MD0 + pr2100_write_register(ViPipe, 0x4f, 0x2c); //OUTFMT_CON0 + pr2100_write_register(ViPipe, 0x50, 0x21); //TST_EQ_POS0_0 + pr2100_write_register(ViPipe, 0x51, 0x28); //TST_EQ_POS1_0 + pr2100_write_register(ViPipe, 0x52, 0x40); //TST_EQ_POS2_0 + pr2100_write_register(ViPipe, 0x53, 0x0c); //TST_VID_DEC0 + pr2100_write_register(ViPipe, 0x54, 0x0f); //TST_VID_RST0 + pr2100_write_register(ViPipe, 0x55, 0x8d); //PTZ_SLICE_LVL0 + pr2100_write_register(ViPipe, 0x70, 0x06); //COMB_VCRL_VTH1_0 + pr2100_write_register(ViPipe, 0x71, 0x08); //COMB_VCRL_VTH2_0 + pr2100_write_register(ViPipe, 0x72, 0x0a); //COMB_VCRL_VTH3_0 + pr2100_write_register(ViPipe, 0x73, 0x0c); //COMB_VCRL_VTH4_0 + pr2100_write_register(ViPipe, 0x74, 0x0e); //COMB_VCRL_VTH5_0 + pr2100_write_register(ViPipe, 0x75, 0x10); //COMB_VCRL_VTH6_0 + pr2100_write_register(ViPipe, 0x76, 0x12); //COMB_VCRL_VTH7_0 + pr2100_write_register(ViPipe, 0x77, 0x14); //COMB_VCRL_VTH8_0 + pr2100_write_register(ViPipe, 0x78, 0x06); //COMB_VMIX_VTH1_0 + pr2100_write_register(ViPipe, 0x79, 0x08); //COMB_VMIX_VTH2_0 + pr2100_write_register(ViPipe, 0x7a, 0x0a); //COMB_VMIX_VTH3_0 + pr2100_write_register(ViPipe, 0x7b, 0x0c); //COMB_VMIX_VTH4_0 + pr2100_write_register(ViPipe, 0x7c, 0x0e); //COMB_VMIX_VTH5_0 + pr2100_write_register(ViPipe, 0x7d, 0x10); //COMB_VMIX_VTH6_0 + pr2100_write_register(ViPipe, 0x7e, 0x12); //COMB_VMIX_VTH7_0 + pr2100_write_register(ViPipe, 0x7f, 0x14); //COMB_VMIX_VTH8_0 + pr2100_write_register(ViPipe, 0x80, 0x00); //STD_VPOS_PVI_960MSB0 + pr2100_write_register(ViPipe, 0x81, 0x09); //STD_VPOS_PVI_960LSB0 + pr2100_write_register(ViPipe, 0x82, 0x00); //STD_VPOS_CVI_960MSB0 + pr2100_write_register(ViPipe, 0x83, 0x07); //STD_VPOS_CVI_960LSB0 + pr2100_write_register(ViPipe, 0x84, 0x00); //STD_VPOS_AHD_960MSB0 + pr2100_write_register(ViPipe, 0x85, 0x17); //STD_VPOS_AHD_960LSB0 + pr2100_write_register(ViPipe, 0x86, 0x03); //STD_VPOS_TVI_960MSB0 + pr2100_write_register(ViPipe, 0x87, 0xe5); //STD_VPOS_TVI_960LSB0 + pr2100_write_register(ViPipe, 0x88, 0x05); //STD_HPOS_PVI_960MSB0 + pr2100_write_register(ViPipe, 0x89, 0x24); //STD_HPOS_PVI_960LSB0 + pr2100_write_register(ViPipe, 0x8a, 0x05); //STD_HPOS_CVI_960MSB0 + pr2100_write_register(ViPipe, 0x8b, 0x24); //STD_HPOS_CVI_960LSB0 + pr2100_write_register(ViPipe, 0x8c, 0x08); //STD_HPOS_AHD_960MSB0 + pr2100_write_register(ViPipe, 0x8d, 0xe8); //STD_HPOS_AHD_960LSB0 + pr2100_write_register(ViPipe, 0x8e, 0x05); //STD_HPOS_TVI_960MSB0 + pr2100_write_register(ViPipe, 0x8f, 0x47); //STD_HPOS_TVI_960LSB0 + pr2100_write_register(ViPipe, 0x90, 0x02); //VSYNC_ACCUM_960MSB0 + pr2100_write_register(ViPipe, 0x91, 0xb4); //VSYNC_ACCUM_960LSB0 + pr2100_write_register(ViPipe, 0x92, 0x73); //VLINE_MAX_960_MSB0 + pr2100_write_register(ViPipe, 0x93, 0xe8); //VLINE_MAX_960_LSB0 + pr2100_write_register(ViPipe, 0x94, 0x0f); //SLICE_VSYNC0 + pr2100_write_register(ViPipe, 0x95, 0x5e); //STD_SLICE_AHD0 + pr2100_write_register(ViPipe, 0x96, 0x03); //HACT_SIZE_960_MSB0 + pr2100_write_register(ViPipe, 0x97, 0xd0); //HACT_SIZE_960_LSB0 + pr2100_write_register(ViPipe, 0x98, 0x17); //HPERIOD_960P25MSB0 + pr2100_write_register(ViPipe, 0x99, 0x34); //HPERIOD_960P25LSB0 + pr2100_write_register(ViPipe, 0x9a, 0x13); //HPERIOD_960P30MSB0 + pr2100_write_register(ViPipe, 0x9b, 0x56); //HPERIOD_960P30LSB0 + pr2100_write_register(ViPipe, 0x9c, 0x0b); //HPERIOD_960P50MSB0 + pr2100_write_register(ViPipe, 0x9d, 0x9a); //HPERIOD_960P50LSB0 + pr2100_write_register(ViPipe, 0x9e, 0x09); //HPERIOD_960P60MSB0 + pr2100_write_register(ViPipe, 0x9f, 0xab); //HPERIOD_960P60LSB0 + pr2100_write_register(ViPipe, 0xa0, 0x01); //VALY_STRT_960P25MSB0 + pr2100_write_register(ViPipe, 0xa1, 0x74); //VALY_STRT_960P25LSB0 + pr2100_write_register(ViPipe, 0xa2, 0x01); //VALY_STRT_960P30MSB0 + pr2100_write_register(ViPipe, 0xa3, 0x6b); //VALY_STRT_960P30LSB0 + pr2100_write_register(ViPipe, 0xa4, 0x00); //VALY_STRT_960P50MSB0 + pr2100_write_register(ViPipe, 0xa5, 0xba); //VALY_STRT_960P50LSB0 + pr2100_write_register(ViPipe, 0xa6, 0x00); //VALY_STRT_960P60MSB0 + pr2100_write_register(ViPipe, 0xa7, 0xa3); //VALY_STRT_960P60LSB0 + pr2100_write_register(ViPipe, 0xa8, 0x01); //PED_STRT_960P25MSB0 + pr2100_write_register(ViPipe, 0xa9, 0x39); //PED_STRT_960P25LSB0 + pr2100_write_register(ViPipe, 0xaa, 0x01); //PED_STRT_960P30MSB0 + pr2100_write_register(ViPipe, 0xab, 0x39); //PED_STRT_960P30LSB0 + pr2100_write_register(ViPipe, 0xac, 0x00); //PED_STRT_960P50MSB0 + pr2100_write_register(ViPipe, 0xad, 0xc1); //PED_STRT_960P50LSB0 + pr2100_write_register(ViPipe, 0xae, 0x00); //PED_STRT_960P60MSB0 + pr2100_write_register(ViPipe, 0xaf, 0xc1); //PED_STRT_960P60LSB0 + pr2100_write_register(ViPipe, 0xb0, 0x05); //COMB_MEM_960PMSB0 + pr2100_write_register(ViPipe, 0xb1, 0xcc); //COMB_MEM_960PLSB0 + pr2100_write_register(ViPipe, 0xb2, 0x09); //C_JIT_GAIN_960PMSB0 + pr2100_write_register(ViPipe, 0xb3, 0x6d); //C_JIT_GAIN_960PLSB0 + pr2100_write_register(ViPipe, 0xb4, 0x00); //STD_VPOS_AHD_MSB0 + pr2100_write_register(ViPipe, 0xb5, 0x17); //STD_VPOS_AHD_LSB0 + pr2100_write_register(ViPipe, 0xb6, 0x08); //STD_HPOS_AHD_MSB0 + pr2100_write_register(ViPipe, 0xb7, 0xe8); //STD_HPOS_AHD_LSB0 + pr2100_write_register(ViPipe, 0xb8, 0xb0); //STD_TVI_OFFSET_25F0 + pr2100_write_register(ViPipe, 0xb9, 0xce); //STD_TVI_OFFSET_30F0 + pr2100_write_register(ViPipe, 0xba, 0x90); //STD_TVI_OFFSET_960P0 + pr2100_write_register(ViPipe, 0xbb, 0x00); //EXT_SYNC_CON0 + pr2100_write_register(ViPipe, 0xbc, 0x00); //VOSYNC_HDELAY_MSB0 + pr2100_write_register(ViPipe, 0xbd, 0x04); //VOSYNC_HDELAY_LSB0 + pr2100_write_register(ViPipe, 0xbe, 0x07); //VOSYNC_HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xbf, 0x80); //VOSYNC_HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xc0, 0x00); //VOSYNC_VDELAY_MSB0 + pr2100_write_register(ViPipe, 0xc1, 0x20); //VOSYNC_VDELAY_LSB0 + #if PR2100_SLAVE_TEST_PATTERN + pr2100_write_register(ViPipe, 0xc2, 0x44); + pr2100_write_register(ViPipe, 0xc3, 0x38); + pr2100_write_register(ViPipe, 0xc4, 0x88); + #else + pr2100_write_register(ViPipe, 0xc2, 0x04); //VOSYNC_VACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xc3, 0x38); //VOSYNC_VACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xc4, 0x00); + #endif + pr2100_write_register(ViPipe, 0xc5, 0x00); //MAN_INFMT_ADD_LSB0 + pr2100_write_register(ViPipe, 0xc6, 0x00); //C_PHASE_LOCK_RNG0_0 + pr2100_write_register(ViPipe, 0xc7, 0x00); //C_PHASE_LOCK_RNG1_0 + pr2100_write_register(ViPipe, 0xc8, 0x00); //C_PHASE_LOCK_RNG2_0 + pr2100_write_register(ViPipe, 0xc9, 0x00); //VISYNC_HDELAY_MSB0 + pr2100_write_register(ViPipe, 0xca, 0x04); //VISYNC_HDELAY_LSB0 + pr2100_write_register(ViPipe, 0xcb, 0x07); //VISYNC_HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xcc, 0x80); //VISYNC_HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xcd, 0x08); //VISYNC_VDELAY_MSB0 + pr2100_write_register(ViPipe, 0xce, 0x20); //VISYNC_VDELAY_LSB0 + pr2100_write_register(ViPipe, 0xcf, 0x04); //VISYNC_VACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xd0, 0x38); //VISYNC_VACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xd1, 0x10); //MIPI_DATA_FLD_CON_0 + + pr2100_write_register(ViPipe, 0xFF, 0x02); + pr2100_write_register(ViPipe, 0x00, 0xe4); //VID_CON1 + pr2100_write_register(ViPipe, 0x01, 0x61); //GAINFIT1 + pr2100_write_register(ViPipe, 0x02, 0x00); //PEDFIT1 + pr2100_write_register(ViPipe, 0x03, 0x56); //CLAMP_CON1 + pr2100_write_register(ViPipe, 0x04, 0x0c); //HPLL_CON0_1 + pr2100_write_register(ViPipe, 0x05, 0x88); //HPLL_CON1_1 + pr2100_write_register(ViPipe, 0x06, 0x04); //HPLL_CON2_1 + pr2100_write_register(ViPipe, 0x07, 0xb2); //HPLL_CON3_1 + pr2100_write_register(ViPipe, 0x08, 0x44); //HPLL_CON4_1 + pr2100_write_register(ViPipe, 0x09, 0x34); //HPLL_CON5_1 + pr2100_write_register(ViPipe, 0x0a, 0x02); //HPLL_CON6_1 + pr2100_write_register(ViPipe, 0x0b, 0x14); //STD_POS0_1 + pr2100_write_register(ViPipe, 0x0c, 0x04); //STD_POS1_1 + pr2100_write_register(ViPipe, 0x0d, 0x08); //STD_POS2_1 + pr2100_write_register(ViPipe, 0x0e, 0x5e); //STD_SLICE0_1 + pr2100_write_register(ViPipe, 0x0f, 0x5e); //STD_SLICE1_1 + pr2100_write_register(ViPipe, 0x10, 0x26); //STD_SLICE2_1 + pr2100_write_register(ViPipe, 0x11, 0x00); //HDELAY_MSB1 + pr2100_write_register(ViPipe, 0x12, 0x87); //HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0x13, 0x24); //HDELAY_LSB1 + pr2100_write_register(ViPipe, 0x14, 0x80); //HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x15, 0x2a); //VDELAY1 + pr2100_write_register(ViPipe, 0x16, 0x38); //VACTIVE1 + pr2100_write_register(ViPipe, 0x17, 0x00); //CBG_DELAY_MSB1 + pr2100_write_register(ViPipe, 0x18, 0x80); //CBG_ACTIVE_MSB1 + pr2100_write_register(ViPipe, 0x19, 0x48); //CBG_DELAY_LSB1 + pr2100_write_register(ViPipe, 0x1a, 0x6c); //CBG_ACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x1b, 0x05); //VSMASK_INV_STRT1 + pr2100_write_register(ViPipe, 0x1c, 0x61); //VSMASK_INV_END1 + pr2100_write_register(ViPipe, 0x1d, 0x07); //CBP_DELAY_MSB1 + pr2100_write_register(ViPipe, 0x1e, 0x7e); //CBP_DELAY_LSB1 + pr2100_write_register(ViPipe, 0x1f, 0x80); //HSCL_ACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x20, 0x80); //CONT1 + pr2100_write_register(ViPipe, 0x21, 0x80); //BRGT1 + pr2100_write_register(ViPipe, 0x22, 0x90); //SAT1 + pr2100_write_register(ViPipe, 0x23, 0x80); //HUE1 + pr2100_write_register(ViPipe, 0x24, 0x80); //CB_GAIN1 + pr2100_write_register(ViPipe, 0x25, 0x80); //CR_GAIN1 + pr2100_write_register(ViPipe, 0x26, 0x84); //CB_OFF1 + pr2100_write_register(ViPipe, 0x27, 0x82); //CR_OFF1 + pr2100_write_register(ViPipe, 0x28, 0x00); //Y_OUT_GAIN1 + pr2100_write_register(ViPipe, 0x29, 0xff); //DOWN_HSCL_MSB1 + pr2100_write_register(ViPipe, 0x2a, 0xff); //DOWN_HSCL_LSB1 + pr2100_write_register(ViPipe, 0x2b, 0x00); //MAN_HSCL_ADD0_1 + pr2100_write_register(ViPipe, 0x2c, 0x00); //MAN_HSCL_ADD1_1 + pr2100_write_register(ViPipe, 0x2d, 0x00); //MAN_HSCL_ADD2_1 + pr2100_write_register(ViPipe, 0x2e, 0x00); //MAN_OUTFMT_ADD0_1 + pr2100_write_register(ViPipe, 0x2f, 0x00); //MAN_OUTFMT_ADD1_1 + pr2100_write_register(ViPipe, 0x30, 0x00); //MAN_OUTFMT_ADD2_1 + pr2100_write_register(ViPipe, 0x31, 0x00); //MAN_COMB_MD1 + pr2100_write_register(ViPipe, 0x32, 0xc0); //COMB_CRL_MD1 + pr2100_write_register(ViPipe, 0x33, 0x14); //COMB_CVBS_CRL0_1 + pr2100_write_register(ViPipe, 0x34, 0x14); //COMB_CVBS_CRL1_1 + pr2100_write_register(ViPipe, 0x35, 0x80); //COMB_CVBS_CRL2_1 + pr2100_write_register(ViPipe, 0x36, 0x80); //COMB_CVBS_CRL3_1 + pr2100_write_register(ViPipe, 0x37, 0xad); //HD_Y_NOTCH_MD1 + pr2100_write_register(ViPipe, 0x38, 0x4b); //HD_COMB_FLT_MD1 + pr2100_write_register(ViPipe, 0x39, 0x08); //Y_DYN_PEAK_GN1 + pr2100_write_register(ViPipe, 0x3a, 0x21); //HD_Y_LPF_MD1 + pr2100_write_register(ViPipe, 0x3b, 0x02); //Y_HPF_CORE_MIN1 + pr2100_write_register(ViPipe, 0x3c, 0x01); //Y_HPF_CORE_STEP1 + pr2100_write_register(ViPipe, 0x3d, 0x23); //CORE_CON1 + pr2100_write_register(ViPipe, 0x3e, 0x05); //MAN_CLPF_MD1 + pr2100_write_register(ViPipe, 0x3f, 0xc8); //HD_CTI_CON1 + pr2100_write_register(ViPipe, 0x40, 0x05); //C_LOOP_CON0_1 + pr2100_write_register(ViPipe, 0x41, 0x55); //C_LOOP_CON1_1 + pr2100_write_register(ViPipe, 0x42, 0x01); //C_LOOP_CON2_1 + pr2100_write_register(ViPipe, 0x43, 0x38); //C_LOOP_CON3_1 + pr2100_write_register(ViPipe, 0x44, 0x6a); //C_HUE_CVI0_1 + pr2100_write_register(ViPipe, 0x45, 0x00); //C_HUE_CVI1_1 + pr2100_write_register(ViPipe, 0x46, 0x14); //C_PHASE_REF0_1 + pr2100_write_register(ViPipe, 0x47, 0xb0); //C_PHASE_REF1_1 + pr2100_write_register(ViPipe, 0x48, 0xdf); //C_PHASE_REF2_1 + pr2100_write_register(ViPipe, 0x49, 0x00); //G_GAIN_REF0_1 + pr2100_write_register(ViPipe, 0x4a, 0x7b); //G_GAIN_REF1_1 + pr2100_write_register(ViPipe, 0x4b, 0x60); //MAN_C_GAIN_VAL0_1 + pr2100_write_register(ViPipe, 0x4c, 0x00); //MAN_C_GAIN_VAL1_1 + pr2100_write_register(ViPipe, 0x4d, 0x26); //YC_DELAY1 + pr2100_write_register(ViPipe, 0x4e, 0x00); //HD_HALF_MD1 + pr2100_write_register(ViPipe, 0x4f, 0x2c); //OUTFMT_CON1 + pr2100_write_register(ViPipe, 0x50, 0x21); //TST_EQ_POS0_1 + pr2100_write_register(ViPipe, 0x51, 0x28); //TST_EQ_POS1_1 + pr2100_write_register(ViPipe, 0x52, 0x40); //TST_EQ_POS2_1 + pr2100_write_register(ViPipe, 0x53, 0x0c); //TST_VID_DEC1 + pr2100_write_register(ViPipe, 0x54, 0x0f); //TST_VID_RST1 + pr2100_write_register(ViPipe, 0x55, 0x8d); //PTZ_SLICE_LVL1 + pr2100_write_register(ViPipe, 0x70, 0x06); //COMB_VCRL_VTH1_1 + pr2100_write_register(ViPipe, 0x71, 0x08); //COMB_VCRL_VTH2_1 + pr2100_write_register(ViPipe, 0x72, 0x0a); //COMB_VCRL_VTH3_1 + pr2100_write_register(ViPipe, 0x73, 0x0c); //COMB_VCRL_VTH4_1 + pr2100_write_register(ViPipe, 0x74, 0x0e); //COMB_VCRL_VTH5_1 + pr2100_write_register(ViPipe, 0x75, 0x10); //COMB_VCRL_VTH6_1 + pr2100_write_register(ViPipe, 0x76, 0x12); //COMB_VCRL_VTH7_1 + pr2100_write_register(ViPipe, 0x77, 0x14); //COMB_VCRL_VTH8_1 + pr2100_write_register(ViPipe, 0x78, 0x06); //COMB_VMIX_VTH1_1 + pr2100_write_register(ViPipe, 0x79, 0x08); //COMB_VMIX_VTH2_1 + pr2100_write_register(ViPipe, 0x7a, 0x0a); //COMB_VMIX_VTH3_1 + pr2100_write_register(ViPipe, 0x7b, 0x0c); //COMB_VMIX_VTH4_1 + pr2100_write_register(ViPipe, 0x7c, 0x0e); //COMB_VMIX_VTH5_1 + pr2100_write_register(ViPipe, 0x7d, 0x10); //COMB_VMIX_VTH6_1 + pr2100_write_register(ViPipe, 0x7e, 0x12); //COMB_VMIX_VTH7_1 + pr2100_write_register(ViPipe, 0x7f, 0x14); //COMB_VMIX_VTH8_1 + pr2100_write_register(ViPipe, 0x80, 0x00); //STD_VPOS_PVI_960MSB1 + pr2100_write_register(ViPipe, 0x81, 0x09); //STD_VPOS_PVI_960LSB1 + pr2100_write_register(ViPipe, 0x82, 0x00); //STD_VPOS_CVI_960MSB1 + pr2100_write_register(ViPipe, 0x83, 0x07); //STD_VPOS_CVI_960LSB1 + pr2100_write_register(ViPipe, 0x84, 0x00); //STD_VPOS_AHD_960MSB1 + pr2100_write_register(ViPipe, 0x85, 0x17); //STD_VPOS_AHD_960LSB1 + pr2100_write_register(ViPipe, 0x86, 0x03); //STD_VPOS_TVI_960MSB1 + pr2100_write_register(ViPipe, 0x87, 0xe5); //STD_VPOS_TVI_960LSB1 + pr2100_write_register(ViPipe, 0x88, 0x05); //STD_HPOS_PVI_960MSB1 + pr2100_write_register(ViPipe, 0x89, 0x24); //STD_HPOS_PVI_960LSB1 + pr2100_write_register(ViPipe, 0x8a, 0x05); //STD_HPOS_CVI_960MSB1 + pr2100_write_register(ViPipe, 0x8b, 0x24); //STD_HPOS_CVI_960LSB1 + pr2100_write_register(ViPipe, 0x8c, 0x08); //STD_HPOS_AHD_960MSB1 + pr2100_write_register(ViPipe, 0x8d, 0xe8); //STD_HPOS_AHD_960LSB1 + pr2100_write_register(ViPipe, 0x8e, 0x05); //STD_HPOS_TVI_960MSB1 + pr2100_write_register(ViPipe, 0x8f, 0x47); //STD_HPOS_TVI_960LSB1 + pr2100_write_register(ViPipe, 0x90, 0x02); //VSYNC_ACCUM_960MSB1 + pr2100_write_register(ViPipe, 0x91, 0xb4); //VSYNC_ACCUM_960LSB1 + pr2100_write_register(ViPipe, 0x92, 0x73); //VLINE_MAX_960_MSB1 + pr2100_write_register(ViPipe, 0x93, 0xe8); //VLINE_MAX_960_LSB1 + pr2100_write_register(ViPipe, 0x94, 0x0f); //SLICE_VSYNC1 + pr2100_write_register(ViPipe, 0x95, 0x5e); //STD_SLICE_AHD1 + pr2100_write_register(ViPipe, 0x96, 0x03); //HACT_SIZE_960_MSB1 + pr2100_write_register(ViPipe, 0x97, 0xd0); //HACT_SIZE_960_LSB1 + pr2100_write_register(ViPipe, 0x98, 0x17); //HPERIOD_960P25MSB1 + pr2100_write_register(ViPipe, 0x99, 0x34); //HPERIOD_960P25LSB1 + pr2100_write_register(ViPipe, 0x9a, 0x13); //HPERIOD_960P30MSB1 + pr2100_write_register(ViPipe, 0x9b, 0x56); //HPERIOD_960P30LSB1 + pr2100_write_register(ViPipe, 0x9c, 0x0b); //HPERIOD_960P50MSB1 + pr2100_write_register(ViPipe, 0x9d, 0x9a); //HPERIOD_960P50LSB1 + pr2100_write_register(ViPipe, 0x9e, 0x09); //HPERIOD_960P60MSB1 + pr2100_write_register(ViPipe, 0x9f, 0xab); //HPERIOD_960P60LSB1 + pr2100_write_register(ViPipe, 0xa0, 0x01); //VALY_STRT_960P25MSB1 + pr2100_write_register(ViPipe, 0xa1, 0x74); //VALY_STRT_960P25LSB1 + pr2100_write_register(ViPipe, 0xa2, 0x01); //VALY_STRT_960P30MSB1 + pr2100_write_register(ViPipe, 0xa3, 0x6b); //VALY_STRT_960P30LSB1 + pr2100_write_register(ViPipe, 0xa4, 0x00); //VALY_STRT_960P50MSB1 + pr2100_write_register(ViPipe, 0xa5, 0xba); //VALY_STRT_960P50LSB1 + pr2100_write_register(ViPipe, 0xa6, 0x00); //VALY_STRT_960P60MSB1 + pr2100_write_register(ViPipe, 0xa7, 0xa3); //VALY_STRT_960P60LSB1 + pr2100_write_register(ViPipe, 0xa8, 0x01); //PED_STRT_960P25MSB1 + pr2100_write_register(ViPipe, 0xa9, 0x39); //PED_STRT_960P25LSB1 + pr2100_write_register(ViPipe, 0xaa, 0x01); //PED_STRT_960P30MSB1 + pr2100_write_register(ViPipe, 0xab, 0x39); //PED_STRT_960P30LSB1 + pr2100_write_register(ViPipe, 0xac, 0x00); //PED_STRT_960P50MSB1 + pr2100_write_register(ViPipe, 0xad, 0xc1); //PED_STRT_960P50LSB1 + pr2100_write_register(ViPipe, 0xae, 0x00); //PED_STRT_960P60MSB1 + pr2100_write_register(ViPipe, 0xaf, 0xc1); //PED_STRT_960P60LSB1 + pr2100_write_register(ViPipe, 0xb0, 0x05); //COMB_MEM_960PMSB1 + pr2100_write_register(ViPipe, 0xb1, 0xcc); //COMB_MEM_960PLSB1 + pr2100_write_register(ViPipe, 0xb2, 0x09); //C_JIT_GAIN_960PMSB1 + pr2100_write_register(ViPipe, 0xb3, 0x6d); //C_JIT_GAIN_960PLSB1 + pr2100_write_register(ViPipe, 0xb4, 0x00); //STD_VPOS_AHD_MSB1 + pr2100_write_register(ViPipe, 0xb5, 0x17); //STD_VPOS_AHD_LSB1 + pr2100_write_register(ViPipe, 0xb6, 0x08); //STD_HPOS_AHD_MSB1 + pr2100_write_register(ViPipe, 0xb7, 0xe8); //STD_HPOS_AHD_LSB1 + pr2100_write_register(ViPipe, 0xb8, 0xb0); //STD_TVI_OFFSET_25F1 + pr2100_write_register(ViPipe, 0xb9, 0xce); //STD_TVI_OFFSET_30F1 + pr2100_write_register(ViPipe, 0xba, 0x90); //STD_TVI_OFFSET_960P1 + pr2100_write_register(ViPipe, 0xbb, 0x00); //EXT_SYNC_CON1 + pr2100_write_register(ViPipe, 0xbc, 0x00); //VOSYNC_HDELAY_MSB1 + pr2100_write_register(ViPipe, 0xbd, 0x04); //VOSYNC_HDELAY_LSB1 + pr2100_write_register(ViPipe, 0xbe, 0x07); //VOSYNC_HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xbf, 0x80); //VOSYNC_HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xc0, 0x00); //VOSYNC_VDELAY_MSB1 + pr2100_write_register(ViPipe, 0xc1, 0x20); //VOSYNC_VDELAY_LSB1 + #if PR2100_SLAVE_TEST_PATTERN + pr2100_write_register(ViPipe, 0xc2, 0x44); + pr2100_write_register(ViPipe, 0xc3, 0x38); + pr2100_write_register(ViPipe, 0xc4, 0x88); + #else + pr2100_write_register(ViPipe, 0xc2, 0x04); //VOSYNC_VACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xc3, 0x38); //VOSYNC_VACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xc4, 0x00); + #endif + pr2100_write_register(ViPipe, 0xc5, 0x00); //MAN_INFMT_ADD_LSB1 + pr2100_write_register(ViPipe, 0xc6, 0x00); //C_PHASE_LOCK_RNG0_1 + pr2100_write_register(ViPipe, 0xc7, 0x00); //C_PHASE_LOCK_RNG1_1 + pr2100_write_register(ViPipe, 0xc8, 0x00); //C_PHASE_LOCK_RNG2_1 + pr2100_write_register(ViPipe, 0xc9, 0x00); //VISYNC_HDELAY_MSB1 + pr2100_write_register(ViPipe, 0xca, 0x04); //VISYNC_HDELAY_LSB1 + pr2100_write_register(ViPipe, 0xcb, 0x07); //VISYNC_HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xcc, 0x80); //VISYNC_HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xcd, 0x08); //VISYNC_VDELAY_MSB1 + pr2100_write_register(ViPipe, 0xce, 0x20); //VISYNC_VDELAY_LSB1 + pr2100_write_register(ViPipe, 0xcf, 0x04); //VISYNC_VACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xd0, 0x38); //VISYNC_VACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xd1, 0x10); //MIPI_DATA_FLD_CON_1 + + pr2100_write_register(ViPipe, 0xFF, 0x06); + pr2100_write_register(ViPipe, 0x04, 0x30); //MIPI_CONTROL_0 +} + +static void pr2100_set_1080p_4ch(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "4CH Master ViPipe=%d\n", ViPipe); + + //chip id : 0x5c-(ch:0)Set vdec [Camera:3(HDA), videoResolution:11(video_1920x1080p25)] + pr2100_write_register(ViPipe, 0xFF, 0x00); + pr2100_write_register(ViPipe, 0x10, 0x83); //MAN_IFMT0 + pr2100_write_register(ViPipe, 0x11, 0x0f); //MAN_EQ_DC_GN0 + pr2100_write_register(ViPipe, 0x12, 0x00); //MAN_EQ_AC_GN0 + pr2100_write_register(ViPipe, 0x13, 0x00); //VADC_EQ_BAND0 + pr2100_write_register(ViPipe, 0x14, 0x21); //VADC_CTRL0_0 + pr2100_write_register(ViPipe, 0x15, 0x44); //VADC_CTRL1_0 + pr2100_write_register(ViPipe, 0x16, 0x0d); //VADC_CTRL2_0 + pr2100_write_register(ViPipe, 0x30, 0x83); //MAN_IFMT1 + pr2100_write_register(ViPipe, 0x31, 0x0f); //MAN_EQ_DC_GN1 + pr2100_write_register(ViPipe, 0x32, 0x00); //MAN_EQ_AC_GN1 + pr2100_write_register(ViPipe, 0x33, 0x00); //VADC_EQ_BAND1 + pr2100_write_register(ViPipe, 0x34, 0x21); //VADC_CTRL0_1 + pr2100_write_register(ViPipe, 0x35, 0x44); //VADC_CTRL1_1 + pr2100_write_register(ViPipe, 0x36, 0x0d); //VADC_CTRL2_1 + pr2100_write_register(ViPipe, 0x80, 0x80); //IRQ_CTRL + pr2100_write_register(ViPipe, 0x81, 0x0e); //IRQ_SYNC_PERIOD + pr2100_write_register(ViPipe, 0x82, 0x0d); //WAKE0_PERIOD + pr2100_write_register(ViPipe, 0x84, 0xf0); //IRQ_NOVID_MD + pr2100_write_register(ViPipe, 0x8a, 0x00); //WAKE1_PERIOD + pr2100_write_register(ViPipe, 0x90, 0x00); //IRQENA_WAKE + pr2100_write_register(ViPipe, 0x91, 0x00); //IRQENA_GPIO + pr2100_write_register(ViPipe, 0x94, 0xff); //IRQCLR_WAKE + pr2100_write_register(ViPipe, 0x95, 0xff); //IRQCLR_GPIO + pr2100_write_register(ViPipe, 0xa0, 0x33); //IRQENA_VFD0 + pr2100_write_register(ViPipe, 0xb0, 0x33); //IRQENA_VFD1 + pr2100_write_register(ViPipe, 0xc0, 0x21); //MPP_CTRL0 + pr2100_write_register(ViPipe, 0xc1, 0x21); //MPP_CTRL1 + pr2100_write_register(ViPipe, 0xc2, 0x21); //MPP_CTRL2 + pr2100_write_register(ViPipe, 0xc3, 0x21); //MPP_CTRL3 + pr2100_write_register(ViPipe, 0xc4, 0x21); //MPP_CTRL4 + pr2100_write_register(ViPipe, 0xc5, 0x21); //MPP_CTRL5 + pr2100_write_register(ViPipe, 0xc6, 0x21); //MPP_CTRL6 + pr2100_write_register(ViPipe, 0xc7, 0x21); //MPP_CTRL7 + pr2100_write_register(ViPipe, 0xc8, 0x21); //MPP_CTRL8 + pr2100_write_register(ViPipe, 0xc9, 0x01); //MPP_CTRL9 + pr2100_write_register(ViPipe, 0xca, 0x01); //MPP_CTRLA + pr2100_write_register(ViPipe, 0xcb, 0x01); //MPP_CTRLB + pr2100_write_register(ViPipe, 0xd0, 0x06); //PLL0_CON0 + pr2100_write_register(ViPipe, 0xd1, 0x23); //PLL0_CON1 + pr2100_write_register(ViPipe, 0xd2, 0x21); //PLL0_CON2 + pr2100_write_register(ViPipe, 0xd3, 0x44); //PLL0_CON3 + pr2100_write_register(ViPipe, 0xd4, 0x06); //PLL1_CON0 + pr2100_write_register(ViPipe, 0xd5, 0x23); //PLL1_CON1 + pr2100_write_register(ViPipe, 0xd6, 0x21); //PLL1_CON2 + pr2100_write_register(ViPipe, 0xd7, 0x44); //PLL1_CON3 + pr2100_write_register(ViPipe, 0xd8, 0x06); //PLL2_CON0 + pr2100_write_register(ViPipe, 0xd9, 0x22); //PLL2_CON1 + pr2100_write_register(ViPipe, 0xda, 0x2c); //PLL2_CON2 + pr2100_write_register(ViPipe, 0xe0, 0x05); //LATCH_EN_CON0 + pr2100_write_register(ViPipe, 0xe1, 0x05); //LATCH_EN_CON1 + pr2100_write_register(ViPipe, 0xe2, 0x00); //OUT_FMT + pr2100_write_register(ViPipe, 0xe3, 0xc4); //CHID_NUM, Y-Cb-Y-Cr + pr2100_write_register(ViPipe, 0xe4, 0x20); //CH_SEL0 + pr2100_write_register(ViPipe, 0xe5, 0x64); //CH_SEL1 + pr2100_write_register(ViPipe, 0xe6, 0x20); //CH_SEL2 + pr2100_write_register(ViPipe, 0xe7, 0x64); //CH_SEL3 + pr2100_write_register(ViPipe, 0xe8, 0x00); //VDCKP_PHASE + pr2100_write_register(ViPipe, 0xe9, 0x00); //VDCKN_PHASE + pr2100_write_register(ViPipe, 0xea, 0x00); //CLK_PWDN + pr2100_write_register(ViPipe, 0xeb, 0x01); //MIPI_DATA_EN + pr2100_write_register(ViPipe, 0xf0, 0x03); //PAR_OE_M + pr2100_write_register(ViPipe, 0xf1, 0xff); //PAR_OE_L + pr2100_write_register(ViPipe, 0xf3, 0x06); //PAD_MPP_CTL + pr2100_write_register(ViPipe, 0xf4, 0x66); //PAD_VD_CTL + + pr2100_write_register(ViPipe, 0xFF, 0x01); + pr2100_write_register(ViPipe, 0x00, 0xe4); //VID_CON0 + pr2100_write_register(ViPipe, 0x01, 0x61); //GAINFIT0 + pr2100_write_register(ViPipe, 0x02, 0x00); //PEDFIT0 + pr2100_write_register(ViPipe, 0x03, 0x56); //CLAMP_CON0 + pr2100_write_register(ViPipe, 0x04, 0x0c); //HPLL_CON0_0 + pr2100_write_register(ViPipe, 0x05, 0x88); //HPLL_CON1_0 + pr2100_write_register(ViPipe, 0x06, 0x04); //HPLL_CON2_0 + pr2100_write_register(ViPipe, 0x07, 0xb2); //HPLL_CON3_0 + pr2100_write_register(ViPipe, 0x08, 0x44); //HPLL_CON4_0 + pr2100_write_register(ViPipe, 0x09, 0x34); //HPLL_CON5_0 + pr2100_write_register(ViPipe, 0x0a, 0x02); //HPLL_CON6_0 + pr2100_write_register(ViPipe, 0x0b, 0x14); //STD_POS0_0 + pr2100_write_register(ViPipe, 0x0c, 0x04); //STD_POS1_0 + pr2100_write_register(ViPipe, 0x0d, 0x08); //STD_POS2_0 + pr2100_write_register(ViPipe, 0x0e, 0x5e); //STD_SLICE0_0 + pr2100_write_register(ViPipe, 0x0f, 0x5e); //STD_SLICE1_0 + pr2100_write_register(ViPipe, 0x10, 0x26); //STD_SLICE2_0 + pr2100_write_register(ViPipe, 0x11, 0x00); //HDELAY_MSB0 + pr2100_write_register(ViPipe, 0x12, 0x87); //HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0x13, 0x24); //HDELAY_LSB0 + pr2100_write_register(ViPipe, 0x14, 0x80); //HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x15, 0x2a); //VDELAY0 + pr2100_write_register(ViPipe, 0x16, 0x38); //VACTIVE0 + pr2100_write_register(ViPipe, 0x17, 0x00); //CBG_DELAY_MSB0 + pr2100_write_register(ViPipe, 0x18, 0x80); //CBG_ACTIVE_MSB0 + pr2100_write_register(ViPipe, 0x19, 0x48); //CBG_DELAY_LSB0 + pr2100_write_register(ViPipe, 0x1a, 0x6c); //CBG_ACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x1b, 0x05); //VSMASK_INV_STRT0 + pr2100_write_register(ViPipe, 0x1c, 0x61); //VSMASK_INV_END0 + pr2100_write_register(ViPipe, 0x1d, 0x07); //CBP_DELAY_MSB0 + pr2100_write_register(ViPipe, 0x1e, 0x7e); //CBP_DELAY_LSB0 + pr2100_write_register(ViPipe, 0x1f, 0x80); //HSCL_ACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x20, 0x80); //CONT0 + pr2100_write_register(ViPipe, 0x21, 0x80); //BRGT0 + pr2100_write_register(ViPipe, 0x22, 0x90); //SAT0 + pr2100_write_register(ViPipe, 0x23, 0x80); //HUE0 + pr2100_write_register(ViPipe, 0x24, 0x80); //CB_GAIN0 + pr2100_write_register(ViPipe, 0x25, 0x80); //CR_GAIN0 + pr2100_write_register(ViPipe, 0x26, 0x84); //CB_OFF0 + pr2100_write_register(ViPipe, 0x27, 0x82); //CR_OFF0 + pr2100_write_register(ViPipe, 0x28, 0x00); //Y_OUT_GAIN0 + pr2100_write_register(ViPipe, 0x29, 0xff); //DOWN_HSCL_MSB0 + pr2100_write_register(ViPipe, 0x2a, 0xff); //DOWN_HSCL_LSB0 + pr2100_write_register(ViPipe, 0x2b, 0x00); //MAN_HSCL_ADD0_0 + pr2100_write_register(ViPipe, 0x2c, 0x00); //MAN_HSCL_ADD1_0 + pr2100_write_register(ViPipe, 0x2d, 0x00); //MAN_HSCL_ADD2_0 + pr2100_write_register(ViPipe, 0x2e, 0x00); //MAN_OUTFMT_ADD0_0 + pr2100_write_register(ViPipe, 0x2f, 0x00); //MAN_OUTFMT_ADD1_0 + pr2100_write_register(ViPipe, 0x30, 0x00); //MAN_OUTFMT_ADD2_0 + pr2100_write_register(ViPipe, 0x31, 0x00); //MAN_COMB_MD0 + pr2100_write_register(ViPipe, 0x32, 0xc0); //COMB_CRL_MD0 + pr2100_write_register(ViPipe, 0x33, 0x14); //COMB_CVBS_CRL0_0 + pr2100_write_register(ViPipe, 0x34, 0x14); //COMB_CVBS_CRL1_0 + pr2100_write_register(ViPipe, 0x35, 0x80); //COMB_CVBS_CRL2_0 + pr2100_write_register(ViPipe, 0x36, 0x80); //COMB_CVBS_CRL3_0 + pr2100_write_register(ViPipe, 0x37, 0xad); //HD_Y_NOTCH_MD0 + pr2100_write_register(ViPipe, 0x38, 0x4b); //HD_COMB_FLT_MD0 + pr2100_write_register(ViPipe, 0x39, 0x08); //Y_DYN_PEAK_GN0 + pr2100_write_register(ViPipe, 0x3a, 0x21); //HD_Y_LPF_MD0 + pr2100_write_register(ViPipe, 0x3b, 0x02); //Y_HPF_CORE_MIN0 + pr2100_write_register(ViPipe, 0x3c, 0x01); //Y_HPF_CORE_STEP0 + pr2100_write_register(ViPipe, 0x3d, 0x23); //CORE_CON0 + pr2100_write_register(ViPipe, 0x3e, 0x05); //MAN_CLPF_MD0 + pr2100_write_register(ViPipe, 0x3f, 0xc8); //HD_CTI_CON0 + pr2100_write_register(ViPipe, 0x40, 0x05); //C_LOOP_CON0_0 + pr2100_write_register(ViPipe, 0x41, 0x55); //C_LOOP_CON1_0 + pr2100_write_register(ViPipe, 0x42, 0x01); //C_LOOP_CON2_0 + pr2100_write_register(ViPipe, 0x43, 0x38); //C_LOOP_CON3_0 + pr2100_write_register(ViPipe, 0x44, 0x6a); //C_HUE_CVI0_0 + pr2100_write_register(ViPipe, 0x45, 0x00); //C_HUE_CVI1_0 + pr2100_write_register(ViPipe, 0x46, 0x14); //C_PHASE_REF0_0 + pr2100_write_register(ViPipe, 0x47, 0xb0); //C_PHASE_REF1_0 + pr2100_write_register(ViPipe, 0x48, 0xdf); //C_PHASE_REF2_0 + pr2100_write_register(ViPipe, 0x49, 0x00); //G_GAIN_REF0_0 + pr2100_write_register(ViPipe, 0x4a, 0x7b); //G_GAIN_REF1_0 + pr2100_write_register(ViPipe, 0x4b, 0x60); //MAN_C_GAIN_VAL0_0 + pr2100_write_register(ViPipe, 0x4c, 0x00); //MAN_C_GAIN_VAL1_0 + pr2100_write_register(ViPipe, 0x4d, 0x26); //YC_DELAY0 + pr2100_write_register(ViPipe, 0x4e, 0x00); //HD_HALF_MD0 + pr2100_write_register(ViPipe, 0x4f, 0x2c); //OUTFMT_CON0 + pr2100_write_register(ViPipe, 0x50, 0x21); //TST_EQ_POS0_0 + pr2100_write_register(ViPipe, 0x51, 0x28); //TST_EQ_POS1_0 + pr2100_write_register(ViPipe, 0x52, 0x40); //TST_EQ_POS2_0 + pr2100_write_register(ViPipe, 0x53, 0x0c); //TST_VID_DEC0 + pr2100_write_register(ViPipe, 0x54, 0x0f); //TST_VID_RST0 + pr2100_write_register(ViPipe, 0x55, 0x8d); //PTZ_SLICE_LVL0 + pr2100_write_register(ViPipe, 0x70, 0x06); //COMB_VCRL_VTH1_0 + pr2100_write_register(ViPipe, 0x71, 0x08); //COMB_VCRL_VTH2_0 + pr2100_write_register(ViPipe, 0x72, 0x0a); //COMB_VCRL_VTH3_0 + pr2100_write_register(ViPipe, 0x73, 0x0c); //COMB_VCRL_VTH4_0 + pr2100_write_register(ViPipe, 0x74, 0x0e); //COMB_VCRL_VTH5_0 + pr2100_write_register(ViPipe, 0x75, 0x10); //COMB_VCRL_VTH6_0 + pr2100_write_register(ViPipe, 0x76, 0x12); //COMB_VCRL_VTH7_0 + pr2100_write_register(ViPipe, 0x77, 0x14); //COMB_VCRL_VTH8_0 + pr2100_write_register(ViPipe, 0x78, 0x06); //COMB_VMIX_VTH1_0 + pr2100_write_register(ViPipe, 0x79, 0x08); //COMB_VMIX_VTH2_0 + pr2100_write_register(ViPipe, 0x7a, 0x0a); //COMB_VMIX_VTH3_0 + pr2100_write_register(ViPipe, 0x7b, 0x0c); //COMB_VMIX_VTH4_0 + pr2100_write_register(ViPipe, 0x7c, 0x0e); //COMB_VMIX_VTH5_0 + pr2100_write_register(ViPipe, 0x7d, 0x10); //COMB_VMIX_VTH6_0 + pr2100_write_register(ViPipe, 0x7e, 0x12); //COMB_VMIX_VTH7_0 + pr2100_write_register(ViPipe, 0x7f, 0x14); //COMB_VMIX_VTH8_0 + pr2100_write_register(ViPipe, 0x80, 0x00); //STD_VPOS_PVI_960MSB0 + pr2100_write_register(ViPipe, 0x81, 0x09); //STD_VPOS_PVI_960LSB0 + pr2100_write_register(ViPipe, 0x82, 0x00); //STD_VPOS_CVI_960MSB0 + pr2100_write_register(ViPipe, 0x83, 0x07); //STD_VPOS_CVI_960LSB0 + pr2100_write_register(ViPipe, 0x84, 0x00); //STD_VPOS_AHD_960MSB0 + pr2100_write_register(ViPipe, 0x85, 0x17); //STD_VPOS_AHD_960LSB0 + pr2100_write_register(ViPipe, 0x86, 0x03); //STD_VPOS_TVI_960MSB0 + pr2100_write_register(ViPipe, 0x87, 0xe5); //STD_VPOS_TVI_960LSB0 + pr2100_write_register(ViPipe, 0x88, 0x05); //STD_HPOS_PVI_960MSB0 + pr2100_write_register(ViPipe, 0x89, 0x24); //STD_HPOS_PVI_960LSB0 + pr2100_write_register(ViPipe, 0x8a, 0x05); //STD_HPOS_CVI_960MSB0 + pr2100_write_register(ViPipe, 0x8b, 0x24); //STD_HPOS_CVI_960LSB0 + pr2100_write_register(ViPipe, 0x8c, 0x08); //STD_HPOS_AHD_960MSB0 + pr2100_write_register(ViPipe, 0x8d, 0xe8); //STD_HPOS_AHD_960LSB0 + pr2100_write_register(ViPipe, 0x8e, 0x05); //STD_HPOS_TVI_960MSB0 + pr2100_write_register(ViPipe, 0x8f, 0x47); //STD_HPOS_TVI_960LSB0 + pr2100_write_register(ViPipe, 0x90, 0x02); //VSYNC_ACCUM_960MSB0 + pr2100_write_register(ViPipe, 0x91, 0xb4); //VSYNC_ACCUM_960LSB0 + pr2100_write_register(ViPipe, 0x92, 0x73); //VLINE_MAX_960_MSB0 + pr2100_write_register(ViPipe, 0x93, 0xe8); //VLINE_MAX_960_LSB0 + pr2100_write_register(ViPipe, 0x94, 0x0f); //SLICE_VSYNC0 + pr2100_write_register(ViPipe, 0x95, 0x5e); //STD_SLICE_AHD0 + pr2100_write_register(ViPipe, 0x96, 0x03); //HACT_SIZE_960_MSB0 + pr2100_write_register(ViPipe, 0x97, 0xd0); //HACT_SIZE_960_LSB0 + pr2100_write_register(ViPipe, 0x98, 0x17); //HPERIOD_960P25MSB0 + pr2100_write_register(ViPipe, 0x99, 0x34); //HPERIOD_960P25LSB0 + pr2100_write_register(ViPipe, 0x9a, 0x13); //HPERIOD_960P30MSB0 + pr2100_write_register(ViPipe, 0x9b, 0x56); //HPERIOD_960P30LSB0 + pr2100_write_register(ViPipe, 0x9c, 0x0b); //HPERIOD_960P50MSB0 + pr2100_write_register(ViPipe, 0x9d, 0x9a); //HPERIOD_960P50LSB0 + pr2100_write_register(ViPipe, 0x9e, 0x09); //HPERIOD_960P60MSB0 + pr2100_write_register(ViPipe, 0x9f, 0xab); //HPERIOD_960P60LSB0 + pr2100_write_register(ViPipe, 0xa0, 0x01); //VALY_STRT_960P25MSB0 + pr2100_write_register(ViPipe, 0xa1, 0x74); //VALY_STRT_960P25LSB0 + pr2100_write_register(ViPipe, 0xa2, 0x01); //VALY_STRT_960P30MSB0 + pr2100_write_register(ViPipe, 0xa3, 0x6b); //VALY_STRT_960P30LSB0 + pr2100_write_register(ViPipe, 0xa4, 0x00); //VALY_STRT_960P50MSB0 + pr2100_write_register(ViPipe, 0xa5, 0xba); //VALY_STRT_960P50LSB0 + pr2100_write_register(ViPipe, 0xa6, 0x00); //VALY_STRT_960P60MSB0 + pr2100_write_register(ViPipe, 0xa7, 0xa3); //VALY_STRT_960P60LSB0 + pr2100_write_register(ViPipe, 0xa8, 0x01); //PED_STRT_960P25MSB0 + pr2100_write_register(ViPipe, 0xa9, 0x39); //PED_STRT_960P25LSB0 + pr2100_write_register(ViPipe, 0xaa, 0x01); //PED_STRT_960P30MSB0 + pr2100_write_register(ViPipe, 0xab, 0x39); //PED_STRT_960P30LSB0 + pr2100_write_register(ViPipe, 0xac, 0x00); //PED_STRT_960P50MSB0 + pr2100_write_register(ViPipe, 0xad, 0xc1); //PED_STRT_960P50LSB0 + pr2100_write_register(ViPipe, 0xae, 0x00); //PED_STRT_960P60MSB0 + pr2100_write_register(ViPipe, 0xaf, 0xc1); //PED_STRT_960P60LSB0 + pr2100_write_register(ViPipe, 0xb0, 0x05); //COMB_MEM_960PMSB0 + pr2100_write_register(ViPipe, 0xb1, 0xcc); //COMB_MEM_960PLSB0 + pr2100_write_register(ViPipe, 0xb2, 0x09); //C_JIT_GAIN_960PMSB0 + pr2100_write_register(ViPipe, 0xb3, 0x6d); //C_JIT_GAIN_960PLSB0 + pr2100_write_register(ViPipe, 0xb4, 0x00); //STD_VPOS_AHD_MSB0 + pr2100_write_register(ViPipe, 0xb5, 0x17); //STD_VPOS_AHD_LSB0 + pr2100_write_register(ViPipe, 0xb6, 0x08); //STD_HPOS_AHD_MSB0 + pr2100_write_register(ViPipe, 0xb7, 0xe8); //STD_HPOS_AHD_LSB0 + pr2100_write_register(ViPipe, 0xb8, 0xb0); //STD_TVI_OFFSET_25F0 + pr2100_write_register(ViPipe, 0xb9, 0xce); //STD_TVI_OFFSET_30F0 + pr2100_write_register(ViPipe, 0xba, 0x90); //STD_TVI_OFFSET_960P0 + pr2100_write_register(ViPipe, 0xbb, 0x00); //EXT_SYNC_CON0 + pr2100_write_register(ViPipe, 0xbc, 0x00); //VOSYNC_HDELAY_MSB0 + pr2100_write_register(ViPipe, 0xbd, 0x04); //VOSYNC_HDELAY_LSB0 + pr2100_write_register(ViPipe, 0xbe, 0x07); //VOSYNC_HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xbf, 0x80); //VOSYNC_HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xc0, 0x00); //VOSYNC_VDELAY_MSB0 + pr2100_write_register(ViPipe, 0xc1, 0x00); //VOSYNC_VDELAY_LSB0 + #if PR2100_TEST_PATTERN + pr2100_write_register(ViPipe, 0xc2, 0x44); + pr2100_write_register(ViPipe, 0xc3, 0x38); + #else + pr2100_write_register(ViPipe, 0xc2, 0x04); //VOSYNC_VACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xc3, 0x39); //VOSYNC_VACTIVE_LSB0 + #endif + pr2100_write_register(ViPipe, 0xc4, output_pattern_ch0); + pr2100_write_register(ViPipe, 0xc9, 0x00); //VISYNC_HDELAY_MSB0 + pr2100_write_register(ViPipe, 0xca, 0x02); //VISYNC_HDELAY_LSB0 + pr2100_write_register(ViPipe, 0xcb, 0x07); //VISYNC_HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xcc, 0x80); //VISYNC_HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xcd, 0x08); //VISYNC_VDELAY_MSB0 + pr2100_write_register(ViPipe, 0xce, 0x20); //VISYNC_VDELAY_LSB0 + pr2100_write_register(ViPipe, 0xcf, 0x04); //VISYNC_VACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xd0, 0x38); //VISYNC_VACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xd1, 0x10); //MIPI_DATA_FLD_CON_0 + pr2100_write_register(ViPipe, 0xd2, 0x00); //MIPI_DATA_ODD_VAL_0 + pr2100_write_register(ViPipe, 0xd3, 0x00); //MIPI_DATA_EVEN_VAL_0 + #if PR2100_TEST_PATTERN + pr2100_write_register(ViPipe, 0xcf, 0x8c); //VISYNC_VACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xd0, 0x38); //VISYNC_VACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xcd, 0x40); //VISYNC_VDELAY_MSB0 + #endif + pr2100_write_register(ViPipe, 0xFF, 0x02); + pr2100_write_register(ViPipe, 0x00, 0xe4); //VID_CON1 + pr2100_write_register(ViPipe, 0x01, 0x61); //GAINFIT1 + pr2100_write_register(ViPipe, 0x02, 0x00); //PEDFIT1 + pr2100_write_register(ViPipe, 0x03, 0x56); //CLAMP_CON1 + pr2100_write_register(ViPipe, 0x04, 0x0c); //HPLL_CON0_1 + pr2100_write_register(ViPipe, 0x05, 0x88); //HPLL_CON1_1 + pr2100_write_register(ViPipe, 0x06, 0x04); //HPLL_CON2_1 + pr2100_write_register(ViPipe, 0x07, 0xb2); //HPLL_CON3_1 + pr2100_write_register(ViPipe, 0x08, 0x44); //HPLL_CON4_1 + pr2100_write_register(ViPipe, 0x09, 0x34); //HPLL_CON5_1 + pr2100_write_register(ViPipe, 0x0a, 0x02); //HPLL_CON6_1 + pr2100_write_register(ViPipe, 0x0b, 0x14); //STD_POS0_1 + pr2100_write_register(ViPipe, 0x0c, 0x04); //STD_POS1_1 + pr2100_write_register(ViPipe, 0x0d, 0x08); //STD_POS2_1 + pr2100_write_register(ViPipe, 0x0e, 0x5e); //STD_SLICE0_1 + pr2100_write_register(ViPipe, 0x0f, 0x5e); //STD_SLICE1_1 + pr2100_write_register(ViPipe, 0x10, 0x26); //STD_SLICE2_1 + pr2100_write_register(ViPipe, 0x11, 0x00); //HDELAY_MSB1 + pr2100_write_register(ViPipe, 0x12, 0x87); //HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0x13, 0x24); //HDELAY_LSB1 + pr2100_write_register(ViPipe, 0x14, 0x80); //HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x15, 0x2a); //VDELAY1 + pr2100_write_register(ViPipe, 0x16, 0x38); //VACTIVE1 + pr2100_write_register(ViPipe, 0x17, 0x00); //CBG_DELAY_MSB1 + pr2100_write_register(ViPipe, 0x18, 0x80); //CBG_ACTIVE_MSB1 + pr2100_write_register(ViPipe, 0x19, 0x48); //CBG_DELAY_LSB1 + pr2100_write_register(ViPipe, 0x1a, 0x6c); //CBG_ACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x1b, 0x05); //VSMASK_INV_STRT1 + pr2100_write_register(ViPipe, 0x1c, 0x61); //VSMASK_INV_END1 + pr2100_write_register(ViPipe, 0x1d, 0x07); //CBP_DELAY_MSB1 + pr2100_write_register(ViPipe, 0x1e, 0x7e); //CBP_DELAY_LSB1 + pr2100_write_register(ViPipe, 0x1f, 0x80); //HSCL_ACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x20, 0x80); //CONT1 + pr2100_write_register(ViPipe, 0x21, 0x80); //BRGT1 + pr2100_write_register(ViPipe, 0x22, 0x90); //SAT1 + pr2100_write_register(ViPipe, 0x23, 0x80); //HUE1 + pr2100_write_register(ViPipe, 0x24, 0x80); //CB_GAIN1 + pr2100_write_register(ViPipe, 0x25, 0x80); //CR_GAIN1 + pr2100_write_register(ViPipe, 0x26, 0x84); //CB_OFF1 + pr2100_write_register(ViPipe, 0x27, 0x82); //CR_OFF1 + pr2100_write_register(ViPipe, 0x28, 0x00); //Y_OUT_GAIN1 + pr2100_write_register(ViPipe, 0x29, 0xff); //DOWN_HSCL_MSB1 + pr2100_write_register(ViPipe, 0x2a, 0xff); //DOWN_HSCL_LSB1 + pr2100_write_register(ViPipe, 0x2b, 0x00); //MAN_HSCL_ADD0_1 + pr2100_write_register(ViPipe, 0x2c, 0x00); //MAN_HSCL_ADD1_1 + pr2100_write_register(ViPipe, 0x2d, 0x00); //MAN_HSCL_ADD2_1 + pr2100_write_register(ViPipe, 0x2e, 0x00); //MAN_OUTFMT_ADD0_1 + pr2100_write_register(ViPipe, 0x2f, 0x00); //MAN_OUTFMT_ADD1_1 + pr2100_write_register(ViPipe, 0x30, 0x00); //MAN_OUTFMT_ADD2_1 + pr2100_write_register(ViPipe, 0x31, 0x00); //MAN_COMB_MD1 + pr2100_write_register(ViPipe, 0x32, 0xc0); //COMB_CRL_MD1 + pr2100_write_register(ViPipe, 0x33, 0x14); //COMB_CVBS_CRL0_1 + pr2100_write_register(ViPipe, 0x34, 0x14); //COMB_CVBS_CRL1_1 + pr2100_write_register(ViPipe, 0x35, 0x80); //COMB_CVBS_CRL2_1 + pr2100_write_register(ViPipe, 0x36, 0x80); //COMB_CVBS_CRL3_1 + pr2100_write_register(ViPipe, 0x37, 0xad); //HD_Y_NOTCH_MD1 + pr2100_write_register(ViPipe, 0x38, 0x4b); //HD_COMB_FLT_MD1 + pr2100_write_register(ViPipe, 0x39, 0x08); //Y_DYN_PEAK_GN1 + pr2100_write_register(ViPipe, 0x3a, 0x21); //HD_Y_LPF_MD1 + pr2100_write_register(ViPipe, 0x3b, 0x02); //Y_HPF_CORE_MIN1 + pr2100_write_register(ViPipe, 0x3c, 0x01); //Y_HPF_CORE_STEP1 + pr2100_write_register(ViPipe, 0x3d, 0x23); //CORE_CON1 + pr2100_write_register(ViPipe, 0x3e, 0x05); //MAN_CLPF_MD1 + pr2100_write_register(ViPipe, 0x3f, 0xc8); //HD_CTI_CON1 + pr2100_write_register(ViPipe, 0x40, 0x05); //C_LOOP_CON0_1 + pr2100_write_register(ViPipe, 0x41, 0x55); //C_LOOP_CON1_1 + pr2100_write_register(ViPipe, 0x42, 0x01); //C_LOOP_CON2_1 + pr2100_write_register(ViPipe, 0x43, 0x38); //C_LOOP_CON3_1 + pr2100_write_register(ViPipe, 0x44, 0x6a); //C_HUE_CVI0_1 + pr2100_write_register(ViPipe, 0x45, 0x00); //C_HUE_CVI1_1 + pr2100_write_register(ViPipe, 0x46, 0x14); //C_PHASE_REF0_1 + pr2100_write_register(ViPipe, 0x47, 0xb0); //C_PHASE_REF1_1 + pr2100_write_register(ViPipe, 0x48, 0xdf); //C_PHASE_REF2_1 + pr2100_write_register(ViPipe, 0x49, 0x00); //G_GAIN_REF0_1 + pr2100_write_register(ViPipe, 0x4a, 0x7b); //G_GAIN_REF1_1 + pr2100_write_register(ViPipe, 0x4b, 0x60); //MAN_C_GAIN_VAL0_1 + pr2100_write_register(ViPipe, 0x4c, 0x00); //MAN_C_GAIN_VAL1_1 + pr2100_write_register(ViPipe, 0x4d, 0x26); //YC_DELAY1 + pr2100_write_register(ViPipe, 0x4e, 0x00); //HD_HALF_MD1 + pr2100_write_register(ViPipe, 0x4f, 0x2c); //OUTFMT_CON1 + pr2100_write_register(ViPipe, 0x50, 0x21); //TST_EQ_POS0_1 + pr2100_write_register(ViPipe, 0x51, 0x28); //TST_EQ_POS1_1 + pr2100_write_register(ViPipe, 0x52, 0x40); //TST_EQ_POS2_1 + pr2100_write_register(ViPipe, 0x53, 0x0c); //TST_VID_DEC1 + pr2100_write_register(ViPipe, 0x54, 0x0f); //TST_VID_RST1 + pr2100_write_register(ViPipe, 0x55, 0x8d); //PTZ_SLICE_LVL1 + pr2100_write_register(ViPipe, 0x70, 0x06); //COMB_VCRL_VTH1_1 + pr2100_write_register(ViPipe, 0x71, 0x08); //COMB_VCRL_VTH2_1 + pr2100_write_register(ViPipe, 0x72, 0x0a); //COMB_VCRL_VTH3_1 + pr2100_write_register(ViPipe, 0x73, 0x0c); //COMB_VCRL_VTH4_1 + pr2100_write_register(ViPipe, 0x74, 0x0e); //COMB_VCRL_VTH5_1 + pr2100_write_register(ViPipe, 0x75, 0x10); //COMB_VCRL_VTH6_1 + pr2100_write_register(ViPipe, 0x76, 0x12); //COMB_VCRL_VTH7_1 + pr2100_write_register(ViPipe, 0x77, 0x14); //COMB_VCRL_VTH8_1 + pr2100_write_register(ViPipe, 0x78, 0x06); //COMB_VMIX_VTH1_1 + pr2100_write_register(ViPipe, 0x79, 0x08); //COMB_VMIX_VTH2_1 + pr2100_write_register(ViPipe, 0x7a, 0x0a); //COMB_VMIX_VTH3_1 + pr2100_write_register(ViPipe, 0x7b, 0x0c); //COMB_VMIX_VTH4_1 + pr2100_write_register(ViPipe, 0x7c, 0x0e); //COMB_VMIX_VTH5_1 + pr2100_write_register(ViPipe, 0x7d, 0x10); //COMB_VMIX_VTH6_1 + pr2100_write_register(ViPipe, 0x7e, 0x12); //COMB_VMIX_VTH7_1 + pr2100_write_register(ViPipe, 0x7f, 0x14); //COMB_VMIX_VTH8_1 + pr2100_write_register(ViPipe, 0x80, 0x00); //STD_VPOS_PVI_960MSB1 + pr2100_write_register(ViPipe, 0x81, 0x09); //STD_VPOS_PVI_960LSB1 + pr2100_write_register(ViPipe, 0x82, 0x00); //STD_VPOS_CVI_960MSB1 + pr2100_write_register(ViPipe, 0x83, 0x07); //STD_VPOS_CVI_960LSB1 + pr2100_write_register(ViPipe, 0x84, 0x00); //STD_VPOS_AHD_960MSB1 + pr2100_write_register(ViPipe, 0x85, 0x17); //STD_VPOS_AHD_960LSB1 + pr2100_write_register(ViPipe, 0x86, 0x03); //STD_VPOS_TVI_960MSB1 + pr2100_write_register(ViPipe, 0x87, 0xe5); //STD_VPOS_TVI_960LSB1 + pr2100_write_register(ViPipe, 0x88, 0x05); //STD_HPOS_PVI_960MSB1 + pr2100_write_register(ViPipe, 0x89, 0x24); //STD_HPOS_PVI_960LSB1 + pr2100_write_register(ViPipe, 0x8a, 0x05); //STD_HPOS_CVI_960MSB1 + pr2100_write_register(ViPipe, 0x8b, 0x24); //STD_HPOS_CVI_960LSB1 + pr2100_write_register(ViPipe, 0x8c, 0x08); //STD_HPOS_AHD_960MSB1 + pr2100_write_register(ViPipe, 0x8d, 0xe8); //STD_HPOS_AHD_960LSB1 + pr2100_write_register(ViPipe, 0x8e, 0x05); //STD_HPOS_TVI_960MSB1 + pr2100_write_register(ViPipe, 0x8f, 0x47); //STD_HPOS_TVI_960LSB1 + pr2100_write_register(ViPipe, 0x90, 0x02); //VSYNC_ACCUM_960MSB1 + pr2100_write_register(ViPipe, 0x91, 0xb4); //VSYNC_ACCUM_960LSB1 + pr2100_write_register(ViPipe, 0x92, 0x73); //VLINE_MAX_960_MSB1 + pr2100_write_register(ViPipe, 0x93, 0xe8); //VLINE_MAX_960_LSB1 + pr2100_write_register(ViPipe, 0x94, 0x0f); //SLICE_VSYNC1 + pr2100_write_register(ViPipe, 0x95, 0x5e); //STD_SLICE_AHD1 + pr2100_write_register(ViPipe, 0x96, 0x03); //HACT_SIZE_960_MSB1 + pr2100_write_register(ViPipe, 0x97, 0xd0); //HACT_SIZE_960_LSB1 + pr2100_write_register(ViPipe, 0x98, 0x17); //HPERIOD_960P25MSB1 + pr2100_write_register(ViPipe, 0x99, 0x34); //HPERIOD_960P25LSB1 + pr2100_write_register(ViPipe, 0x9a, 0x13); //HPERIOD_960P30MSB1 + pr2100_write_register(ViPipe, 0x9b, 0x56); //HPERIOD_960P30LSB1 + pr2100_write_register(ViPipe, 0x9c, 0x0b); //HPERIOD_960P50MSB1 + pr2100_write_register(ViPipe, 0x9d, 0x9a); //HPERIOD_960P50LSB1 + pr2100_write_register(ViPipe, 0x9e, 0x09); //HPERIOD_960P60MSB1 + pr2100_write_register(ViPipe, 0x9f, 0xab); //HPERIOD_960P60LSB1 + pr2100_write_register(ViPipe, 0xa0, 0x01); //VALY_STRT_960P25MSB1 + pr2100_write_register(ViPipe, 0xa1, 0x74); //VALY_STRT_960P25LSB1 + pr2100_write_register(ViPipe, 0xa2, 0x01); //VALY_STRT_960P30MSB1 + pr2100_write_register(ViPipe, 0xa3, 0x6b); //VALY_STRT_960P30LSB1 + pr2100_write_register(ViPipe, 0xa4, 0x00); //VALY_STRT_960P50MSB1 + pr2100_write_register(ViPipe, 0xa5, 0xba); //VALY_STRT_960P50LSB1 + pr2100_write_register(ViPipe, 0xa6, 0x00); //VALY_STRT_960P60MSB1 + pr2100_write_register(ViPipe, 0xa7, 0xa3); //VALY_STRT_960P60LSB1 + pr2100_write_register(ViPipe, 0xa8, 0x01); //PED_STRT_960P25MSB1 + pr2100_write_register(ViPipe, 0xa9, 0x39); //PED_STRT_960P25LSB1 + pr2100_write_register(ViPipe, 0xaa, 0x01); //PED_STRT_960P30MSB1 + pr2100_write_register(ViPipe, 0xab, 0x39); //PED_STRT_960P30LSB1 + pr2100_write_register(ViPipe, 0xac, 0x00); //PED_STRT_960P50MSB1 + pr2100_write_register(ViPipe, 0xad, 0xc1); //PED_STRT_960P50LSB1 + pr2100_write_register(ViPipe, 0xae, 0x00); //PED_STRT_960P60MSB1 + pr2100_write_register(ViPipe, 0xaf, 0xc1); //PED_STRT_960P60LSB1 + pr2100_write_register(ViPipe, 0xb0, 0x05); //COMB_MEM_960PMSB1 + pr2100_write_register(ViPipe, 0xb1, 0xcc); //COMB_MEM_960PLSB1 + pr2100_write_register(ViPipe, 0xb2, 0x09); //C_JIT_GAIN_960PMSB1 + pr2100_write_register(ViPipe, 0xb3, 0x6d); //C_JIT_GAIN_960PLSB1 + pr2100_write_register(ViPipe, 0xb4, 0x00); //STD_VPOS_AHD_MSB1 + pr2100_write_register(ViPipe, 0xb5, 0x17); //STD_VPOS_AHD_LSB1 + pr2100_write_register(ViPipe, 0xb6, 0x08); //STD_HPOS_AHD_MSB1 + pr2100_write_register(ViPipe, 0xb7, 0xe8); //STD_HPOS_AHD_LSB1 + pr2100_write_register(ViPipe, 0xb8, 0xb0); //STD_TVI_OFFSET_25F1 + pr2100_write_register(ViPipe, 0xb9, 0xce); //STD_TVI_OFFSET_30F1 + pr2100_write_register(ViPipe, 0xba, 0x90); //STD_TVI_OFFSET_960P1 + pr2100_write_register(ViPipe, 0xbb, 0x00); //EXT_SYNC_CON1 + pr2100_write_register(ViPipe, 0xbc, 0x00); //VOSYNC_HDELAY_MSB1 + pr2100_write_register(ViPipe, 0xbd, 0x04); //VOSYNC_HDELAY_LSB1 + pr2100_write_register(ViPipe, 0xbe, 0x07); //VOSYNC_HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xbf, 0x80); //VOSYNC_HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xc0, 0x00); //VOSYNC_VDELAY_MSB1 + pr2100_write_register(ViPipe, 0xc1, 0x00); //VOSYNC_VDELAY_LSB1 + #if PR2100_TEST_PATTERN + pr2100_write_register(ViPipe, 0xc2, 0x44); + pr2100_write_register(ViPipe, 0xc3, 0x38); + #else + pr2100_write_register(ViPipe, 0xc2, 0x04); //VOSYNC_VACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xc3, 0x39); //VOSYNC_VACTIVE_LSB1 + #endif + pr2100_write_register(ViPipe, 0xc4, output_pattern_ch1); + pr2100_write_register(ViPipe, 0xc9, 0x00); //VISYNC_HDELAY_MSB1 + pr2100_write_register(ViPipe, 0xca, 0x02); //VISYNC_HDELAY_LSB1 + pr2100_write_register(ViPipe, 0xcb, 0x07); //VISYNC_HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xcc, 0x80); //VISYNC_HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xcd, 0x08); //VISYNC_VDELAY_MSB1 + pr2100_write_register(ViPipe, 0xce, 0x20); //VISYNC_VDELAY_LSB1 + pr2100_write_register(ViPipe, 0xcf, 0x04); //VISYNC_VACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xd0, 0x38); //VISYNC_VACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xd1, 0x10); //MIPI_DATA_FLD_CON_1 + pr2100_write_register(ViPipe, 0xd2, 0x00); //MIPI_DATA_ODD_VAL_1 + pr2100_write_register(ViPipe, 0xd3, 0x00); //MIPI_DATA_EVEN_VAL_1 + #if PR2100_TEST_PATTERN + pr2100_write_register(ViPipe, 0xcf, 0x8c); //VISYNC_VACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xd0, 0x38); //VISYNC_VACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xcd, 0x40); //VISYNC_VDELAY_MSB0 + #endif + pr2100_write_register(ViPipe, 0xFF, 0x05); + pr2100_write_register(ViPipe, 0x09, 0x00); //REF_CH_STRT + pr2100_write_register(ViPipe, 0x0a, 0x03); //REF_CH_VDLY + pr2100_write_register(ViPipe, 0x0e, 0x80); //VBLK_CODE + pr2100_write_register(ViPipe, 0x0f, 0x10); //VBLK_CODE + pr2100_write_register(ViPipe, 0x10, 0xb3); //MTX_CTRL + pr2100_write_register(ViPipe, 0x11, 0xb0); //MTX_LONG_DLY_H + pr2100_write_register(ViPipe, 0x12, 0x6e); //MTX_LONG_DLY_L + pr2100_write_register(ViPipe, 0x13, 0x00); //MTX_SHORT_DLY_H + pr2100_write_register(ViPipe, 0x14, 0x6e); //MTX_SHORT_DLY_L + pr2100_write_register(ViPipe, 0x15, 0x00); //REF_OFFSET + pr2100_write_register(ViPipe, 0x16, 0x00); //REF_FE_HDLY + pr2100_write_register(ViPipe, 0x17, 0x00); //REF_FE_HDLY + pr2100_write_register(ViPipe, 0x18, 0x00); //REF_FS_HDLY + pr2100_write_register(ViPipe, 0x19, 0x00); //REF_FS_HDLY + pr2100_write_register(ViPipe, 0x1a, 0x00); //REF_HTOTAL + pr2100_write_register(ViPipe, 0x1b, 0x00); //REF_HTOTAL + pr2100_write_register(ViPipe, 0x1c, 0x00); //REF_VTOTAL + pr2100_write_register(ViPipe, 0x1d, 0x00); //REF_VTOTAL + pr2100_write_register(ViPipe, 0x1e, 0x00); //CHID_MD + pr2100_write_register(ViPipe, 0x20, 0x88); //MTX_CH0_CTRL + pr2100_write_register(ViPipe, 0x21, 0x07); //MTX_CH0_HSIZE + pr2100_write_register(ViPipe, 0x22, 0x80); //MTX_CH0_HSIZE + pr2100_write_register(ViPipe, 0x23, 0x04); //MTX_CH0_VSIZE + pr2100_write_register(ViPipe, 0x24, 0x38); //MTX_CH0_VSIZE + pr2100_write_register(ViPipe, 0x25, 0x0f); //CH0_FS_OS_H + pr2100_write_register(ViPipe, 0x26, 0x00); //CH0_FS_OS_L + pr2100_write_register(ViPipe, 0x27, 0x0f); //CH0_FE_OS_H + pr2100_write_register(ViPipe, 0x28, 0x00); //CH0_FE_OS_L + pr2100_write_register(ViPipe, 0x29, 0x0b); //REF_CH0_VS_OS + pr2100_write_register(ViPipe, 0x2a, 0x40); //REF_CH0_VS_OS + pr2100_write_register(ViPipe, 0x30, 0x98); //MTX_CH1_CTRL + pr2100_write_register(ViPipe, 0x31, 0x07); //MTX_CH1_HSIZE + pr2100_write_register(ViPipe, 0x32, 0x80); //MTX_CH1_HSIZE + pr2100_write_register(ViPipe, 0x33, 0x04); //MTX_CH1_VSIZE + pr2100_write_register(ViPipe, 0x34, 0x38); //MTX_CH1_VSIZE + pr2100_write_register(ViPipe, 0x35, 0x0f); //CH1_FS_OS_H + pr2100_write_register(ViPipe, 0x36, 0x00); //CH1_FS_OS_L + pr2100_write_register(ViPipe, 0x37, 0x0f); //CH1_FE_OS_H + pr2100_write_register(ViPipe, 0x38, 0x00); //CH1_FE_OS_L + pr2100_write_register(ViPipe, 0x39, 0x07); //REF_CH1_VS_OS + pr2100_write_register(ViPipe, 0x3a, 0x80); //REF_CH1_VS_OS + pr2100_write_register(ViPipe, 0x40, 0xa8); //MTX_CH2_CTRL + pr2100_write_register(ViPipe, 0x41, 0x07); //MTX_CH2_HSIZE + pr2100_write_register(ViPipe, 0x42, 0x80); //MTX_CH2_HSIZE + pr2100_write_register(ViPipe, 0x43, 0x04); //MTX_CH2_VSIZE + pr2100_write_register(ViPipe, 0x44, 0x38); //MTX_CH2_VSIZE + pr2100_write_register(ViPipe, 0x45, 0x0f); //CH2_FS_OS_H + pr2100_write_register(ViPipe, 0x46, 0x00); //CH2_FS_OS_L + pr2100_write_register(ViPipe, 0x47, 0x0f); //CH2_FE_OS_H + pr2100_write_register(ViPipe, 0x48, 0x00); //CH2_FE_OS_L + pr2100_write_register(ViPipe, 0x49, 0x03); //REF_CH2_VS_OS + pr2100_write_register(ViPipe, 0x4a, 0xc0); //REF_CH2_VS_OS + pr2100_write_register(ViPipe, 0x50, 0xb8); //MTX_CH3_CTRL + pr2100_write_register(ViPipe, 0x51, 0x07); //MTX_CH3_HSIZE + pr2100_write_register(ViPipe, 0x52, 0x80); //MTX_CH3_HSIZE + pr2100_write_register(ViPipe, 0x53, 0x04); //MTX_CH3_VSIZE + pr2100_write_register(ViPipe, 0x54, 0x38); //MTX_CH3_VSIZE + pr2100_write_register(ViPipe, 0x55, 0x0f); //CH3_FS_OS_H + pr2100_write_register(ViPipe, 0x56, 0x00); //CH3_FS_OS_L + pr2100_write_register(ViPipe, 0x57, 0x0f); //CH3_FE_OS_H + pr2100_write_register(ViPipe, 0x58, 0x00); //CH3_FE_OS_L + pr2100_write_register(ViPipe, 0x59, 0x00); //REF_CH3_VS_OS + pr2100_write_register(ViPipe, 0x5a, 0x00); //REF_CH3_VS_OS + pr2100_write_register(ViPipe, 0x60, 0x05); //CH0_HWIDTH[13:8] + pr2100_write_register(ViPipe, 0x61, 0x28); //CH0_HWIDTH [7:0] + pr2100_write_register(ViPipe, 0x62, 0x05); //CH1_HWIDTH[13:8] + pr2100_write_register(ViPipe, 0x63, 0x28); //CH1_HWIDTH [7:0] + pr2100_write_register(ViPipe, 0x64, 0x05); //CH2_HWIDTH[13:8] + pr2100_write_register(ViPipe, 0x65, 0x28); //CH2_HWIDTH [7:0] + pr2100_write_register(ViPipe, 0x66, 0x05); //CH3_HWIDTH[13:8] + pr2100_write_register(ViPipe, 0x67, 0x28); //CH3_HWIDTH [7:0] + pr2100_write_register(ViPipe, 0x68, 0xff); //CH0_VRATE[15:8] + pr2100_write_register(ViPipe, 0x69, 0xff); //CH0_VRATE[7:0] + pr2100_write_register(ViPipe, 0x6a, 0xff); //CH1_VRATE[15:8] + pr2100_write_register(ViPipe, 0x6b, 0xff); //CH1_VRATE[7:0] + pr2100_write_register(ViPipe, 0x6c, 0xff); //CH2_VRATE[15:8] + pr2100_write_register(ViPipe, 0x6d, 0xff); //CH2_VRATE[7:0] + pr2100_write_register(ViPipe, 0x6e, 0xff); //CH3_VRATE[15:8] + pr2100_write_register(ViPipe, 0x6f, 0xff); //CH3_VRATE[7:0] + + pr2100_write_register(ViPipe, 0xFF, 0x06); + pr2100_write_register(ViPipe, 0x04, 0x10); //MIPI_CONTROL_0 + pr2100_write_register(ViPipe, 0x05, 0x04); //MIPI_CONTROL_1 + pr2100_write_register(ViPipe, 0x06, 0x00); //MIPI_CONTROL_2 + pr2100_write_register(ViPipe, 0x07, 0x00); //MIPI_CONTROL_3 + pr2100_write_register(ViPipe, 0x08, 0xc9); //MIPI_CONTROL_4 + pr2100_write_register(ViPipe, 0x1c, 0x09); //MIPI_T_LPX + pr2100_write_register(ViPipe, 0x1d, 0x08); //MIPI_T_CLK_PREPARE + pr2100_write_register(ViPipe, 0x1e, 0x09); //MIPI_T_HS_PREPARE + pr2100_write_register(ViPipe, 0x1f, 0x11); //MIPI_T_HS_ZERO + pr2100_write_register(ViPipe, 0x20, 0x0c); //MIPI_T_HS_TRAIL + pr2100_write_register(ViPipe, 0x21, 0x28); //MIPI_T_CLK_ZERO + pr2100_write_register(ViPipe, 0x22, 0x0b); //MIPI_T_CLK_TRAIL + pr2100_write_register(ViPipe, 0x23, 0x01); //MIPI_T_CLK_PRE + pr2100_write_register(ViPipe, 0x24, 0x12); //MIPI_T_CLK_POST + pr2100_write_register(ViPipe, 0x25, 0x82); //MIPI_T_WAKEUP + pr2100_write_register(ViPipe, 0x26, 0x11); //MIPI_T_HSEXIT + pr2100_write_register(ViPipe, 0x27, 0x11); //MIPI_T_CLK_HSEXIT + pr2100_write_register(ViPipe, 0x36, 0x0f); //MIPI_PKT_SIZE0_H + pr2100_write_register(ViPipe, 0x37, 0x00); //MIPI_PKT_SIZE0_L + pr2100_write_register(ViPipe, 0x38, 0x0f); //MIPI_PKT_SIZE1_H + pr2100_write_register(ViPipe, 0x39, 0x00); //MIPI_PKT_SIZE1_L + pr2100_write_register(ViPipe, 0x3a, 0x0f); //MIPI_PKT_SIZE2_H + pr2100_write_register(ViPipe, 0x3b, 0x00); //MIPI_PKT_SIZE2_L + pr2100_write_register(ViPipe, 0x3c, 0x0f); //MIPI_PKT_SIZE3_H + pr2100_write_register(ViPipe, 0x3d, 0x00); //MIPI_PKT_SIZE3_L + pr2100_write_register(ViPipe, 0x46, 0x1e); //MIPI_DATA_ID0 + pr2100_write_register(ViPipe, 0x47, 0x5e); //MIPI_DATA_ID1 + pr2100_write_register(ViPipe, 0x48, 0x9e); //MIPI_DATA_ID2 + pr2100_write_register(ViPipe, 0x49, 0xde); //MIPI_DATA_ID3 + pr2100_write_register(ViPipe, 0x04, 0x50); //MIPI_CONTROL_0 + + pr2100_set_1080p_4ch_slave(slave_pipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs/Makefile b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs/Makefile new file mode 100644 index 000000000..b1901ad9d --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc035gs.a +TARGET_SO = $(MW_LIB)/libsns_sc035gs.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs/sc035gs_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs/sc035gs_cmos.c new file mode 100644 index 000000000..f4eec6d28 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs/sc035gs_cmos.c @@ -0,0 +1,992 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc035gs_cmos_ex.h" +#include "sc035gs_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC035GS_ID 35 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC035GS[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC035GS_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC035GS[dev]) +#define SC035GS_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC035GS[dev] = pstCtx) +#define SC035GS_SENSOR_RESET_CTX(dev) (g_pastSC035GS[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC035GS_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC035GS_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC035GS_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC035GS Lines Range*****/ +#define SC035GS_FULL_LINES_MAX (0xFFFF) + +/*****SC035GS Register Address*****/ +#define SC035GS_EXP_H_ADDR (0x3e01) +#define SC035GS_EXP_L_ADDR (0x3e02) + +#define SC035GS_AGAIN_H_ADDR (0x3e08) +#define SC035GS_AGAIN_L_ADDR (0x3e09) + +#define SC035GS_DGAIN_H_ADDR (0x3e06) +#define SC035GS_DGAIN_L_ADDR (0x3e07) + +#define SC035GS_VMAX_H_ADDR (0x320e) +#define SC035GS_VMAX_L_ADDR (0x320f) + +#define SC035GS_GAIN_MAGIC_0_ADDR (0x3314) +#define SC035GS_GAIN_MAGIC_1_ADDR (0x3317) + +#define SC035GS_RES_IS_480P(w, h) ((w) <= 640 && (h) <= 480) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC035GS_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC035GS_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC035GS_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 120); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 0.0625; /* unit = 1/16 line */ + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 120 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = pstAeSnsDft->u32MaxIntTime; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC035GS_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC035GS_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC035GS_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC035GS_MODE_640X480P120: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC035GS_FULL_LINES_MAX) ? SC035GS_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = (pstSnsState->u32FLStd - 6) << 4; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 1 + * max : 16 * (vts - 6) + * step : 1 + */ + u32MinTime = 1; + u32MaxTime = (pstSnsState->au32FL[0] - 6) << 4; + + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_ADDR].u32Data = ((u32TmpIntTime & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_ADDR].u32Data = (u32TmpIntTime & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +#define MAX_AGAIN_STEP 3 + +struct gain_tbl_info_s { + CVI_U32 gainMax; + CVI_U32 gainMin; + CVI_U32 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; + CVI_U8 stepOrd; +}; + +static struct gain_tbl_info_s AgainInfo[MAX_AGAIN_STEP] = { + { + .gainMin = 1024, + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 6, + }, + { + .gainMin = 2048, + .gainMax = 3968, + .idxBase = 16, + .regGain = 0x01, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 7, + }, + { + .gainMin = 4096, + .gainMax = 4096, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 8, + }, +/* vendor suggest the maximum again shall not be larger than 4X*/ +#if 0 + { + .gainMin = 4096, + .gainMax = 7936, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 8, + }, + { + .gainMin = 8192, + .gainMax = 15872, + .idxBase = 48, + .regGain = 0x07, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 9, + }, +#endif +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i, size = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + struct gain_tbl_info_s *gainInfo = &AgainInfo[size - 1]; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin < 1024) + *pu32AgainLin = 1024; + + if (*pu32AgainLin >= gainInfo->gainMax) { + *pu32AgainDb = gainInfo->idxBase + ((gainInfo->gainMax - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32AgainLin = gainInfo->gainMax; + return CVI_SUCCESS; + } + + for (i = size - 1; i >= 0 ; i--) { + gainInfo = &AgainInfo[i]; + if (*pu32AgainLin >= gainInfo->gainMin) { + *pu32AgainDb = gainInfo->idxBase + + ((*pu32AgainLin - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32AgainLin = ((*pu32AgainDb - gainInfo->idxBase) << gainInfo->stepOrd) + + gainInfo->gainMin; + break; + } + } + return CVI_SUCCESS; +} + +#define MAX_DGAIN_STEP 3 +static struct gain_tbl_info_s DgainInfo[MAX_DGAIN_STEP] = { + { + .gainMin = 1024, + .gainMax = 2040, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 3, + }, + { + .gainMin = 2048, + .gainMax = 4080, + .idxBase = 128, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 4, + }, + { + .gainMin = 4096, + .gainMax = 8160, + .idxBase = 256, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 5, + }, +}; + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i, size = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + struct gain_tbl_info_s *gainInfo = &DgainInfo[size - 1]; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin < 1024) + *pu32DgainLin = 1024; + + if (*pu32DgainLin >= gainInfo->gainMax) { + *pu32DgainDb = gainInfo->idxBase + ((gainInfo->gainMax - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32DgainLin = gainInfo->gainMax; + return CVI_SUCCESS; + } + + for (i = size - 1; i >= 0; i--) { + gainInfo = &DgainInfo[i]; + if (*pu32DgainLin >= gainInfo->gainMin) { + *pu32DgainDb = gainInfo->idxBase + + ((*pu32DgainLin - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32DgainLin = ((*pu32DgainDb - gainInfo->idxBase) << gainInfo->stepOrd) + + gainInfo->gainMin; + break; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H_ADDR].u32Data = ((info->regGain & 0x7) << 2) | 0x3; + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L_ADDR].u32Data = (u32Again & 0xFF); + + /* gain logic setting. */ + if (info->regGain == 0x00) {//gain<2 + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_0_ADDR].u32Data = 0x1e; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_1_ADDR].u32Data = 0x10; + } else {//[gain>=4] + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_0_ADDR].u32Data = 0x4f; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_1_ADDR].u32Data = 0x0f; + } + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H_ADDR].u32Data = 0x0C | (info->regGain & 0x3); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L_ADDR].u32Data = (u32Dgain & 0xFF); + + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC035GS_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC035GS_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC035GS_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC035GS_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC035GS_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 1; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc035gs_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc035gs_addr_byte; + pstI2c_data[i].u32DataByteNum = sc035gs_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC035GS_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC035GS_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H_ADDR].u32RegAddr = SC035GS_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L_ADDR].u32RegAddr = SC035GS_AGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC035GS_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC035GS_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC035GS_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC035GS_VMAX_L_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_0_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_0_ADDR].u32RegAddr = SC035GS_GAIN_MAGIC_0_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_1_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_1_ADDR].u32RegAddr = SC035GS_GAIN_MAGIC_1_ADDR; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 120) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC035GS_RES_IS_480P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC035GS_MODE_640X480P120; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC035GS_MODE_S *pstMode = CVI_NULL; + + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC035GS_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC035GS_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc035gs_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC035GS_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC035GS_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc035gs_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc035gs_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc035gs_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc035gs_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC035GS_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC035GS_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC035GS_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC035GS_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC035GS_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC035GS_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC035GS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC035GS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC035GS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC035GS_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC035GS_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC035GS_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc035gs_standby, + .pfnRestart = sc035gs_restart, + .pfnMirrorFlip = sc035gs_mirror_flip, + .pfnWriteReg = sc035gs_write_register, + .pfnReadReg = sc035gs_read_register, + .pfnSetBusInfo = sc035gs_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs/sc035gs_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs/sc035gs_cmos_ex.h new file mode 100644 index 000000000..1f727fd18 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs/sc035gs_cmos_ex.h @@ -0,0 +1,80 @@ +#ifndef __SC035GS_CMOS_EX_H_ +#define __SC035GS_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc035gs_linear_regs_e { + LINEAR_EXP_H_ADDR, + LINEAR_EXP_L_ADDR, + LINEAR_AGAIN_H_ADDR, + LINEAR_AGAIN_L_ADDR, + LINEAR_DGAIN_H_ADDR, + LINEAR_DGAIN_L_ADDR, + LINEAR_VMAX_H_ADDR, + LINEAR_VMAX_L_ADDR, + LINEAR_GAIN_MAGIC_0_ADDR, + LINEAR_GAIN_MAGIC_1_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC035GS_MODE_E { + SC035GS_MODE_640X480P120 = 0, + SC035GS_MODE_LINEAR_NUM, + SC035GS_MODE_NUM +} SC035GS_MODE_E; + +typedef struct _SC035GS_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} SC035GS_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC035GS[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC035GS_BusInfo[]; +extern CVI_U16 g_au16SC035GS_GainMode[]; +extern CVI_U16 g_au16SC035GS_L2SMode[]; +extern const CVI_U8 sc035gs_i2c_addr; +extern const CVI_U32 sc035gs_addr_byte; +extern const CVI_U32 sc035gs_data_byte; +extern void sc035gs_init(VI_PIPE ViPipe); +extern void sc035gs_exit(VI_PIPE ViPipe); +extern void sc035gs_standby(VI_PIPE ViPipe); +extern void sc035gs_restart(VI_PIPE ViPipe); +extern int sc035gs_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc035gs_read_register(VI_PIPE ViPipe, int addr); +extern void sc035gs_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC035GS_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs/sc035gs_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs/sc035gs_cmos_param.h new file mode 100644 index 000000000..9e5d0d5c6 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs/sc035gs_cmos_param.h @@ -0,0 +1,122 @@ +#ifndef __SC035GS_CMOS_PARAM_H_ +#define __SC035GS_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc035gs_cmos_ex.h" + +static const SC035GS_MODE_S g_astSC035GS_mode[SC035GS_MODE_NUM] = { + [SC035GS_MODE_640X480P120] = { + .name = "480p120", + .astImg[0] = { + .stSnsSize = { + .u32Width = 640, + .u32Height = 480, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 640, + .u32Height = 480, + }, + .stMaxSize = { + .u32Width = 640, + .u32Height = 480, + }, + }, + .f32MaxFps = 120, + .f32MinFps = 1.25, /* 515 * 120 / 0xFFFF */ + .u32HtsDef = 878, + .u32VtsDef = 683, + .stExp[0] = { + .u16Min = 1, + .u16Max = 677 << 4,// (vts - 6) * 16 + .u16Def = 400 << 4, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 4096, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 8160, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {145, 145, 145, 145, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1061, 1061, 1061, 1061 +#endif + }, /* [TODO] check black leve*/ + .stAuto = { + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc035gs_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {2, 0, 1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .pn_swap = {1, 1, 1, 0, 0}, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC035GS_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs/sc035gs_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs/sc035gs_sensor_ctl.c new file mode 100644 index 000000000..213a9bd3d --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs/sc035gs_sensor_ctl.c @@ -0,0 +1,307 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc035gs_cmos_ex.h" + +static void sc035gs_linear_1296P30_init(VI_PIPE ViPipe); + +const CVI_U8 sc035gs_i2c_addr = 0x30; /* I2C Address of SC035GS */ +const CVI_U32 sc035gs_addr_byte = 2; +const CVI_U32 sc035gs_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc035gs_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC035GS_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc035gs_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc035gs_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc035gs_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc035gs_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc035gs_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc035gs_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc035gs_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int sc035gs_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc035gs_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc035gs_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc035gs_addr_byte + sc035gs_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc035gs_standby(VI_PIPE ViPipe) +{ + sc035gs_write_register(ViPipe, 0x0100, 0x00); +} + +void sc035gs_restart(VI_PIPE ViPipe) +{ + sc035gs_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc035gs_write_register(ViPipe, 0x0100, 0x01); +} + +void sc035gs_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC035GS[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC035GS[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc035gs_write_register(ViPipe, + g_pastSC035GS[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC035GS[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc035gs_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = sc035gs_read_register(ViPipe, 0x3221) & ~0x66; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc035gs_write_register(ViPipe, 0x3221, val); +} + +void sc035gs_init(VI_PIPE ViPipe) +{ + sc035gs_i2c_init(ViPipe); + + //linear mode only + sc035gs_linear_1296P30_init(ViPipe); + + g_pastSC035GS[ViPipe]->bInit = CVI_TRUE; +} + +void sc035gs_exit(VI_PIPE ViPipe) +{ + sc035gs_i2c_exit(ViPipe); +} + +/* 1296P30 and 1296P25 */ +static void sc035gs_linear_1296P30_init(VI_PIPE ViPipe) +{ + sc035gs_write_register(ViPipe, 0x0103, 0x01); + delay_ms(33); + sc035gs_write_register(ViPipe, 0x0100, 0x00); + sc035gs_write_register(ViPipe, 0x36e9, 0x80); + sc035gs_write_register(ViPipe, 0x36f9, 0x80); + sc035gs_write_register(ViPipe, 0x3000, 0x00); + sc035gs_write_register(ViPipe, 0x3001, 0x00); + sc035gs_write_register(ViPipe, 0x300f, 0x0f); + sc035gs_write_register(ViPipe, 0x3018, 0x33); + sc035gs_write_register(ViPipe, 0x3019, 0x0c); + sc035gs_write_register(ViPipe, 0x301c, 0x78); + sc035gs_write_register(ViPipe, 0x3031, 0x0a); + sc035gs_write_register(ViPipe, 0x3037, 0x20); + sc035gs_write_register(ViPipe, 0x303f, 0x01); + sc035gs_write_register(ViPipe, 0x320c, 0x03); + sc035gs_write_register(ViPipe, 0x320d, 0x6e); + sc035gs_write_register(ViPipe, 0x320e, 0x02); + sc035gs_write_register(ViPipe, 0x320f, 0xab); + sc035gs_write_register(ViPipe, 0x3252, 0x02); // 0x1 + sc035gs_write_register(ViPipe, 0x3253, 0x08); // 0xf8 + //sc035gs_write_register(ViPipe, 0x3252, 0x02); + //sc035gs_write_register(ViPipe, 0x3253, 0xa6); + sc035gs_write_register(ViPipe, 0x3220, 0x10); + sc035gs_write_register(ViPipe, 0x3250, 0xc0); + sc035gs_write_register(ViPipe, 0x3251, 0x02); + sc035gs_write_register(ViPipe, 0x3254, 0x02); + sc035gs_write_register(ViPipe, 0x3255, 0x07); + sc035gs_write_register(ViPipe, 0x3304, 0x48); + sc035gs_write_register(ViPipe, 0x3306, 0x38); + sc035gs_write_register(ViPipe, 0x3309, 0x68); + sc035gs_write_register(ViPipe, 0x330b, 0xe0); + sc035gs_write_register(ViPipe, 0x330c, 0x18); + sc035gs_write_register(ViPipe, 0x330f, 0x20); + sc035gs_write_register(ViPipe, 0x3310, 0x10); + sc035gs_write_register(ViPipe, 0x3314, 0x1e); + sc035gs_write_register(ViPipe, 0x3315, 0x38); + sc035gs_write_register(ViPipe, 0x3316, 0x40); + sc035gs_write_register(ViPipe, 0x3317, 0x10); + sc035gs_write_register(ViPipe, 0x3329, 0x34); + sc035gs_write_register(ViPipe, 0x332d, 0x34); + sc035gs_write_register(ViPipe, 0x332f, 0x38); + sc035gs_write_register(ViPipe, 0x3335, 0x3c); + sc035gs_write_register(ViPipe, 0x3344, 0x3c); + sc035gs_write_register(ViPipe, 0x335b, 0x80); + sc035gs_write_register(ViPipe, 0x335f, 0x80); + sc035gs_write_register(ViPipe, 0x3366, 0x06); + sc035gs_write_register(ViPipe, 0x3385, 0x31); + sc035gs_write_register(ViPipe, 0x3387, 0x51); + sc035gs_write_register(ViPipe, 0x3389, 0x01); + sc035gs_write_register(ViPipe, 0x33b1, 0x03); + sc035gs_write_register(ViPipe, 0x33b2, 0x06); + sc035gs_write_register(ViPipe, 0x3621, 0xa4); + sc035gs_write_register(ViPipe, 0x3622, 0x05); + sc035gs_write_register(ViPipe, 0x3624, 0x47); + sc035gs_write_register(ViPipe, 0x3630, 0x46); + sc035gs_write_register(ViPipe, 0x3631, 0x48); + sc035gs_write_register(ViPipe, 0x3633, 0x52); + sc035gs_write_register(ViPipe, 0x3635, 0x18); + sc035gs_write_register(ViPipe, 0x3636, 0x25); + sc035gs_write_register(ViPipe, 0x3637, 0x89); + sc035gs_write_register(ViPipe, 0x3638, 0x0f); + sc035gs_write_register(ViPipe, 0x3639, 0x08); + sc035gs_write_register(ViPipe, 0x363a, 0x00); + sc035gs_write_register(ViPipe, 0x363b, 0x48); + sc035gs_write_register(ViPipe, 0x363c, 0x06); + sc035gs_write_register(ViPipe, 0x363d, 0x00); + sc035gs_write_register(ViPipe, 0x363e, 0xf8); + sc035gs_write_register(ViPipe, 0x3640, 0x00); + sc035gs_write_register(ViPipe, 0x3641, 0x01); + sc035gs_write_register(ViPipe, 0x36ea, 0x3b); + sc035gs_write_register(ViPipe, 0x36eb, 0x0e); + sc035gs_write_register(ViPipe, 0x36ec, 0x1e); + sc035gs_write_register(ViPipe, 0x36ed, 0x33); + sc035gs_write_register(ViPipe, 0x36fa, 0x3a); + sc035gs_write_register(ViPipe, 0x36fc, 0x01); + sc035gs_write_register(ViPipe, 0x3908, 0x91); + sc035gs_write_register(ViPipe, 0x3d08, 0x01); + sc035gs_write_register(ViPipe, 0x3e01, 0x14); + sc035gs_write_register(ViPipe, 0x3e02, 0x80); + sc035gs_write_register(ViPipe, 0x3e06, 0x0c); + sc035gs_write_register(ViPipe, 0x4500, 0x59); + sc035gs_write_register(ViPipe, 0x4501, 0xc4); + sc035gs_write_register(ViPipe, 0x4603, 0x00); + sc035gs_write_register(ViPipe, 0x4809, 0x01); + sc035gs_write_register(ViPipe, 0x4837, 0x37); + sc035gs_write_register(ViPipe, 0x5011, 0x00); + sc035gs_write_register(ViPipe, 0x36e9, 0x00); + sc035gs_write_register(ViPipe, 0x36f9, 0x00); + sc035gs_default_reg_init(ViPipe); + sc035gs_write_register(ViPipe, 0x0100, 0x01); + delay_ms(18); + sc035gs_write_register(ViPipe, 0x4418, 0x08); + sc035gs_write_register(ViPipe, 0x4419, 0x8e); + delay_ms(100); + + printf("ViPipe:%d,===SC035GS 480P 120fps 12bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs_1L/Makefile b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs_1L/Makefile new file mode 100644 index 000000000..64cc1ef82 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs_1L/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc035gs_1L.a +TARGET_SO = $(MW_LIB)/libsns_sc035gs_1L.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs_1L/sc035gs_1L_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs_1L/sc035gs_1L_cmos.c new file mode 100644 index 000000000..6cb31f0e0 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs_1L/sc035gs_1L_cmos.c @@ -0,0 +1,992 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc035gs_1L_cmos_ex.h" +#include "sc035gs_1L_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC035GS_1L_ID 35 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC035GS_1L[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC035GS_1L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC035GS_1L[dev]) +#define SC035GS_1L_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC035GS_1L[dev] = pstCtx) +#define SC035GS_1L_SENSOR_RESET_CTX(dev) (g_pastSC035GS_1L[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC035GS_1L_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC035GS_1L_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC035GS_1L_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC035GS_1L Lines Range*****/ +#define SC035GS_1L_FULL_LINES_MAX (0xFFFF) + +/*****SC035GS_1L Register Address*****/ +#define SC035GS_1L_EXP_H_ADDR (0x3e01) +#define SC035GS_1L_EXP_L_ADDR (0x3e02) + +#define SC035GS_1L_AGAIN_H_ADDR (0x3e08) +#define SC035GS_1L_AGAIN_L_ADDR (0x3e09) + +#define SC035GS_1L_DGAIN_H_ADDR (0x3e06) +#define SC035GS_1L_DGAIN_L_ADDR (0x3e07) + +#define SC035GS_1L_VMAX_H_ADDR (0x320e) +#define SC035GS_1L_VMAX_L_ADDR (0x320f) + +#define SC035GS_1L_GAIN_MAGIC_0_ADDR (0x3314) +#define SC035GS_1L_GAIN_MAGIC_1_ADDR (0x3317) + +#define SC035GS_1L_RES_IS_480P(w, h) ((w) == 640 && (h) == 480) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC035GS_1L_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC035GS_1L_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC035GS_1L_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 120); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 0.0625; /* unit = 1/16 line */ + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 120 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = pstAeSnsDft->u32MaxIntTime; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC035GS_1L_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC035GS_1L_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC035GS_1L_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC035GS_1L_MODE_640X480P120: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC035GS_1L_FULL_LINES_MAX) ? SC035GS_1L_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = (pstSnsState->u32FLStd - 6) << 4; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 1 + * max : 16 * (vts - 6) + * step : 1 + */ + u32MinTime = 1; + u32MaxTime = (pstSnsState->au32FL[0] - 6) << 4; + + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_ADDR].u32Data = ((u32TmpIntTime & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_ADDR].u32Data = (u32TmpIntTime & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +#define MAX_AGAIN_STEP 3 + +struct gain_tbl_info_s { + CVI_U32 gainMax; + CVI_U32 gainMin; + CVI_U32 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; + CVI_U8 stepOrd; +}; + +static struct gain_tbl_info_s AgainInfo[MAX_AGAIN_STEP] = { + { + .gainMin = 1024, + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 6, + }, + { + .gainMin = 2048, + .gainMax = 3968, + .idxBase = 16, + .regGain = 0x01, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 7, + }, + { + .gainMin = 4096, + .gainMax = 4096, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 8, + }, +/* vendor suggest the maximum again shall not be larger than 4X*/ +#if 0 + { + .gainMin = 4096, + .gainMax = 7936, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 8, + }, + { + .gainMin = 8192, + .gainMax = 15872, + .idxBase = 48, + .regGain = 0x07, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 9, + }, +#endif +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i, size = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + struct gain_tbl_info_s *gainInfo = &AgainInfo[size - 1]; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin < 1024) + *pu32AgainLin = 1024; + + if (*pu32AgainLin >= gainInfo->gainMax) { + *pu32AgainDb = gainInfo->idxBase + ((gainInfo->gainMax - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32AgainLin = gainInfo->gainMax; + return CVI_SUCCESS; + } + + for (i = size - 1; i >= 0 ; i--) { + gainInfo = &AgainInfo[i]; + if (*pu32AgainLin >= gainInfo->gainMin) { + *pu32AgainDb = gainInfo->idxBase + + ((*pu32AgainLin - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32AgainLin = ((*pu32AgainDb - gainInfo->idxBase) << gainInfo->stepOrd) + + gainInfo->gainMin; + break; + } + } + return CVI_SUCCESS; +} + +#define MAX_DGAIN_STEP 3 +static struct gain_tbl_info_s DgainInfo[MAX_DGAIN_STEP] = { + { + .gainMin = 1024, + .gainMax = 2040, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 3, + }, + { + .gainMin = 2048, + .gainMax = 4080, + .idxBase = 128, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 4, + }, + { + .gainMin = 4096, + .gainMax = 8160, + .idxBase = 256, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 5, + }, +}; + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i, size = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + struct gain_tbl_info_s *gainInfo = &DgainInfo[size - 1]; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin < 1024) + *pu32DgainLin = 1024; + + if (*pu32DgainLin >= gainInfo->gainMax) { + *pu32DgainDb = gainInfo->idxBase + ((gainInfo->gainMax - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32DgainLin = gainInfo->gainMax; + return CVI_SUCCESS; + } + + for (i = size - 1; i >= 0; i--) { + gainInfo = &DgainInfo[i]; + if (*pu32DgainLin >= gainInfo->gainMin) { + *pu32DgainDb = gainInfo->idxBase + + ((*pu32DgainLin - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32DgainLin = ((*pu32DgainDb - gainInfo->idxBase) << gainInfo->stepOrd) + + gainInfo->gainMin; + break; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H_ADDR].u32Data = ((info->regGain & 0x7) << 2) | 0x3; + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L_ADDR].u32Data = (u32Again & 0xFF); + + /* gain logic setting. */ + if (info->regGain == 0x00) {//gain<2 + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_0_ADDR].u32Data = 0x1e; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_1_ADDR].u32Data = 0x10; + } else {//[gain>=4] + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_0_ADDR].u32Data = 0x4f; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_1_ADDR].u32Data = 0x0f; + } + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H_ADDR].u32Data = 0x0C | (info->regGain & 0x3); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L_ADDR].u32Data = (u32Dgain & 0xFF); + + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC035GS_1L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC035GS_1L_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC035GS_1L_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC035GS_1L_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC035GS_1L_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 1; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc035gs_1L_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc035gs_1L_addr_byte; + pstI2c_data[i].u32DataByteNum = sc035gs_1L_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC035GS_1L_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC035GS_1L_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H_ADDR].u32RegAddr = SC035GS_1L_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L_ADDR].u32RegAddr = SC035GS_1L_AGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC035GS_1L_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC035GS_1L_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC035GS_1L_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC035GS_1L_VMAX_L_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_0_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_0_ADDR].u32RegAddr = SC035GS_1L_GAIN_MAGIC_0_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_1_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_1_ADDR].u32RegAddr = SC035GS_1L_GAIN_MAGIC_1_ADDR; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 120) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC035GS_1L_RES_IS_480P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC035GS_1L_MODE_640X480P120; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC035GS_1L_MODE_S *pstMode = CVI_NULL; + + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC035GS_1L_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC035GS_1L_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc035gs_1L_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC035GS_1L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC035GS_1L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc035gs_1L_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc035gs_1L_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc035gs_1L_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc035gs_1L_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC035GS_1L_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC035GS_1L_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC035GS_1L_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC035GS_1L_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC035GS_1L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC035GS_1L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC035GS_1L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC035GS_1L_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC035GS_1L_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC035GS_1L_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc035gs_1L_standby, + .pfnRestart = sc035gs_1L_restart, + .pfnMirrorFlip = sc035gs_1L_mirror_flip, + .pfnWriteReg = sc035gs_1L_write_register, + .pfnReadReg = sc035gs_1L_read_register, + .pfnSetBusInfo = sc035gs_1L_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs_1L/sc035gs_1L_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs_1L/sc035gs_1L_cmos_ex.h new file mode 100644 index 000000000..dfa0a52ee --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs_1L/sc035gs_1L_cmos_ex.h @@ -0,0 +1,80 @@ +#ifndef __SC035GS_1L_CMOS_EX_H_ +#define __SC035GS_1L_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc035gs_1L_linear_regs_e { + LINEAR_EXP_H_ADDR, + LINEAR_EXP_L_ADDR, + LINEAR_AGAIN_H_ADDR, + LINEAR_AGAIN_L_ADDR, + LINEAR_DGAIN_H_ADDR, + LINEAR_DGAIN_L_ADDR, + LINEAR_VMAX_H_ADDR, + LINEAR_VMAX_L_ADDR, + LINEAR_GAIN_MAGIC_0_ADDR, + LINEAR_GAIN_MAGIC_1_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC035GS_1L_MODE_E { + SC035GS_1L_MODE_640X480P120 = 0, + SC035GS_1L_MODE_LINEAR_NUM, + SC035GS_1L_MODE_NUM +} SC035GS_1L_MODE_E; + +typedef struct _SC035GS_1L_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} SC035GS_1L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC035GS_1L[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC035GS_1L_BusInfo[]; +extern CVI_U16 g_au16SC035GS_1L_GainMode[]; +extern CVI_U16 g_au16SC035GS_1L_L2SMode[]; +extern const CVI_U8 sc035gs_1L_i2c_addr; +extern const CVI_U32 sc035gs_1L_addr_byte; +extern const CVI_U32 sc035gs_1L_data_byte; +extern void sc035gs_1L_init(VI_PIPE ViPipe); +extern void sc035gs_1L_exit(VI_PIPE ViPipe); +extern void sc035gs_1L_standby(VI_PIPE ViPipe); +extern void sc035gs_1L_restart(VI_PIPE ViPipe); +extern int sc035gs_1L_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc035gs_1L_read_register(VI_PIPE ViPipe, int addr); +extern void sc035gs_1L_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC035GS_1L_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs_1L/sc035gs_1L_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs_1L/sc035gs_1L_cmos_param.h new file mode 100644 index 000000000..1df5b1ebb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs_1L/sc035gs_1L_cmos_param.h @@ -0,0 +1,122 @@ +#ifndef __SC035GS_1L_CMOS_PARAM_H_ +#define __SC035GS_1L_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc035gs_1L_cmos_ex.h" + +static const SC035GS_1L_MODE_S g_astSC035GS_1L_mode[SC035GS_1L_MODE_NUM] = { + [SC035GS_1L_MODE_640X480P120] = { + .name = "480p120", + .astImg[0] = { + .stSnsSize = { + .u32Width = 640, + .u32Height = 480, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 640, + .u32Height = 480, + }, + .stMaxSize = { + .u32Width = 640, + .u32Height = 480, + }, + }, + .f32MaxFps = 120, + .f32MinFps = 1.25, /* 515 * 120 / 0xFFFF */ + .u32HtsDef = 878, + .u32VtsDef = 683, + .stExp[0] = { + .u16Min = 1, + .u16Max = 677 << 4,// (vts - 6) * 16 + .u16Def = 400 << 4, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 4096, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 8160, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {145, 145, 145, 145, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1061, 1061, 1061, 1061 +#endif + }, /* [TODO] check black leve*/ + .stAuto = { + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc035gs_1L_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 0, -1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .pn_swap = {1, 1, 0, 0, 0}, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC035GS_1L_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs_1L/sc035gs_1L_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs_1L/sc035gs_1L_sensor_ctl.c new file mode 100644 index 000000000..ff33222ea --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc035gs_1L/sc035gs_1L_sensor_ctl.c @@ -0,0 +1,310 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc035gs_1L_cmos_ex.h" + +static void sc035gs_1L_linear_1296P30_init(VI_PIPE ViPipe); + +const CVI_U8 sc035gs_1L_i2c_addr = 0x30; /* I2C Address of SC035GS_1L */ +const CVI_U32 sc035gs_1L_addr_byte = 2; +const CVI_U32 sc035gs_1L_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc035gs_1L_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC035GS_1L_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc035gs_1L_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc035gs_1L_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc035gs_1L_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc035gs_1L_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc035gs_1L_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc035gs_1L_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc035gs_1L_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int sc035gs_1L_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc035gs_1L_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc035gs_1L_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc035gs_1L_addr_byte + sc035gs_1L_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc035gs_1L_standby(VI_PIPE ViPipe) +{ + sc035gs_1L_write_register(ViPipe, 0x0100, 0x00); +} + +void sc035gs_1L_restart(VI_PIPE ViPipe) +{ + sc035gs_1L_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc035gs_1L_write_register(ViPipe, 0x0100, 0x01); +} + +void sc035gs_1L_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC035GS_1L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC035GS_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc035gs_1L_write_register(ViPipe, + g_pastSC035GS_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC035GS_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc035gs_1L_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = sc035gs_1L_read_register(ViPipe, 0x3221) & ~0x66; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc035gs_1L_write_register(ViPipe, 0x3221, val); +} + +void sc035gs_1L_init(VI_PIPE ViPipe) +{ + sc035gs_1L_i2c_init(ViPipe); + + //linear mode only + sc035gs_1L_linear_1296P30_init(ViPipe); + + g_pastSC035GS_1L[ViPipe]->bInit = CVI_TRUE; +} + +void sc035gs_1L_exit(VI_PIPE ViPipe) +{ + sc035gs_1L_i2c_exit(ViPipe); +} + +/* 1296P30 and 1296P25 */ +static void sc035gs_1L_linear_1296P30_init(VI_PIPE ViPipe) +{ + sc035gs_1L_write_register(ViPipe, 0x0103, 0x01); + delay_ms(33); + sc035gs_1L_write_register(ViPipe, 0x0100, 0x00); + sc035gs_1L_write_register(ViPipe, 0x36e9, 0x80); + sc035gs_1L_write_register(ViPipe, 0x36f9, 0x80); + sc035gs_1L_write_register(ViPipe, 0x3001, 0x00); + sc035gs_1L_write_register(ViPipe, 0x3000, 0x00); + sc035gs_1L_write_register(ViPipe, 0x300f, 0x0f); + sc035gs_1L_write_register(ViPipe, 0x3018, 0x13); + sc035gs_1L_write_register(ViPipe, 0x3019, 0xfe); + sc035gs_1L_write_register(ViPipe, 0x301c, 0x78); + sc035gs_1L_write_register(ViPipe, 0x301f, 0x07); + sc035gs_1L_write_register(ViPipe, 0x3031, 0x0a); + sc035gs_1L_write_register(ViPipe, 0x3037, 0x20); + sc035gs_1L_write_register(ViPipe, 0x303f, 0x01); + sc035gs_1L_write_register(ViPipe, 0x320c, 0x03); + sc035gs_1L_write_register(ViPipe, 0x320d, 0x6e); + sc035gs_1L_write_register(ViPipe, 0x320e, 0x02); + sc035gs_1L_write_register(ViPipe, 0x320f, 0xab); + sc035gs_1L_write_register(ViPipe, 0x3220, 0x10); + sc035gs_1L_write_register(ViPipe, 0x3250, 0xc0); + sc035gs_1L_write_register(ViPipe, 0x3251, 0x02); + sc035gs_1L_write_register(ViPipe, 0x3252, 0x02); + sc035gs_1L_write_register(ViPipe, 0x3253, 0x08); +// sc035gs_1L_write_register(ViPipe, 0x3252, 0x02); +// sc035gs_1L_write_register(ViPipe, 0x3253, 0xa6); + sc035gs_1L_write_register(ViPipe, 0x3254, 0x02); + sc035gs_1L_write_register(ViPipe, 0x3255, 0x07); + sc035gs_1L_write_register(ViPipe, 0x3304, 0x48); + sc035gs_1L_write_register(ViPipe, 0x3306, 0x38); + sc035gs_1L_write_register(ViPipe, 0x3309, 0x68); + sc035gs_1L_write_register(ViPipe, 0x330b, 0xe0); + sc035gs_1L_write_register(ViPipe, 0x330c, 0x18); + sc035gs_1L_write_register(ViPipe, 0x330f, 0x20); + sc035gs_1L_write_register(ViPipe, 0x3310, 0x10); + sc035gs_1L_write_register(ViPipe, 0x3314, 0x1e); + sc035gs_1L_write_register(ViPipe, 0x3315, 0x38); + sc035gs_1L_write_register(ViPipe, 0x3316, 0x40); + sc035gs_1L_write_register(ViPipe, 0x3317, 0x10); + sc035gs_1L_write_register(ViPipe, 0x3329, 0x34); + sc035gs_1L_write_register(ViPipe, 0x332d, 0x34); + sc035gs_1L_write_register(ViPipe, 0x332f, 0x38); + sc035gs_1L_write_register(ViPipe, 0x3335, 0x3c); + sc035gs_1L_write_register(ViPipe, 0x3344, 0x3c); + sc035gs_1L_write_register(ViPipe, 0x335b, 0x80); + sc035gs_1L_write_register(ViPipe, 0x335f, 0x80); + sc035gs_1L_write_register(ViPipe, 0x3366, 0x06); + sc035gs_1L_write_register(ViPipe, 0x3385, 0x31); + sc035gs_1L_write_register(ViPipe, 0x3387, 0x51); + sc035gs_1L_write_register(ViPipe, 0x3389, 0x01); + sc035gs_1L_write_register(ViPipe, 0x33b1, 0x03); + sc035gs_1L_write_register(ViPipe, 0x33b2, 0x06); + sc035gs_1L_write_register(ViPipe, 0x3621, 0xa4); + sc035gs_1L_write_register(ViPipe, 0x3622, 0x05); + sc035gs_1L_write_register(ViPipe, 0x3624, 0x47); + sc035gs_1L_write_register(ViPipe, 0x3630, 0x46); + sc035gs_1L_write_register(ViPipe, 0x3631, 0x48); + sc035gs_1L_write_register(ViPipe, 0x3633, 0x52); + sc035gs_1L_write_register(ViPipe, 0x3635, 0x18); + sc035gs_1L_write_register(ViPipe, 0x3636, 0x25); + sc035gs_1L_write_register(ViPipe, 0x3637, 0x89); + sc035gs_1L_write_register(ViPipe, 0x3638, 0x0f); + sc035gs_1L_write_register(ViPipe, 0x3639, 0x08); + sc035gs_1L_write_register(ViPipe, 0x363a, 0x00); + sc035gs_1L_write_register(ViPipe, 0x363b, 0x48); + sc035gs_1L_write_register(ViPipe, 0x363c, 0x06); + sc035gs_1L_write_register(ViPipe, 0x363d, 0x00); + sc035gs_1L_write_register(ViPipe, 0x363e, 0xf8); + sc035gs_1L_write_register(ViPipe, 0x3640, 0x00); + sc035gs_1L_write_register(ViPipe, 0x3641, 0x01); + sc035gs_1L_write_register(ViPipe, 0x36ea, 0x3b); + sc035gs_1L_write_register(ViPipe, 0x36eb, 0x0e); + sc035gs_1L_write_register(ViPipe, 0x36ec, 0x0e); + sc035gs_1L_write_register(ViPipe, 0x36ed, 0x33); + sc035gs_1L_write_register(ViPipe, 0x36fa, 0x3a); + sc035gs_1L_write_register(ViPipe, 0x36fc, 0x01); + sc035gs_1L_write_register(ViPipe, 0x3908, 0x91); + sc035gs_1L_write_register(ViPipe, 0x3d08, 0x01); + sc035gs_1L_write_register(ViPipe, 0x3e01, 0x14); + sc035gs_1L_write_register(ViPipe, 0x3e02, 0x80); + sc035gs_1L_write_register(ViPipe, 0x3e06, 0x0c); + sc035gs_1L_write_register(ViPipe, 0x4500, 0x59); + sc035gs_1L_write_register(ViPipe, 0x4501, 0xc4); + sc035gs_1L_write_register(ViPipe, 0x4603, 0x00); + sc035gs_1L_write_register(ViPipe, 0x4809, 0x01); + sc035gs_1L_write_register(ViPipe, 0x4837, 0x1b); + sc035gs_1L_write_register(ViPipe, 0x5011, 0x00); + sc035gs_1L_write_register(ViPipe, 0x36e9, 0x00); + sc035gs_1L_write_register(ViPipe, 0x36f9, 0x00); + + sc035gs_1L_default_reg_init(ViPipe); + + sc035gs_1L_write_register(ViPipe, 0x0100, 0x01); + delay_ms(18); + sc035gs_1L_write_register(ViPipe, 0x4418, 0x08); + sc035gs_1L_write_register(ViPipe, 0x4419, 0x8e); + delay_ms(100); + + printf("ViPipe:%d,===SC035GS_1L 480P 120fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc035hgs/Makefile b/middleware/v2/component/isp/sensor/cv180x/sms_sc035hgs/Makefile new file mode 100644 index 000000000..58ef7260c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc035hgs/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc035hgs.a +TARGET_SO = $(MW_LIB)/libsns_sc035hgs.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc035hgs/sc035hgs_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc035hgs/sc035hgs_cmos.c new file mode 100644 index 000000000..4b971ad74 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc035hgs/sc035hgs_cmos.c @@ -0,0 +1,1059 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc035hgs_cmos_ex.h" +#include "sc035hgs_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC035HGS_ID 35 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC035HGS[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC035HGS_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC035HGS[dev]) +#define SC035HGS_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC035HGS[dev] = pstCtx) +#define SC035HGS_SENSOR_RESET_CTX(dev) (g_pastSC035HGS[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC035HGS_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC035HGS_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC035HGS_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC035HGS Lines Range*****/ +#define SC035HGS_FULL_LINES_MAX (0xFFFF) + +/*****SC035HGS Register Address*****/ +#define SC035HGS_EXP_H_ADDR (0x3e01) +#define SC035HGS_EXP_L_ADDR (0x3e02) + +#define SC035HGS_AGAIN_H_ADDR (0x3e08) +#define SC035HGS_AGAIN_L_ADDR (0x3e09) + +#define SC035HGS_DGAIN_H_ADDR (0x3e06) +#define SC035HGS_DGAIN_L_ADDR (0x3e07) + +#define SC035HGS_VMAX_H_ADDR (0x320e) +#define SC035HGS_VMAX_L_ADDR (0x320f) + +#define SC035HGS_GAIN_MAGIC_0_ADDR (0x3314) +#define SC035HGS_GAIN_MAGIC_1_ADDR (0x3317) +#define SC035HGS_GAIN_MAGIC_2_ADDR (0x3631) +#define SC035HGS_GAIN_MAGIC_3_ADDR (0x3329) +#define SC035HGS_GAIN_MAGIC_4_ADDR (0x332d) +#define SC035HGS_GAIN_MAGIC_5_ADDR (0x332f) +#define SC035HGS_GAIN_MAGIC_6_ADDR (0x3335) +#define SC035HGS_GAIN_MAGIC_7_ADDR (0x3344) +#define SC035HGS_GAIN_MAGIC_8_ADDR (0x3316) +#define SC035HGS_GAIN_MAGIC_9_ADDR (0x3630) + +#define SC035HGS_RES_IS_480P(w, h) ((w) <= 640 && (h) <= 480) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC035HGS_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC035HGS_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC035HGS_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 120); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 0.0625; /* unit = 1/16 line */ + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 120 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 3; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = pstAeSnsDft->u32MaxIntTime; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC035HGS_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC035HGS_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC035HGS_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC035HGS_MODE_640X480P120: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC035HGS_FULL_LINES_MAX) ? SC035HGS_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = (pstSnsState->u32FLStd - 6) << 4; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 1 + * max : 16 * (vts - 6) + * step : 1 + */ + u32MinTime = 1; + u32MaxTime = (pstSnsState->au32FL[0] - 6) << 4; + + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_ADDR].u32Data = ((u32TmpIntTime & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_ADDR].u32Data = (u32TmpIntTime & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +#define MAX_AGAIN_STEP 3 + +struct gain_tbl_info_s { + CVI_U32 gainMax; + CVI_U32 gainMin; + CVI_U32 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; + CVI_U8 stepOrd; +}; + +static struct gain_tbl_info_s AgainInfo[MAX_AGAIN_STEP] = { + { + .gainMin = 1024, + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 6, + }, + { + .gainMin = 2048, + .gainMax = 3968, + .idxBase = 16, + .regGain = 0x01, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 7, + }, + { + .gainMin = 4096, + .gainMax = 4096, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 8, + }, +/* vendor suggest the maximum again shall not be larger than 4X*/ +#if 0 + { + .gainMin = 4096, + .gainMax = 7936, + .gainMax = 4096, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 8, + }, + { + .gainMin = 8192, + .gainMax = 15872, + .idxBase = 48, + .regGain = 0x07, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 9, + }, +#endif +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i, size = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + struct gain_tbl_info_s *gainInfo = &AgainInfo[size - 1]; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin < 1024) + *pu32AgainLin = 1024; + + if (*pu32AgainLin >= gainInfo->gainMax) { + *pu32AgainDb = gainInfo->idxBase + ((gainInfo->gainMax - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32AgainLin = gainInfo->gainMax; + return CVI_SUCCESS; + } + + for (i = size - 1; i >= 0 ; i--) { + gainInfo = &AgainInfo[i]; + if (*pu32AgainLin >= gainInfo->gainMin) { + *pu32AgainDb = gainInfo->idxBase + + ((*pu32AgainLin - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32AgainLin = ((*pu32AgainDb - gainInfo->idxBase) << gainInfo->stepOrd) + + gainInfo->gainMin; + break; + } + } + return CVI_SUCCESS; +} + +#define MAX_DGAIN_STEP 3 +static struct gain_tbl_info_s DgainInfo[MAX_DGAIN_STEP] = { + { + .gainMin = 1024, + .gainMax = 2040, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 3, + }, + { + .gainMin = 2048, + .gainMax = 4080, + .idxBase = 128, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 4, + }, + { + .gainMin = 4096, + .gainMax = 8160, + .idxBase = 256, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 5, + }, +}; + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i, size = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + struct gain_tbl_info_s *gainInfo = &DgainInfo[size - 1]; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin < 1024) + *pu32DgainLin = 1024; + + if (*pu32DgainLin >= gainInfo->gainMax) { + *pu32DgainDb = gainInfo->idxBase + ((gainInfo->gainMax - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32DgainLin = gainInfo->gainMax; + return CVI_SUCCESS; + } + + for (i = size - 1; i >= 0; i--) { + gainInfo = &DgainInfo[i]; + if (*pu32DgainLin >= gainInfo->gainMin) { + *pu32DgainDb = gainInfo->idxBase + + ((*pu32DgainLin - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32DgainLin = ((*pu32DgainDb - gainInfo->idxBase) << gainInfo->stepOrd) + + gainInfo->gainMin; + break; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H_ADDR].u32Data = ((info->regGain & 0x7) << 2) | 0x3; + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L_ADDR].u32Data = (u32Again & 0xFF); + + /* gain logic setting. */ + if (info->regGain == 0x00) {//gain<2 + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_0_ADDR].u32Data = 0x1e; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_1_ADDR].u32Data = 0x1b; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_2_ADDR].u32Data = 0x58; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_3_ADDR].u32Data = 0x3c; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_4_ADDR].u32Data = 0x3c; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_5_ADDR].u32Data = 0x40; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_6_ADDR].u32Data = 0x44; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_7_ADDR].u32Data = 0x44; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_8_ADDR].u32Data = 0x48; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_9_ADDR].u32Data = 0x4a; + } else if (info->regGain == 0x01) {//[2=astI2cData[LINEAR_GAIN_MAGIC_0_ADDR].u32Data = 0x6f; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_1_ADDR].u32Data = 0x10; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_2_ADDR].u32Data = 0x48; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_3_ADDR].u32Data = 0x5c; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_4_ADDR].u32Data = 0x5c; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_5_ADDR].u32Data = 0x60; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_6_ADDR].u32Data = 0x64; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_7_ADDR].u32Data = 0x64; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_8_ADDR].u32Data = 0x68; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_9_ADDR].u32Data = 0x4c; + } else {//[gain>=4] + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_0_ADDR].u32Data = 0x76; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_1_ADDR].u32Data = 0x15; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_2_ADDR].u32Data = 0x48; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_3_ADDR].u32Data = 0x5c; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_4_ADDR].u32Data = 0x5c; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_5_ADDR].u32Data = 0x60; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_6_ADDR].u32Data = 0x64; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_7_ADDR].u32Data = 0x64; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_8_ADDR].u32Data = 0x68; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_9_ADDR].u32Data = 0x4c; + } + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H_ADDR].u32Data = 0x0C | (info->regGain & 0x3); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L_ADDR].u32Data = (u32Dgain & 0xFF); + + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC035HGS_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC035HGS_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC035HGS_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC035HGS_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC035HGS_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 1; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc035hgs_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc035hgs_addr_byte; + pstI2c_data[i].u32DataByteNum = sc035hgs_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC035HGS_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC035HGS_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H_ADDR].u32RegAddr = SC035HGS_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_H_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_AGAIN_L_ADDR].u32RegAddr = SC035HGS_AGAIN_L_ADDR; + pstI2c_data[LINEAR_AGAIN_L_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC035HGS_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC035HGS_DGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC035HGS_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC035HGS_VMAX_L_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_0_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_0_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_0_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_0_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_1_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_1_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_1_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_1_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_2_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_2_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_2_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_2_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_3_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_3_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_3_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_3_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_4_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_4_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_4_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_4_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_5_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_5_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_5_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_5_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_6_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_6_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_6_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_6_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_7_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_7_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_7_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_7_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_8_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_8_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_8_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_8_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_9_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_9_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_9_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_9_ADDR].u8DelayFrmNum = 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 120) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC035HGS_RES_IS_480P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC035HGS_MODE_640X480P120; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC035HGS_MODE_S *pstMode = CVI_NULL; + + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC035HGS_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC035HGS_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc035hgs_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC035HGS_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC035HGS_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc035hgs_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc035hgs_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc035hgs_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc035hgs_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC035HGS_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC035HGS_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC035HGS_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC035HGS_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC035HGS_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC035HGS_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC035HGS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC035HGS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC035HGS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC035HGS_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC035HGS_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC035HGS_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc035hgs_standby, + .pfnRestart = sc035hgs_restart, + .pfnMirrorFlip = CVI_NULL, + .pfnWriteReg = sc035hgs_write_register, + .pfnReadReg = sc035hgs_read_register, + .pfnSetBusInfo = sc035hgs_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc035hgs/sc035hgs_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc035hgs/sc035hgs_cmos_ex.h new file mode 100644 index 000000000..2e9b6e4fb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc035hgs/sc035hgs_cmos_ex.h @@ -0,0 +1,87 @@ +#ifndef __SC035HGS_CMOS_EX_H_ +#define __SC035HGS_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc035hgs_linear_regs_e { + LINEAR_EXP_H_ADDR, + LINEAR_EXP_L_ADDR, + LINEAR_AGAIN_H_ADDR, + LINEAR_AGAIN_L_ADDR, + LINEAR_DGAIN_H_ADDR, + LINEAR_DGAIN_L_ADDR, + LINEAR_VMAX_H_ADDR, + LINEAR_VMAX_L_ADDR, + LINEAR_GAIN_MAGIC_0_ADDR, + LINEAR_GAIN_MAGIC_1_ADDR, + LINEAR_GAIN_MAGIC_2_ADDR, + LINEAR_GAIN_MAGIC_3_ADDR, + LINEAR_GAIN_MAGIC_4_ADDR, + LINEAR_GAIN_MAGIC_5_ADDR, + LINEAR_GAIN_MAGIC_6_ADDR, + LINEAR_GAIN_MAGIC_7_ADDR, + LINEAR_GAIN_MAGIC_8_ADDR, + LINEAR_GAIN_MAGIC_9_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC035HGS_MODE_E { + SC035HGS_MODE_640X480P120 = 0, + SC035HGS_MODE_LINEAR_NUM, + SC035HGS_MODE_NUM +} SC035HGS_MODE_E; + +typedef struct _SC035HGS_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} SC035HGS_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC035HGS[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC035HGS_BusInfo[]; +extern CVI_U16 g_au16SC035HGS_GainMode[]; +extern CVI_U16 g_au16SC035HGS_L2SMode[]; +extern const CVI_U8 sc035hgs_i2c_addr; +extern const CVI_U32 sc035hgs_addr_byte; +extern const CVI_U32 sc035hgs_data_byte; +extern void sc035hgs_init(VI_PIPE ViPipe); +extern void sc035hgs_exit(VI_PIPE ViPipe); +extern void sc035hgs_standby(VI_PIPE ViPipe); +extern void sc035hgs_restart(VI_PIPE ViPipe); +extern int sc035hgs_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc035hgs_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC035HGS_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc035hgs/sc035hgs_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc035hgs/sc035hgs_cmos_param.h new file mode 100644 index 000000000..8331c5ff3 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc035hgs/sc035hgs_cmos_param.h @@ -0,0 +1,122 @@ +#ifndef __SC035HGS_CMOS_PARAM_H_ +#define __SC035HGS_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc035hgs_cmos_ex.h" + +static const SC035HGS_MODE_S g_astSC035HGS_mode[SC035HGS_MODE_NUM] = { + [SC035HGS_MODE_640X480P120] = { + .name = "480p120", + .astImg[0] = { + .stSnsSize = { + .u32Width = 640, + .u32Height = 480, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 640, + .u32Height = 480, + }, + .stMaxSize = { + .u32Width = 640, + .u32Height = 480, + }, + }, + .f32MaxFps = 120, + .f32MinFps = 0.95, /* 515 * 120 / 0xFFFF */ + .u32HtsDef = 1364, + .u32VtsDef = 515, + .stExp[0] = { + .u16Min = 1, + .u16Max = 509 << 4,// (vts - 6) * 16 + .u16Def = 400 << 4, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 4096, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 8160, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {145, 145, 145, 145, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1061, 1061, 1061, 1061 +#endif + }, /* [TODO] check black leve*/ + .stAuto = { + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc035hgs_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {2, 0, 1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .pn_swap = {1, 1, 1, 0, 0}, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC035HGS_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc035hgs/sc035hgs_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc035hgs/sc035hgs_sensor_ctl.c new file mode 100644 index 000000000..eaad111ef --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc035hgs/sc035hgs_sensor_ctl.c @@ -0,0 +1,307 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc035hgs_cmos_ex.h" + +static void sc035hgs_linear_1296P30_init(VI_PIPE ViPipe); + +const CVI_U8 sc035hgs_i2c_addr = 0x30; /* I2C Address of SC035HGS */ +const CVI_U32 sc035hgs_addr_byte = 2; +const CVI_U32 sc035hgs_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc035hgs_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC035HGS_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc035hgs_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc035hgs_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc035hgs_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc035hgs_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc035hgs_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc035hgs_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc035hgs_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int sc035hgs_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc035hgs_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc035hgs_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc035hgs_addr_byte + sc035hgs_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc035hgs_standby(VI_PIPE ViPipe) +{ + sc035hgs_write_register(ViPipe, 0x0100, 0x00); +} + +void sc035hgs_restart(VI_PIPE ViPipe) +{ + sc035hgs_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc035hgs_write_register(ViPipe, 0x0100, 0x01); +} + +void sc035hgs_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC035HGS[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC035HGS[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc035hgs_write_register(ViPipe, + g_pastSC035HGS[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC035HGS[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc035hgs_init(VI_PIPE ViPipe) +{ + sc035hgs_i2c_init(ViPipe); + + //linear mode only + sc035hgs_linear_1296P30_init(ViPipe); + + g_pastSC035HGS[ViPipe]->bInit = CVI_TRUE; +} + +void sc035hgs_exit(VI_PIPE ViPipe) +{ + sc035hgs_i2c_exit(ViPipe); +} + +/* 1296P30 and 1296P25 */ +static void sc035hgs_linear_1296P30_init(VI_PIPE ViPipe) +{ + sc035hgs_write_register(ViPipe, 0x0103, 0x01); + delay_ms(33); + sc035hgs_write_register(ViPipe, 0x0100, 0x00); + sc035hgs_write_register(ViPipe, 0x36e9, 0x80); + sc035hgs_write_register(ViPipe, 0x36f9, 0x80); + sc035hgs_write_register(ViPipe, 0x3000, 0x00); + sc035hgs_write_register(ViPipe, 0x3001, 0x00); + sc035hgs_write_register(ViPipe, 0x300f, 0x0f); + sc035hgs_write_register(ViPipe, 0x3018, 0x33); + sc035hgs_write_register(ViPipe, 0x3019, 0xfc); + sc035hgs_write_register(ViPipe, 0x301c, 0x78); + sc035hgs_write_register(ViPipe, 0x301f, 0x8e); + sc035hgs_write_register(ViPipe, 0x3031, 0x0c); + sc035hgs_write_register(ViPipe, 0x3037, 0x40); + sc035hgs_write_register(ViPipe, 0x303f, 0x01); + sc035hgs_write_register(ViPipe, 0x320c, 0x05); + sc035hgs_write_register(ViPipe, 0x320d, 0x54); + sc035hgs_write_register(ViPipe, 0x320e, 0x02); + sc035hgs_write_register(ViPipe, 0x320f, 0x03); + sc035hgs_write_register(ViPipe, 0x3217, 0x00); + sc035hgs_write_register(ViPipe, 0x3218, 0x00); + sc035hgs_write_register(ViPipe, 0x3220, 0x10); + sc035hgs_write_register(ViPipe, 0x3223, 0x48); + sc035hgs_write_register(ViPipe, 0x3226, 0x74); + sc035hgs_write_register(ViPipe, 0x3227, 0x07); + sc035hgs_write_register(ViPipe, 0x323b, 0x00); + sc035hgs_write_register(ViPipe, 0x3250, 0xf0); + sc035hgs_write_register(ViPipe, 0x3251, 0x02); + sc035hgs_write_register(ViPipe, 0x3252, 0x02); // 0x1 + sc035hgs_write_register(ViPipe, 0x3253, 0x08); // 0xf8 + sc035hgs_write_register(ViPipe, 0x3254, 0x02); + sc035hgs_write_register(ViPipe, 0x3255, 0x07); + sc035hgs_write_register(ViPipe, 0x3304, 0x48); + sc035hgs_write_register(ViPipe, 0x3305, 0x00); + sc035hgs_write_register(ViPipe, 0x3306, 0x98); + sc035hgs_write_register(ViPipe, 0x3309, 0x50); + sc035hgs_write_register(ViPipe, 0x330a, 0x01); + sc035hgs_write_register(ViPipe, 0x330b, 0x18); + sc035hgs_write_register(ViPipe, 0x330c, 0x18); + sc035hgs_write_register(ViPipe, 0x330f, 0x40); + sc035hgs_write_register(ViPipe, 0x3310, 0x10); + sc035hgs_write_register(ViPipe, 0x3314, 0x1e); + sc035hgs_write_register(ViPipe, 0x3315, 0x30); + sc035hgs_write_register(ViPipe, 0x3316, 0x48); + sc035hgs_write_register(ViPipe, 0x3317, 0x1b); + sc035hgs_write_register(ViPipe, 0x3329, 0x3c); + sc035hgs_write_register(ViPipe, 0x332d, 0x3c); + sc035hgs_write_register(ViPipe, 0x332f, 0x40); + sc035hgs_write_register(ViPipe, 0x3335, 0x44); + sc035hgs_write_register(ViPipe, 0x3344, 0x44); + sc035hgs_write_register(ViPipe, 0x335b, 0x80); + sc035hgs_write_register(ViPipe, 0x335f, 0x80); + sc035hgs_write_register(ViPipe, 0x3366, 0x06); + sc035hgs_write_register(ViPipe, 0x3385, 0x31); + sc035hgs_write_register(ViPipe, 0x3387, 0x39); + sc035hgs_write_register(ViPipe, 0x3389, 0x01); + sc035hgs_write_register(ViPipe, 0x33b1, 0x03); + sc035hgs_write_register(ViPipe, 0x33b2, 0x06); + sc035hgs_write_register(ViPipe, 0x33bd, 0xe0); + sc035hgs_write_register(ViPipe, 0x33bf, 0x10); + sc035hgs_write_register(ViPipe, 0x3621, 0xa4); + sc035hgs_write_register(ViPipe, 0x3622, 0x05); + sc035hgs_write_register(ViPipe, 0x3624, 0x47); + sc035hgs_write_register(ViPipe, 0x3630, 0x4a); + sc035hgs_write_register(ViPipe, 0x3631, 0x68); + sc035hgs_write_register(ViPipe, 0x3633, 0x52); + sc035hgs_write_register(ViPipe, 0x3635, 0x03); + sc035hgs_write_register(ViPipe, 0x3636, 0x25); + sc035hgs_write_register(ViPipe, 0x3637, 0x8a); + sc035hgs_write_register(ViPipe, 0x3638, 0x0f); + sc035hgs_write_register(ViPipe, 0x3639, 0x08); + sc035hgs_write_register(ViPipe, 0x363a, 0x00); + sc035hgs_write_register(ViPipe, 0x363b, 0x48); + sc035hgs_write_register(ViPipe, 0x363c, 0x86); + sc035hgs_write_register(ViPipe, 0x363e, 0xf8); + sc035hgs_write_register(ViPipe, 0x3640, 0x00); + sc035hgs_write_register(ViPipe, 0x3641, 0x01); + sc035hgs_write_register(ViPipe, 0x36ea, 0x31); + sc035hgs_write_register(ViPipe, 0x36eb, 0x0f); + sc035hgs_write_register(ViPipe, 0x36ec, 0x1f); + sc035hgs_write_register(ViPipe, 0x36ed, 0x20); + sc035hgs_write_register(ViPipe, 0x36fa, 0x36); + sc035hgs_write_register(ViPipe, 0x36fb, 0x10); + sc035hgs_write_register(ViPipe, 0x36fc, 0x02); + sc035hgs_write_register(ViPipe, 0x36fd, 0x00); + sc035hgs_write_register(ViPipe, 0x3908, 0x91); + sc035hgs_write_register(ViPipe, 0x391b, 0x81); + sc035hgs_write_register(ViPipe, 0x3d08, 0x01); + sc035hgs_write_register(ViPipe, 0x3e01, 0x18); + sc035hgs_write_register(ViPipe, 0x3e02, 0xf0); + sc035hgs_write_register(ViPipe, 0x3e03, 0x2b); + sc035hgs_write_register(ViPipe, 0x3e06, 0x0c); + sc035hgs_write_register(ViPipe, 0x3f04, 0x03); + sc035hgs_write_register(ViPipe, 0x3f05, 0x80); + sc035hgs_write_register(ViPipe, 0x4500, 0x59); + sc035hgs_write_register(ViPipe, 0x4501, 0xc4); + sc035hgs_write_register(ViPipe, 0x4603, 0x00); + sc035hgs_write_register(ViPipe, 0x4800, 0x64); + sc035hgs_write_register(ViPipe, 0x4809, 0x01); + sc035hgs_write_register(ViPipe, 0x4810, 0x00); + sc035hgs_write_register(ViPipe, 0x4811, 0x01); + sc035hgs_write_register(ViPipe, 0x4837, 0x30); + sc035hgs_write_register(ViPipe, 0x5011, 0x00); + sc035hgs_write_register(ViPipe, 0x5988, 0x02); + sc035hgs_write_register(ViPipe, 0x598e, 0x05); + sc035hgs_write_register(ViPipe, 0x598f, 0x17); + sc035hgs_write_register(ViPipe, 0x36e9, 0x20); + sc035hgs_write_register(ViPipe, 0x36f9, 0x52); + + sc035hgs_default_reg_init(ViPipe); + + sc035hgs_write_register(ViPipe, 0x0100, 0x01); + sc035hgs_write_register(ViPipe, 0x363d, 0x10); + sc035hgs_write_register(ViPipe, 0x4418, 0x08); + sc035hgs_write_register(ViPipe, 0x4419, 0x80); + + delay_ms(100); + + printf("ViPipe:%d,===SC035HGS 480P 120fps 12bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc200ai/Makefile b/middleware/v2/component/isp/sensor/cv180x/sms_sc200ai/Makefile new file mode 100644 index 000000000..f98c8fb88 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc200ai/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc200ai.a +TARGET_SO = $(MW_LIB)/libsns_sc200ai.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc200ai/sc200ai_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc200ai/sc200ai_cmos.c new file mode 100644 index 000000000..2fd5fa0a9 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc200ai/sc200ai_cmos.c @@ -0,0 +1,1327 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc200ai_cmos_ex.h" +#include "sc200ai_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC200AI_ID 35 +#define SENSOR_SC200AI_WIDTH 1920 +#define SENSOR_SC200AI_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC200AI[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC200AI_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC200AI[dev]) +#define SC200AI_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC200AI[dev] = pstCtx) +#define SC200AI_SENSOR_RESET_CTX(dev) (g_pastSC200AI[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC200AI_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC200AI_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC200AI_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC200AI_STATE_S g_astSC200AI_State[VI_MAX_PIPE_NUM] = {{0} }; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC200AI Lines Range*****/ +#define SC200AI_FULL_LINES_MAX (0x7FFF) +#define SC200AI_FULL_LINES_MAX_2TO1_WDR (0x7FFF) + +/*****SC200AI Register Address*****/ +#define SC200AI_SHS1_0_ADDR 0x3E00 +#define SC200AI_SHS1_1_ADDR 0x3E01 +#define SC200AI_SHS1_2_ADDR 0x3E02 +#define SC200AI_SHS2_0_ADDR 0x3E22 +#define SC200AI_SHS2_1_ADDR 0x3E04 +#define SC200AI_SHS2_2_ADDR 0x3E05 +#define SC200AI_AGAIN1_ADDR 0x3E08 +#define SC200AI_DGAIN1_ADDR 0x3E06 +#define SC200AI_AGAIN2_ADDR 0x3E12 +#define SC200AI_DGAIN2_ADDR 0x3E10 +#define SC200AI_VMAX_ADDR 0x320E +#define SC200AI_MAXSEXP_ADDR 0x3E23 +#define SC200AI_TABLE_END 0xFFFF + +#define SC200AI_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC200AI_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astSC200AI_mode[SC200AI_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC200AI_mode[SC200AI_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 55270; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 32512; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 4; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astSC200AI_mode[SC200AI_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC200AI_mode[SC200AI_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstAeSnsDft->u32MinIntTime = 1; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 55270; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 32512; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + CVI_U16 u16MaxSexpReg; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC200AI_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC200AI_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC200AI_mode[pstSnsState->u8ImgMode].f32MinFps; + u16MaxSexpReg = g_astSC200AI_mode[pstSnsState->u8ImgMode].u16SexpMaxReg; + + switch (pstSnsState->u8ImgMode) { + case SC200AI_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + u16MaxSexpReg = u16MaxSexpReg * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC200AI_FULL_LINES_MAX_2TO1_WDR) ? SC200AI_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case SC200AI_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC200AI_FULL_LINES_MAX) ? SC200AI_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + g_astSC200AI_State[ViPipe].u32Sexp_MAX = u16MaxSexpReg - 5; + } + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + pstSnsRegsInfo->astI2cData[WDR2_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_MAXSEXP_0_ADDR].u32Data = ((u16MaxSexpReg & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_MAXSEXP_1_ADDR].u32Data = u16MaxSexpReg & 0xFF; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + CVI_U16 u16SexpReg, u16LexpReg; + CVI_U32 u32MaxLExp; + + /* short exposure reg range: + * min : 1 + * max : 2 * reg_sexp_max - 10 + * step : 4 + */ + pstSnsState->au32WDRIntTime[0] = (u32ShortIntTime > g_astSC200AI_State[ViPipe].u32Sexp_MAX) ? + g_astSC200AI_State[ViPipe].u32Sexp_MAX : u32ShortIntTime; + if (!pstSnsState->au32WDRIntTime[0]) + pstSnsState->au32WDRIntTime[0] = 1; + /* short exp = SexpReg / 2 */ + u16SexpReg = (CVI_U16)(pstSnsState->au32WDRIntTime[0] * 2 - 1); + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + + /* long exposure reg range: + * min : 1 + * max : 2 * (vts - max sexp) + * step : 4 + */ + u32MaxLExp = pstSnsState->au32FL[0] - g_astSC200AI_State[ViPipe].u32Sexp_MAX; + pstSnsState->au32WDRIntTime[1] = (u32LongIntTime > u32MaxLExp) ? u32MaxLExp : u32LongIntTime; + if (!pstSnsState->au32WDRIntTime[1]) + pstSnsState->au32WDRIntTime[1] = 1; + u16LexpReg = (CVI_U16)(pstSnsState->au32WDRIntTime[1] * 2 - 1); + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + pstSnsRegsInfo->astI2cData[WDR2_SHS1_0_ADDR].u32Data = ((u16LexpReg & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[WDR2_SHS1_1_ADDR].u32Data = ((u16LexpReg & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[WDR2_SHS1_2_ADDR].u32Data = (u16LexpReg & 0xF) << 4; + + pstSnsRegsInfo->astI2cData[WDR2_SHS2_0_ADDR].u32Data = ((u16SexpReg & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[WDR2_SHS2_1_ADDR].u32Data = ((u16SexpReg & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[WDR2_SHS2_2_ADDR].u32Data = (u16SexpReg & 0xF) << 4; + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + CVI_U32 u32TmpIntTime = u32IntTime[0]; + /* linear exposure reg range: + * min : 1 + * max : 2 * (vts - 8) + * step : 1 + */ + u32TmpIntTime = (u32TmpIntTime > (pstSnsState->au32FL[0] - 4)) ? + (pstSnsState->au32FL[0] - 4) : u32TmpIntTime; + u32TmpIntTime = u32TmpIntTime << 1; + if (!u32TmpIntTime) + u32TmpIntTime = 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = (u32TmpIntTime & 0xF) << 4; + } + + return CVI_SUCCESS; + +} + +struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +}; + +static struct gain_tbl_info_s AgainInfo[6] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x03, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 3456, + .idxBase = 64, + .regGain = 0x07, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 6908, + .idxBase = 109, + .regGain = 0x23, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 13817, + .idxBase = 173, + .regGain = 0x27, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 27635, + .idxBase = 237, + .regGain = 0x2f, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 55270, + .idxBase = 301, + .regGain = 0x3f, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, +}; + +static CVI_U32 Again_table[365] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, 1248, 1263, 1280, + 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, 1472, 1487, 1504, 1519, 1536, 1552, + 1567, 1584, 1600, 1615, 1632, 1647, 1664, 1680, 1695, 1712, 1728, 1743, 1760, 1775, 1792, 1808, 1823, + 1840, 1856, 1871, 1888, 1903, 1920, 1936, 1951, 1968, 1984, 1999, 2016, 2031, 2048, 2079, 2112, 2144, + 2176, 2207, 2240, 2272, 2304, 2335, 2368, 2400, 2432, 2463, 2496, 2528, 2560, 2591, 2624, 2656, 2688, + 2719, 2752, 2784, 2816, 2847, 2880, 2912, 2944, 2975, 3008, 3040, 3072, 3103, 3136, 3168, 3200, 3231, + 3264, 3296, 3328, 3359, 3392, 3424, 3456, 3481, 3535, 3590, 3644, 3699, 3753, 3808, 3862, 3916, 3971, + 4025, 4079, 4134, 4189, 4243, 4297, 4352, 4406, 4460, 4514, 4570, 4624, 4678, 4732, 4787, 4841, 4895, + 4950, 5005, 5059, 5113, 5168, 5222, 5276, 5330, 5385, 5440, 5494, 5549, 5603, 5657, 5711, 5766, 5820, + 5875, 5929, 5984, 6038, 6092, 6147, 6201, 6255, 6310, 6365, 6419, 6473, 6528, 6582, 6636, 6690, 6746, + 6800, 6854, 6908, 6963, 7071, 7181, 7289, 7398, 7506, 7616, 7725, 7833, 7942, 8051, 8160, 8268, 8377, + 8486, 8595, 8704, 8812, 8922, 9030, 9139, 9247, 9357, 9465, 9574, 9682, 9792, 9901, 10009, 10118, 10227, + 10336, 10444, 10553, 10662, 10771, 10880, 10988, 11098, 11206, 11315, 11423, 11533, 11641, 11750, 11858, + 11968, 12077, 12185, 12294, 12403, 12512, 12620, 12729, 12838, 12947, 13056, 13164, 13274, 13382, 13491, + 13599, 13709, 13817, 13926, 14144, 14361, 14579, 14796, 15014, 15232, 15450, 15667, 15885, 16102, 16320, + 16537, 16755, 16972, 17190, 17408, 17626, 17843, 18061, 18278, 18496, 18713, 18931, 19148, 19366, 19584, + 19802, 20019, 20237, 20454, 20672, 20889, 21107, 21324, 21542, 21760, 21978, 22195, 22413, 22630, 22848, + 23065, 23283, 23500, 23718, 23936, 24154, 24371, 24589, 24806, 25024, 25241, 25459, 25676, 25894, 26112, + 26330, 26547, 26765, 26982, 27200, 27417, 27635, 27852, 28288, 28723, 29158, 29593, 30028, 30464, 30899, + 31334, 31769, 32204, 32640, 33075, 33510, 33945, 34380, 34816, 35251, 35686, 36121, 36556, 36992, 37427, + 37862, 38297, 38732, 39168, 39603, 40038, 40473, 40908, 41344, 41779, 42214, 42649, 43084, 43520, 43955, + 44390, 44825, 45260, 45696, 46131, 46566, 47001, 47436, 47872, 48307, 48742, 49177, 49612, 50048, 50483, + 50918, 51353, 51788, 52224, 52659, 53094, 53529, 53964, 54400, 54835, 55270 +}; + +static struct gain_tbl_info_s DgainInfo[5] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 8128, + .idxBase = 128, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 16256, + .idxBase = 192, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 32512, + .idxBase = 256, + .regGain = 0x0f, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, +}; + +static CVI_U32 Dgain_table[320] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, 1248, + 1263, 1280, 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, 1472, 1487, + 1504, 1519, 1536, 1552, 1567, 1584, 1600, 1615, 1632, 1647, 1664, 1680, 1695, 1712, 1728, + 1743, 1760, 1775, 1792, 1808, 1823, 1840, 1856, 1871, 1888, 1903, 1920, 1936, 1951, 1968, + 1984, 1999, 2016, 2031, 2048, 2079, 2112, 2144, 2176, 2207, 2240, 2272, 2304, 2335, 2368, + 2400, 2432, 2463, 2496, 2528, 2560, 2591, 2624, 2656, 2688, 2719, 2752, 2784, 2816, 2847, + 2880, 2912, 2944, 2975, 3008, 3040, 3072, 3103, 3136, 3168, 3200, 3231, 3264, 3296, 3328, + 3359, 3392, 3424, 3456, 3487, 3520, 3552, 3584, 3615, 3648, 3680, 3712, 3743, 3776, 3808, + 3840, 3871, 3904, 3936, 3968, 3999, 4032, 4064, 4096, 4160, 4224, 4288, 4352, 4416, 4480, + 4544, 4608, 4672, 4736, 4800, 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, + 5504, 5568, 5632, 5696, 5760, 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, + 6464, 6528, 6592, 6656, 6720, 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, + 7424, 7488, 7552, 7616, 7680, 7744, 7808, 7872, 7936, 8000, 8064, 8128, 8192, 8320, 8448, + 8576, 8704, 8832, 8960, 9088, 9216, 9344, 9472, 9600, 9728, 9856, 9984, 10112, 10240, 10368, + 10496, 10624, 10752, 10880, 11008, 11136, 11264, 11392, 11520, 11648, 11776, 11904, 12032, + 12160, 12288, 12416, 12544, 12672, 12800, 12928, 13056, 13184, 13312, 13440, 13568, 13696, + 13824, 13952, 14080, 14208, 14336, 14464, 14592, 14720, 14848, 14976, 15104, 15232, 15360, + 15488, 15616, 15744, 15872, 16000, 16128, 16256, 16384, 16640, 16896, 17152, 17408, 17664, + 17920, 18176, 18432, 18688, 18944, 19200, 19456, 19712, 19968, 20224, 20480, 20736, 20992, + 21248, 21504, 21760, 22016, 22272, 22528, 22784, 23040, 23296, 23552, 23808, 24064, 24320, + 24576, 24832, 25088, 25344, 25600, 25856, 26112, 26368, 26624, 26880, 27136, 27392, 27648, + 27904, 28160, 28416, 28672, 28928, 29184, 29440, 29696, 29952, 30208, 30464, 30720, 30976, + 31232, 31488, 31744, 32000, 32256, 32512 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[364]) { + *pu32AgainLin = Again_table[364]; + *pu32AgainDb = 364; + return CVI_SUCCESS; + } + + for (i = 1; i < 365; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[319]) { + *pu32DgainLin = Dgain_table[319]; + *pu32DgainDb = 319; + return CVI_SUCCESS; + } + + for (i = 1; i < 320; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u16Mode = g_au16SC200AI_GainMode[ViPipe]; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + static bool bGainLogicChanged[VI_MAX_PIPE_NUM] = {true}; + + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + // control sensor DPC to fix high-gain noise + if (Again_table[u32Again] >= 30720 && bGainLogicChanged[ViPipe]) { + sc200ai_write_register(ViPipe, 0x5799, 0x7); + bGainLogicChanged[ViPipe] = false; + } else if (Again_table[u32Again] <= 20480 && !bGainLogicChanged[ViPipe]) { + sc200ai_write_register(ViPipe, 0x5799, 0x0); + bGainLogicChanged[ViPipe] = true; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1_ADDR].u32Data = (u32Dgain & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + /* find SEF Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find SEF Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_1_ADDR].u32Data = (u32Dgain & 0xFF); + + u32Again = pu32Again[1]; + u32Dgain = pu32Dgain[1]; + + /* find LEF Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find LEF Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_1_ADDR].u32Data = (u32Dgain & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_0_ADDR].u32Data = (info->regGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_1_ADDR].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_0_ADDR].u32Data = (info->regGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_1_ADDR].u32Data = (u32Dgain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_1_ADDR].u32Data = (u32Dgain & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0; + CVI_U32 u32ShortTimeMinLimit = 1; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + (void) u16ManRatioEnable; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + /* short exposure reg range: + * min : 1 + * max : 2 * (max sexp - 5) + * step : 4 + * long exposure reg range: + * min : 1 + * max : 2 * (vts - max sexp - 5) + * step : 4 + */ + u32IntTimeMaxTmp = ((2 * pstSnsState->au32FL[0] - 10) * 0x40) / (au32Ratio[0] + 0x40) / 4 * 4; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astSC200AI_State[ViPipe].u32Sexp_MAX * 2)) ? + (g_astSC200AI_State[ViPipe].u32Sexp_MAX * 2) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? u32ShortTimeMinLimit : u32IntTimeMaxTmp; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + /* [TODO] Convert to 1-line unit */ + u32IntTimeMaxTmp = (u32IntTimeMaxTmp - 1) / 2; + u32ShortTimeMinLimit = (u32ShortTimeMinLimit + 1) / 2; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + syslog(LOG_DEBUG, "ViPipe = %d ratio = %d, (%d, %d)\n", ViPipe, au32Ratio[0], + u32IntTimeMaxTmp, u32ShortTimeMinLimit); + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC200AI_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC200AI_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == SC200AI_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = SC200AI_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC200AI_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == SC200AI_MODE_1080P30) + pstSnsState->u8ImgMode = SC200AI_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astSC200AI_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "2to1 line WDR 1080p mode(60fps->30fps)\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC200AI_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc200ai_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc200ai_addr_byte; + pstI2c_data[i].u32DataByteNum = sc200ai_data_byte; + } + + //DOL 2t1 Mode Regs + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + //WDR Mode Regs + pstI2c_data[WDR2_SHS1_0_ADDR].u32RegAddr = SC200AI_SHS1_0_ADDR; + pstI2c_data[WDR2_SHS1_1_ADDR].u32RegAddr = SC200AI_SHS1_1_ADDR; + pstI2c_data[WDR2_SHS1_2_ADDR].u32RegAddr = SC200AI_SHS1_2_ADDR; + pstI2c_data[WDR2_SHS2_0_ADDR].u32RegAddr = SC200AI_SHS2_0_ADDR; + pstI2c_data[WDR2_SHS2_1_ADDR].u32RegAddr = SC200AI_SHS2_1_ADDR; + pstI2c_data[WDR2_SHS2_2_ADDR].u32RegAddr = SC200AI_SHS2_2_ADDR; + pstI2c_data[WDR2_AGAIN1_0_ADDR].u32RegAddr = SC200AI_AGAIN1_ADDR; + pstI2c_data[WDR2_AGAIN1_1_ADDR].u32RegAddr = SC200AI_AGAIN1_ADDR + 1; + pstI2c_data[WDR2_DGAIN1_0_ADDR].u32RegAddr = SC200AI_DGAIN1_ADDR; + pstI2c_data[WDR2_DGAIN1_1_ADDR].u32RegAddr = SC200AI_DGAIN1_ADDR + 1; + pstI2c_data[WDR2_AGAIN2_0_ADDR].u32RegAddr = SC200AI_AGAIN2_ADDR; + pstI2c_data[WDR2_AGAIN2_1_ADDR].u32RegAddr = SC200AI_AGAIN2_ADDR + 1; + pstI2c_data[WDR2_DGAIN2_0_ADDR].u32RegAddr = SC200AI_DGAIN2_ADDR; + pstI2c_data[WDR2_DGAIN2_1_ADDR].u32RegAddr = SC200AI_DGAIN2_ADDR + 1; + pstI2c_data[WDR2_VMAX_0_ADDR].u32RegAddr = SC200AI_VMAX_ADDR; + pstI2c_data[WDR2_VMAX_1_ADDR].u32RegAddr = SC200AI_VMAX_ADDR + 1; + pstI2c_data[WDR2_MAXSEXP_0_ADDR].u32RegAddr = SC200AI_MAXSEXP_ADDR; + pstI2c_data[WDR2_MAXSEXP_1_ADDR].u32RegAddr = SC200AI_MAXSEXP_ADDR + 1; + + break; + default: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC200AI_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC200AI_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC200AI_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC200AI_AGAIN1_ADDR; + pstI2c_data[LINEAR_AGAIN_1_ADDR].u32RegAddr = SC200AI_AGAIN1_ADDR + 1; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC200AI_DGAIN1_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC200AI_DGAIN1_ADDR + 1; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC200AI_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC200AI_VMAX_ADDR + 1; + + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC200AI_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC200AI_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (SC200AI_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC200AI_MODE_1080P30_WDR; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC200AI_MODE_S *pstMode = CVI_NULL; + + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC200AI_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC200AI_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc200ai_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC200AI_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC200AI_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc200ai_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc200ai_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc200ai_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc200ai_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC200AI_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC200AI_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC200AI_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC200AI_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC200AI_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC200AI_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC200AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC200AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC200AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC200AI_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC200AI_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC200AI_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc200ai_standby, + .pfnRestart = sc200ai_restart, + .pfnMirrorFlip = sc200ai_mirror_flip, + .pfnWriteReg = sc200ai_write_register, + .pfnReadReg = sc200ai_read_register, + .pfnSetBusInfo = sc200ai_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc200ai_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc200ai/sc200ai_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc200ai/sc200ai_cmos_ex.h new file mode 100644 index 000000000..07ce23225 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc200ai/sc200ai_cmos_ex.h @@ -0,0 +1,108 @@ +#ifndef __SC200AI_CMOS_EX_H_ +#define __SC200AI_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc200ai_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_2_ADDR, + LINEAR_AGAIN_0_ADDR, + LINEAR_AGAIN_1_ADDR, + LINEAR_DGAIN_0_ADDR, + LINEAR_DGAIN_1_ADDR, + LINEAR_VMAX_0_ADDR, + LINEAR_VMAX_1_ADDR, + LINEAR_REGS_NUM +}; + +enum sc200ai_dol2_regs_e { + WDR2_SHS1_0_ADDR, + WDR2_SHS1_1_ADDR, + WDR2_SHS1_2_ADDR, + WDR2_SHS2_0_ADDR, + WDR2_SHS2_1_ADDR, + WDR2_SHS2_2_ADDR, + WDR2_AGAIN1_0_ADDR, + WDR2_AGAIN1_1_ADDR, + WDR2_DGAIN1_0_ADDR, + WDR2_DGAIN1_1_ADDR, + WDR2_AGAIN2_0_ADDR, + WDR2_AGAIN2_1_ADDR, + WDR2_DGAIN2_0_ADDR, + WDR2_DGAIN2_1_ADDR, + WDR2_VMAX_0_ADDR, + WDR2_VMAX_1_ADDR, + WDR2_MAXSEXP_0_ADDR, + WDR2_MAXSEXP_1_ADDR, + WDR2_REGS_NUM +}; + +typedef enum _SC200AI_MODE_E { + SC200AI_MODE_1080P30 = 0, + SC200AI_MODE_LINEAR_NUM, + SC200AI_MODE_1080P30_WDR = SC200AI_MODE_LINEAR_NUM, + SC200AI_MODE_NUM +} SC200AI_MODE_E; + +typedef struct _SC200AI_STATE_S { + CVI_U32 u32Sexp_MAX; /* (2*{16’h3e23,16’h3e24} – 'd10)/2 */ +} SC200AI_STATE_S; + +typedef struct _SC200AI_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16SexpMaxReg; /* {16’h3e23,16’h3e24} */ + char name[64]; +} SC200AI_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC200AI[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC200AI_BusInfo[]; +extern CVI_U16 g_au16SC200AI_GainMode[]; +extern CVI_U16 g_au16SC200AI_L2SMode[]; +extern const CVI_U8 sc200ai_i2c_addr; +extern const CVI_U32 sc200ai_addr_byte; +extern const CVI_U32 sc200ai_data_byte; +extern void sc200ai_init(VI_PIPE ViPipe); +extern void sc200ai_exit(VI_PIPE ViPipe); +extern void sc200ai_standby(VI_PIPE ViPipe); +extern void sc200ai_restart(VI_PIPE ViPipe); +extern int sc200ai_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc200ai_read_register(VI_PIPE ViPipe, int addr); +extern void sc200ai_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc200ai_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC200AI_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc200ai/sc200ai_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc200ai/sc200ai_cmos_param.h new file mode 100644 index 000000000..1a02c07e5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc200ai/sc200ai_cmos_param.h @@ -0,0 +1,265 @@ +#ifndef __SC200AI_CMOS_PARAM_H_ +#define __SC200AI_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc200ai_cmos_ex.h" + +static const SC200AI_MODE_S g_astSC200AI_mode[SC200AI_MODE_NUM] = { + [SC200AI_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.03, /* 1125 * 30 / 0x7FFF*/ + .u32HtsDef = 2560, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1121, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 4096, + .u16Def = 1024, + .u16Step = 1, + }, + }, + [SC200AI_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.06, /* 2250 * 30 / 0x7FFF*/ + .u32HtsDef = 640, + .u32VtsDef = 2250, + .u16SexpMaxReg = 0x13E, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.02792946062982082367, 3.36534714698791503906}, //B: slope, intercept + {0.02071751467883586884, 5.34583568572998046875}, //Gb: slope, intercept + {0.02110148966312408447, 5.02954530715942382813}, //Gr: slope, intercept + {0.02168512716889381409, 4.89776754379272460938}, //R: slope, intercept + }, + { //iso 200 + {0.03194080293178558350, 5.61192893981933593750}, //B: slope, intercept + {0.02428408525884151459, 7.94834280014038085938}, //Gb: slope, intercept + {0.02499442733824253082, 7.72430133819580078125}, //Gr: slope, intercept + {0.02584112435579299927, 7.20574426651000976563}, //R: slope, intercept + }, + { //iso 400 + {0.04612467437982559204, 6.88752269744873046875}, //B: slope, intercept + {0.03022909909486770630, 11.05101776123046875000}, //Gb: slope, intercept + {0.03175539523363113403, 10.60332489013671875000}, //Gr: slope, intercept + {0.03522306308150291443, 9.36425399780273437500}, //R: slope, intercept + }, + { //iso 800 + {0.06092500314116477966, 9.79670524597167968750}, //B: slope, intercept + {0.03984217345714569092, 15.30182266235351562500}, //Gb: slope, intercept + {0.04019560664892196655, 14.93132972717285156250}, //Gr: slope, intercept + {0.04470816254615783691, 13.26843166351318359375}, //R: slope, intercept + }, + { //iso 1600 + {0.08295634388923645020, 14.20334625244140625000}, //B: slope, intercept + {0.05075264349579811096, 20.99221038818359375000}, //Gb: slope, intercept + {0.05426201224327087402, 20.08068656921386718750}, //Gr: slope, intercept + {0.05945669487118721008, 19.02898788452148437500}, //R: slope, intercept + }, + { //iso 3200 + {0.09782519936561584473, 21.84967994689941406250}, //B: slope, intercept + {0.06690908223390579224, 26.53993988037109375000}, //Gb: slope, intercept + {0.06954573839902877808, 25.74129104614257812500}, //Gr: slope, intercept + {0.09061723947525024414, 22.98998260498046875000}, //R: slope, intercept + }, + { //iso 6400 + {0.14311420917510986328, 28.96467971801757812500}, //B: slope, intercept + {0.08148498833179473877, 37.93062591552734375000}, //Gb: slope, intercept + {0.08273542672395706177, 38.37096405029296875000}, //Gr: slope, intercept + {0.12093253433704376221, 33.31475067138671875000}, //R: slope, intercept + }, + { //iso 12800 + {0.17958122491836547852, 43.49506759643554687500}, //B: slope, intercept + {0.09839969873428344727, 55.43268966674804687500}, //Gb: slope, intercept + {0.10201884806156158447, 52.97607040405273437500}, //Gr: slope, intercept + {0.15302789211273193359, 47.54779434204101562500}, //R: slope, intercept + }, + { //iso 25600 + {0.25833165645599365234, 56.96470642089843750000}, //B: slope, intercept + {0.13260601460933685303, 74.69016265869140625000}, //Gb: slope, intercept + {0.14035490155220031738, 75.44366455078125000000}, //Gr: slope, intercept + {0.23465165495872497559, 60.52228164672851562500}, //R: slope, intercept + }, + { //iso 51200 + {0.37595292925834655762, 78.54853057861328125000}, //B: slope, intercept + {0.21475413441658020020, 102.12300872802734375000}, //Gb: slope, intercept + {0.20840260386466979980, 103.65763854980468750000}, //Gr: slope, intercept + {0.34428051114082336426, 87.83551025390625000000}, //R: slope, intercept + }, + { //iso 102400 + {0.51122575998306274414, 113.49224090576171875000}, //B: slope, intercept + {0.29245173931121826172, 154.26939392089843750000}, //Gb: slope, intercept + {0.31501635909080505371, 148.29017639160156250000}, //Gr: slope, intercept + {0.47034618258476257324, 124.06208038330078125000}, //R: slope, intercept + }, + { //iso 204800 + {0.67213481664657592773, 134.71751403808593750000}, //B: slope, intercept + {0.40368056297302246094, 189.80801391601562500000}, //Gb: slope, intercept + {0.43581819534301757813, 186.44682312011718750000}, //Gr: slope, intercept + {0.60127359628677368164, 160.66384887695312500000}, //R: slope, intercept + }, + { //iso 409600 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 819200 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {257, 260, 260, 260, 260, 261, 259, 258, /*8*/255, 248, 264, 300, 291, 310, 310, 311}, + {257, 260, 260, 260, 260, 261, 259, 257, /*8*/254, 247, 261, 296, 287, 309, 309, 306}, + {257, 260, 260, 260, 260, 261, 259, 257, /*8*/255, 248, 262, 298, 289, 308, 308, 308}, + {257, 260, 260, 260, 260, 261, 259, 258, /*8*/255, 247, 261, 301, 293, 310, 308, 314}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1095, 1105, 1102, 1108, 1108, 1108}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1104, 1101, 1108, 1108, 1107}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1104, 1102, 1107, 1107, 1107}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1105, 1103, 1108, 1107, 1109}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc200ai_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 0, 4, -1, -1}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + .dphy = { + .enable = 1, + .hs_settle = 8, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC200AI_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc200ai/sc200ai_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc200ai/sc200ai_sensor_ctl.c new file mode 100644 index 000000000..d38ca7396 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc200ai/sc200ai_sensor_ctl.c @@ -0,0 +1,511 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc200ai_cmos_ex.h" + +static void sc200ai_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void sc200ai_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc200ai_i2c_addr = 0x30; /* I2C Address of SC200AI */ +const CVI_U32 sc200ai_addr_byte = 2; +const CVI_U32 sc200ai_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc200ai_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC200AI_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc200ai_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc200ai_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc200ai_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc200ai_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc200ai_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc200ai_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc200ai_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc200ai_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc200ai_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc200ai_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc200ai_addr_byte + sc200ai_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc200ai_standby(VI_PIPE ViPipe) +{ + sc200ai_write_register(ViPipe, 0x0100, 0x00); +} + +void sc200ai_restart(VI_PIPE ViPipe) +{ + sc200ai_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc200ai_write_register(ViPipe, 0x0100, 0x01); +} + +void sc200ai_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC200AI[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc200ai_write_register(ViPipe, + g_pastSC200AI[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC200AI[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC200AI_CHIP_ID_HI_ADDR 0x3107 +#define SC200AI_CHIP_ID_LO_ADDR 0x3108 +#define SC200AI_CHIP_ID 0xcb1c + +void sc200ai_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc200ai_write_register(ViPipe, 0x3221, val); +} + +int sc200ai_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + delay_ms(4); + if (sc200ai_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc200ai_read_register(ViPipe, SC200AI_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc200ai_read_register(ViPipe, SC200AI_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC200AI_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc200ai_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + CVI_U8 u8ImgMode; + + bInit = g_pastSC200AI[ViPipe]->bInit; + enWDRMode = g_pastSC200AI[ViPipe]->enWDRMode; + u8ImgMode = g_pastSC200AI[ViPipe]->u8ImgMode; + + sc200ai_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == SC200AI_MODE_1080P30_WDR) { + /* SC200AI_MODE_1080P30_WDR */ + sc200ai_wdr_1080p30_2to1_init(ViPipe); + } else { + } + } else { + sc200ai_linear_1080p30_init(ViPipe); + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == SC200AI_MODE_1080P30_WDR) { + /* SC200AI_MODE_1080P30_WDR */ + sc200ai_wdr_1080p30_2to1_init(ViPipe); + } else { + } + } else { + sc200ai_linear_1080p30_init(ViPipe); + } + } + g_pastSC200AI[ViPipe]->bInit = CVI_TRUE; +} + +void sc200ai_exit(VI_PIPE ViPipe) +{ + sc200ai_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void sc200ai_linear_1080p30_init(VI_PIPE ViPipe) +{ + sc200ai_write_register(ViPipe, 0x0103, 0x01); + sc200ai_write_register(ViPipe, 0x0100, 0x00); + sc200ai_write_register(ViPipe, 0x36e9, 0x80); + sc200ai_write_register(ViPipe, 0x36f9, 0x80); + sc200ai_write_register(ViPipe, 0x59e0, 0x60); + sc200ai_write_register(ViPipe, 0x59e1, 0x08); + sc200ai_write_register(ViPipe, 0x59e2, 0x3f); + sc200ai_write_register(ViPipe, 0x59e3, 0x18); + sc200ai_write_register(ViPipe, 0x59e4, 0x18); + sc200ai_write_register(ViPipe, 0x59e5, 0x3f); + sc200ai_write_register(ViPipe, 0x59e6, 0x06); + sc200ai_write_register(ViPipe, 0x59e7, 0x02); + sc200ai_write_register(ViPipe, 0x59e8, 0x38); + sc200ai_write_register(ViPipe, 0x59e9, 0x10); + sc200ai_write_register(ViPipe, 0x59ea, 0x0c); + sc200ai_write_register(ViPipe, 0x59eb, 0x10); + sc200ai_write_register(ViPipe, 0x59ec, 0x04); + sc200ai_write_register(ViPipe, 0x59ed, 0x02); + sc200ai_write_register(ViPipe, 0x59ee, 0xa0); + sc200ai_write_register(ViPipe, 0x59ef, 0x08); + sc200ai_write_register(ViPipe, 0x59f4, 0x18); + sc200ai_write_register(ViPipe, 0x59f5, 0x10); + sc200ai_write_register(ViPipe, 0x59f6, 0x0c); + sc200ai_write_register(ViPipe, 0x59f7, 0x10); + sc200ai_write_register(ViPipe, 0x59f8, 0x06); + sc200ai_write_register(ViPipe, 0x59f9, 0x02); + sc200ai_write_register(ViPipe, 0x59fa, 0x18); + sc200ai_write_register(ViPipe, 0x59fb, 0x10); + sc200ai_write_register(ViPipe, 0x59fc, 0x0c); + sc200ai_write_register(ViPipe, 0x59fd, 0x10); + sc200ai_write_register(ViPipe, 0x59fe, 0x04); + sc200ai_write_register(ViPipe, 0x59ff, 0x02); + sc200ai_write_register(ViPipe, 0x3e16, 0x00); + sc200ai_write_register(ViPipe, 0x3e17, 0x80); + sc200ai_write_register(ViPipe, 0x3f09, 0x48); + sc200ai_write_register(ViPipe, 0x3e01, 0x8c); + sc200ai_write_register(ViPipe, 0x3e02, 0x20); + sc200ai_write_register(ViPipe, 0x391f, 0x18); + sc200ai_write_register(ViPipe, 0x363a, 0x1f); + sc200ai_write_register(ViPipe, 0x3637, 0x1b); + sc200ai_write_register(ViPipe, 0x391d, 0x14); + sc200ai_write_register(ViPipe, 0x330b, 0x88); + sc200ai_write_register(ViPipe, 0x3908, 0x41); + sc200ai_write_register(ViPipe, 0x3333, 0x10); + sc200ai_write_register(ViPipe, 0x3301, 0x20); + sc200ai_write_register(ViPipe, 0x3304, 0x40); + sc200ai_write_register(ViPipe, 0x331e, 0x39); + sc200ai_write_register(ViPipe, 0x330f, 0x02); + sc200ai_write_register(ViPipe, 0x3306, 0x32); + sc200ai_write_register(ViPipe, 0x363c, 0x0e); + sc200ai_write_register(ViPipe, 0x363b, 0xc6); + sc200ai_write_register(ViPipe, 0x3622, 0x16); + sc200ai_write_register(ViPipe, 0x5787, 0x10); + sc200ai_write_register(ViPipe, 0x5788, 0x06); + sc200ai_write_register(ViPipe, 0x578a, 0x10); + sc200ai_write_register(ViPipe, 0x578b, 0x06); + sc200ai_write_register(ViPipe, 0x5790, 0x10); + sc200ai_write_register(ViPipe, 0x5791, 0x10); + sc200ai_write_register(ViPipe, 0x5792, 0x00); + sc200ai_write_register(ViPipe, 0x5793, 0x10); + sc200ai_write_register(ViPipe, 0x5794, 0x10); + sc200ai_write_register(ViPipe, 0x5795, 0x00); + sc200ai_write_register(ViPipe, 0x5799, 0x00); + sc200ai_write_register(ViPipe, 0x57c7, 0x10); + sc200ai_write_register(ViPipe, 0x57c8, 0x06); + sc200ai_write_register(ViPipe, 0x57ca, 0x10); + sc200ai_write_register(ViPipe, 0x57cb, 0x06); + sc200ai_write_register(ViPipe, 0x57d1, 0x10); + sc200ai_write_register(ViPipe, 0x57d4, 0x10); + sc200ai_write_register(ViPipe, 0x57d9, 0x00); + sc200ai_write_register(ViPipe, 0x369c, 0x40); + sc200ai_write_register(ViPipe, 0x369d, 0x48); + sc200ai_write_register(ViPipe, 0x3690, 0x34); + sc200ai_write_register(ViPipe, 0x3691, 0x33); + sc200ai_write_register(ViPipe, 0x3692, 0x44); + sc200ai_write_register(ViPipe, 0x3670, 0x0a); + sc200ai_write_register(ViPipe, 0x367c, 0x48); + sc200ai_write_register(ViPipe, 0x367d, 0x58); + sc200ai_write_register(ViPipe, 0x3674, 0x82); + sc200ai_write_register(ViPipe, 0x3675, 0x76); + sc200ai_write_register(ViPipe, 0x3676, 0x78); + sc200ai_write_register(ViPipe, 0x3253, 0x08); + sc200ai_write_register(ViPipe, 0x301f, 0x03); + sc200ai_write_register(ViPipe, 0x36e9, 0x20); + sc200ai_write_register(ViPipe, 0x36f9, 0x27); + + sc200ai_default_reg_init(ViPipe); + + sc200ai_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC200AI 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +static void sc200ai_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + sc200ai_write_register(ViPipe, 0x0103, 0x01); + sc200ai_write_register(ViPipe, 0x0100, 0x00); + sc200ai_write_register(ViPipe, 0x36e9, 0x80); + sc200ai_write_register(ViPipe, 0x36f9, 0x80); + sc200ai_write_register(ViPipe, 0x59e0, 0x60); + sc200ai_write_register(ViPipe, 0x59e1, 0x08); + sc200ai_write_register(ViPipe, 0x59e2, 0x3f); + sc200ai_write_register(ViPipe, 0x59e3, 0x18); + sc200ai_write_register(ViPipe, 0x59e4, 0x18); + sc200ai_write_register(ViPipe, 0x59e5, 0x3f); + sc200ai_write_register(ViPipe, 0x59e6, 0x06); + sc200ai_write_register(ViPipe, 0x59e7, 0x02); + sc200ai_write_register(ViPipe, 0x59e8, 0x38); + sc200ai_write_register(ViPipe, 0x59e9, 0x10); + sc200ai_write_register(ViPipe, 0x59ea, 0x0c); + sc200ai_write_register(ViPipe, 0x59eb, 0x10); + sc200ai_write_register(ViPipe, 0x59ec, 0x04); + sc200ai_write_register(ViPipe, 0x59ed, 0x02); + sc200ai_write_register(ViPipe, 0x59ee, 0xa0); + sc200ai_write_register(ViPipe, 0x59ef, 0x08); + sc200ai_write_register(ViPipe, 0x59f4, 0x18); + sc200ai_write_register(ViPipe, 0x59f5, 0x10); + sc200ai_write_register(ViPipe, 0x59f6, 0x0c); + sc200ai_write_register(ViPipe, 0x59f7, 0x10); + sc200ai_write_register(ViPipe, 0x59f8, 0x06); + sc200ai_write_register(ViPipe, 0x59f9, 0x02); + sc200ai_write_register(ViPipe, 0x59fa, 0x18); + sc200ai_write_register(ViPipe, 0x59fb, 0x10); + sc200ai_write_register(ViPipe, 0x59fc, 0x0c); + sc200ai_write_register(ViPipe, 0x59fd, 0x10); + sc200ai_write_register(ViPipe, 0x59fe, 0x04); + sc200ai_write_register(ViPipe, 0x59ff, 0x02); + sc200ai_write_register(ViPipe, 0x3e16, 0x00); + sc200ai_write_register(ViPipe, 0x3e17, 0x80); + sc200ai_write_register(ViPipe, 0x3f09, 0x48); + sc200ai_write_register(ViPipe, 0x391f, 0x10); + sc200ai_write_register(ViPipe, 0x363a, 0x1f); + sc200ai_write_register(ViPipe, 0x3908, 0x41); + sc200ai_write_register(ViPipe, 0x330d, 0x16); + sc200ai_write_register(ViPipe, 0x3302, 0x0c); + sc200ai_write_register(ViPipe, 0x3303, 0x08); + sc200ai_write_register(ViPipe, 0x3308, 0x10); + sc200ai_write_register(ViPipe, 0x3310, 0x02); + sc200ai_write_register(ViPipe, 0x334c, 0x08); + sc200ai_write_register(ViPipe, 0x330f, 0x02); + sc200ai_write_register(ViPipe, 0x330e, 0x1c); + sc200ai_write_register(ViPipe, 0x331c, 0x04); + sc200ai_write_register(ViPipe, 0x3320, 0x07); + sc200ai_write_register(ViPipe, 0x33ac, 0x08); + sc200ai_write_register(ViPipe, 0x33ae, 0x10); + sc200ai_write_register(ViPipe, 0x3356, 0x09); + sc200ai_write_register(ViPipe, 0x33af, 0x19); + sc200ai_write_register(ViPipe, 0x3333, 0x10); + sc200ai_write_register(ViPipe, 0x3622, 0x16); + sc200ai_write_register(ViPipe, 0x3630, 0xa0); + sc200ai_write_register(ViPipe, 0x36eb, 0x0c); + sc200ai_write_register(ViPipe, 0x36ec, 0x0c); + sc200ai_write_register(ViPipe, 0x36fd, 0x14); + sc200ai_write_register(ViPipe, 0x5787, 0x10); + sc200ai_write_register(ViPipe, 0x5788, 0x06); + sc200ai_write_register(ViPipe, 0x578a, 0x10); + sc200ai_write_register(ViPipe, 0x578b, 0x06); + sc200ai_write_register(ViPipe, 0x5790, 0x10); + sc200ai_write_register(ViPipe, 0x5791, 0x10); + sc200ai_write_register(ViPipe, 0x5792, 0x00); + sc200ai_write_register(ViPipe, 0x5793, 0x10); + sc200ai_write_register(ViPipe, 0x5794, 0x10); + sc200ai_write_register(ViPipe, 0x5795, 0x00); + sc200ai_write_register(ViPipe, 0x5799, 0x00); + sc200ai_write_register(ViPipe, 0x57c7, 0x10); + sc200ai_write_register(ViPipe, 0x57c8, 0x06); + sc200ai_write_register(ViPipe, 0x57ca, 0x10); + sc200ai_write_register(ViPipe, 0x57cb, 0x06); + sc200ai_write_register(ViPipe, 0x57d1, 0x10); + sc200ai_write_register(ViPipe, 0x57d4, 0x10); + sc200ai_write_register(ViPipe, 0x57d9, 0x00); + sc200ai_write_register(ViPipe, 0x3364, 0x17); + sc200ai_write_register(ViPipe, 0x3390, 0x08); + sc200ai_write_register(ViPipe, 0x3391, 0x18); + sc200ai_write_register(ViPipe, 0x3392, 0x38); + sc200ai_write_register(ViPipe, 0x3301, 0x06); + sc200ai_write_register(ViPipe, 0x3393, 0x06); + sc200ai_write_register(ViPipe, 0x3394, 0x06); + sc200ai_write_register(ViPipe, 0x3395, 0x06); + sc200ai_write_register(ViPipe, 0x3396, 0x08); + sc200ai_write_register(ViPipe, 0x3397, 0x18); + sc200ai_write_register(ViPipe, 0x3398, 0x38); + sc200ai_write_register(ViPipe, 0x3399, 0x06); + sc200ai_write_register(ViPipe, 0x339a, 0x0a); + sc200ai_write_register(ViPipe, 0x339b, 0x10); + sc200ai_write_register(ViPipe, 0x339c, 0x20); + sc200ai_write_register(ViPipe, 0x369c, 0x40); + sc200ai_write_register(ViPipe, 0x369d, 0x48); + sc200ai_write_register(ViPipe, 0x3690, 0x34); + sc200ai_write_register(ViPipe, 0x3691, 0x33); + sc200ai_write_register(ViPipe, 0x3692, 0x44); + sc200ai_write_register(ViPipe, 0x3670, 0x0a); + sc200ai_write_register(ViPipe, 0x367c, 0x48); + sc200ai_write_register(ViPipe, 0x367d, 0x58); + sc200ai_write_register(ViPipe, 0x3674, 0x82); + sc200ai_write_register(ViPipe, 0x3675, 0x76); + sc200ai_write_register(ViPipe, 0x3676, 0x78); + sc200ai_write_register(ViPipe, 0x3637, 0x36); + sc200ai_write_register(ViPipe, 0x3304, 0x60); + sc200ai_write_register(ViPipe, 0x3309, 0x70); + sc200ai_write_register(ViPipe, 0x331e, 0x51); + sc200ai_write_register(ViPipe, 0x331f, 0x61); + sc200ai_write_register(ViPipe, 0x3306, 0x30); + sc200ai_write_register(ViPipe, 0x330b, 0x80); + sc200ai_write_register(ViPipe, 0x363c, 0x0e); + sc200ai_write_register(ViPipe, 0x363b, 0xc6); + sc200ai_write_register(ViPipe, 0x3253, 0x08); + sc200ai_write_register(ViPipe, 0x3220, 0x53); + sc200ai_write_register(ViPipe, 0x3250, 0x3f); + sc200ai_write_register(ViPipe, 0x320e, 0x08); + sc200ai_write_register(ViPipe, 0x320f, 0xca); + sc200ai_write_register(ViPipe, 0x4816, 0xb1); + sc200ai_write_register(ViPipe, 0x3e00, 0x01); + sc200ai_write_register(ViPipe, 0x3e01, 0x06); + sc200ai_write_register(ViPipe, 0x3e02, 0x00); + sc200ai_write_register(ViPipe, 0x3e04, 0x10); + sc200ai_write_register(ViPipe, 0x3e05, 0x60); + sc200ai_write_register(ViPipe, 0x3e06, 0x00); + sc200ai_write_register(ViPipe, 0x3e07, 0x80); + sc200ai_write_register(ViPipe, 0x3e08, 0x03); + sc200ai_write_register(ViPipe, 0x3e09, 0x40); + sc200ai_write_register(ViPipe, 0x3e10, 0x00); + sc200ai_write_register(ViPipe, 0x3e11, 0x80); + sc200ai_write_register(ViPipe, 0x3e12, 0x03); + sc200ai_write_register(ViPipe, 0x3e13, 0x40); + sc200ai_write_register(ViPipe, 0x3e23, 0x00); + sc200ai_write_register(ViPipe, 0x3e24, 0x88); + sc200ai_write_register(ViPipe, 0x301f, 0x02); + sc200ai_write_register(ViPipe, 0x36e9, 0x20); + sc200ai_write_register(ViPipe, 0x36f9, 0x24); + + sc200ai_default_reg_init(ViPipe); + + sc200ai_write_register(ViPipe, 0x0100, 0x01); + + delay_ms(50); + + printf("===SC200AI sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc2335/Makefile b/middleware/v2/component/isp/sensor/cv180x/sms_sc2335/Makefile new file mode 100644 index 000000000..8bd9dde45 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc2335/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc2335.a +TARGET_SO = $(MW_LIB)/libsns_sc2335.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc2335/sc2335_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc2335/sc2335_cmos.c new file mode 100644 index 000000000..b618ef02c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc2335/sc2335_cmos.c @@ -0,0 +1,1058 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" + +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc2335_cmos_ex.h" +#include "sc2335_cmos_param.h" + + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC2335_ID 2335 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC2335[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC2335_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC2335[dev]) +#define SC2335_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC2335[dev] = pstCtx) +#define SC2335_SENSOR_RESET_CTX(dev) (g_pastSC2335[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC2335_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC2335_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC2335_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc2335_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC2335 Lines Range*****/ +#define SC2335_FULL_LINES_MAX (0x7FFF) + +/*****SC2335 Register Address*****/ +#define SC2335_EXP_H_ADDR (0x3e00) +#define SC2335_EXP_M_ADDR (0x3e01) +#define SC2335_EXP_L_ADDR (0x3e02) + +#define SC2335_AGAIN_H_ADDR (0x3e08) +#define SC2335_AGAIN_L_ADDR (0x3e09) + +#define SC2335_DGAIN_H_ADDR (0x3e06) +#define SC2335_DGAIN_L_ADDR (0x3e07) + +#define SC2335_VMAX_H_ADDR (0x320e) +#define SC2335_VMAX_L_ADDR (0x320f) + +#define SC2335_GAIN_LOGIC_ADDR (0x363c) + +#define SC2335_GAIN_DPC_ADDR (0x5799) +#define SC2335_HOLD_ADDR (0x3812) + +#define SC2335_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +#define SC2335_EXPACCURACY (0.5) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC2335_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC2335_mode[pstSnsState->u8ImgMode]; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC2335_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC2335_EXPACCURACY; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = pstAeSnsDft->u32MaxIntTime; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC2335_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC2335_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC2335_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC2335_MODE_1920X1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC2335_FULL_LINES_MAX) ? SC2335_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = 2 * pstSnsState->u32FLStd - 10; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 3 + * max : 2 * vts - 10 + * step : 1 + */ + u32MinTime = 3; + u32MaxTime = 2 * pstSnsState->au32FL[0] - 10; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_M_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_ADDR].u32Data = ((u32TmpIntTime & 0x000F) << 4); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +typedef struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} gain_tbl_info_s; + +static struct gain_tbl_info_s AgainInfo[4] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x03, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x07, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 8128, + .idxBase = 128, + .regGain = 0x0F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 16256, + .idxBase = 192, + .regGain = 0x1F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, +}; +static CVI_U32 Again_table[256] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, 1248, 1263, 1280, + 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, 1472, 1487, 1504, 1519, 1536, 1552, + 1567, 1584, 1600, 1615, 1632, 1647, 1664, 1680, 1695, 1712, 1728, 1743, 1760, 1775, 1792, 1808, 1823, + 1840, 1856, 1871, 1888, 1903, 1920, 1936, 1951, 1968, 1984, 1999, 2016, 2031, 2048, 2079, 2112, 2144, + 2176, 2207, 2240, 2272, 2304, 2335, 2368, 2400, 2432, 2463, 2496, 2528, 2560, 2591, 2624, 2656, 2688, + 2719, 2752, 2784, 2816, 2847, 2880, 2912, 2944, 2975, 3008, 3040, 3072, 3103, 3136, 3168, 3200, 3231, + 3264, 3296, 3328, 3359, 3392, 3424, 3456, 3487, 3520, 3552, 3584, 3615, 3648, 3680, 3712, 3743, 3776, + 3808, 3840, 3871, 3904, 3936, 3968, 3999, 4032, 4064, 4096, 4160, 4224, 4288, 4352, 4416, 4480, 4544, + 4608, 4672, 4736, 4800, 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, 5504, 5568, 5632, + 5696, 5760, 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, 6464, 6528, 6592, 6656, 6720, + 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, 7424, 7488, 7552, 7616, 7680, 7744, 7808, + 7872, 7936, 8000, 8064, 8128, 8192, 8320, 8448, 8576, 8704, 8832, 8960, 9088, 9216, 9344, 9472, 9600, + 9728, 9856, 9984, 10112, 10240, 10368, 10496, 10624, 10752, 10880, 11008, 11136, 11264, 11392, 11520, + 11648, 11776, 11904, 12032, 12160, 12288, 12416, 12544, 12672, 12800, 12928, 13056, 13184, 13312, 13440, + 13568, 13696, 13824, 13952, 14080, 14208, 14336, 14464, 14592, 14720, 14848, 14976, 15104, 15232, 15360, + 15488, 15616, 15744, 15872, 16000, 16128, 16256 +}; + +static struct gain_tbl_info_s DgainInfo[5] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 8128, + .idxBase = 128, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 16256, + .idxBase = 192, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 32512, + .idxBase = 256, + .regGain = 0x0F, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, +}; + +static CVI_U32 Dgain_table[320] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, 1248, + 1263, 1280, 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, 1472, 1487, + 1504, 1519, 1536, 1552, 1567, 1584, 1600, 1615, 1632, 1647, 1664, 1680, 1695, 1712, 1728, + 1743, 1760, 1775, 1792, 1808, 1823, 1840, 1856, 1871, 1888, 1903, 1920, 1936, 1951, 1968, + 1984, 1999, 2016, 2031, 2048, 2079, 2112, 2144, 2176, 2207, 2240, 2272, 2304, 2335, 2368, + 2400, 2432, 2463, 2496, 2528, 2560, 2591, 2624, 2656, 2688, 2719, 2752, 2784, 2816, 2847, + 2880, 2912, 2944, 2975, 3008, 3040, 3072, 3103, 3136, 3168, 3200, 3231, 3264, 3296, 3328, + 3359, 3392, 3424, 3456, 3487, 3520, 3552, 3584, 3615, 3648, 3680, 3712, 3743, 3776, 3808, + 3840, 3871, 3904, 3936, 3968, 3999, 4032, 4064, 4096, 4160, 4224, 4288, 4352, 4416, 4480, + 4544, 4608, 4672, 4736, 4800, 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, + 5504, 5568, 5632, 5696, 5760, 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, + 6464, 6528, 6592, 6656, 6720, 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, + 7424, 7488, 7552, 7616, 7680, 7744, 7808, 7872, 7936, 8000, 8064, 8128, 8192, 8320, 8448, + 8576, 8704, 8832, 8960, 9088, 9216, 9344, 9472, 9600, 9728, 9856, 9984, 10112, 10240, 10368, + 10496, 10624, 10752, 10880, 11008, 11136, 11264, 11392, 11520, 11648, 11776, 11904, 12032, + 12160, 12288, 12416, 12544, 12672, 12800, 12928, 13056, 13184, 13312, 13440, 13568, 13696, + 13824, 13952, 14080, 14208, 14336, 14464, 14592, 14720, 14848, 14976, 15104, 15232, 15360, + 15488, 15616, 15744, 15872, 16000, 16128, 16256, 16384, 16640, 16896, 17152, 17408, 17664, + 17920, 18176, 18432, 18688, 18944, 19200, 19456, 19712, 19968, 20224, 20480, 20736, 20992, + 21248, 21504, 21760, 22016, 22272, 22528, 22784, 23040, 23296, 23552, 23808, 24064, 24320, + 24576, 24832, 25088, 25344, 25600, 25856, 26112, 26368, 26624, 26880, 27136, 27392, 27648, + 27904, 28160, 28416, 28672, 28928, 29184, 29440, 29696, 29952, 30208, 30464, 30720, 30976, + 31232, 31488, 31744, 32000, 32256, 32512 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[255]) { + *pu32AgainLin = Again_table[255]; + *pu32AgainDb = 255; + return CVI_SUCCESS; + } + + for (i = 1; i < 256; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[319]) { + *pu32DgainLin = Dgain_table[319]; + *pu32DgainDb = 319; + return CVI_SUCCESS; + } + + for (i = 1; i < 320; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L_ADDR].u32Data = (u32Again & 0xFF); + + if (info->regGain < 0x07) { //gain < 2x + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_ADDR].u32Data = 0x0e; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } else { //2x <= gain + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_ADDR].u32Data = 0x07; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } + if (sc2335_read_register(ViPipe, 0x3040) == 0x41) { + if (info->regGain < 0x07) { //gain < 2x + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_ADDR].u32Data = 0x0f; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } else { //2x <= gain + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_ADDR].u32Data = 0x07; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } + } else { + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_ADDR].u32Data = 0x07; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } + /* gain DPC setting. */ + if ((info->regGain > 0x1F) || ((info->regGain == 0x1F) && (u32Again == 0x7F))) { //gain >= 15.875 + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_DPC_ADDR].u32Data = 0x07; + } else if ((info->regGain < 0x1F) || ((info->regGain == 0x1F) && (u32Again <= 0x50))) { //gain <= 10x + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_DPC_ADDR].u32Data = 0x00; + } + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L_ADDR].u32Data = (u32Dgain & 0xFF); + + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC2335_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC2335_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC2335_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC2335_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC2335_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc2335_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc2335_addr_byte; + pstI2c_data[i].u32DataByteNum = sc2335_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC2335_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_M_ADDR].u32RegAddr = SC2335_EXP_M_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC2335_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H_ADDR].u32RegAddr = SC2335_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L_ADDR].u32RegAddr = SC2335_AGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC2335_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC2335_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC2335_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC2335_VMAX_L_ADDR; + pstI2c_data[LINEAR_HOLD].u32RegAddr = SC2335_HOLD_ADDR; + pstI2c_data[LINEAR_GAIN_LOGIC_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_LOGIC_ADDR].u32RegAddr = SC2335_GAIN_LOGIC_ADDR; + pstI2c_data[LINEAR_GAIN_DPC_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_DPC_ADDR].u32RegAddr = SC2335_GAIN_DPC_ADDR; + pstI2c_data[LINEAR_REL].u32RegAddr = SC2335_HOLD_ADDR; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update group hold or not*/ + if (pstCfg0->snsCfg.astI2cData[LINEAR_GAIN_LOGIC_ADDR].bUpdate == CVI_TRUE) { + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + /* DPC updata when A/Dgain change */ + if ((pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H_ADDR].bUpdate == CVI_TRUE) + || (pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L_ADDR].bUpdate == CVI_TRUE) + || (pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H_ADDR].bUpdate == CVI_TRUE) + || (pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L_ADDR].bUpdate == CVI_TRUE)) { + pstI2c_data[LINEAR_GAIN_DPC_ADDR].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_HOLD].u32Data = 0x00; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0x30; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC2335_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC2335_MODE_1920X1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeSc2335_MirrorFip[ViPipe] != eSnsMirrorFlip) { + sc2335_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeSc2335_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC2335_MODE_S *pstMode = CVI_NULL; + + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC2335_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC2335_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc2335_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC2335_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC2335_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc2335_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc2335_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc2335_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc2335_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC2335_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC2335_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC2335_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC2335_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC2335_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC2335_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC2335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC2335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC2335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC2335_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC2335_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC2335_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc2335_standby, + .pfnRestart = sc2335_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = sc2335_write_register, + .pfnReadReg = sc2335_read_register, + .pfnSetBusInfo = sc2335_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc2335_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc2335/sc2335_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc2335/sc2335_cmos_ex.h new file mode 100644 index 000000000..d2b7d2246 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc2335/sc2335_cmos_ex.h @@ -0,0 +1,84 @@ +#ifndef __SC2335_CMOS_EX_H_ +#define __SC2335_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc2335_linear_regs_e { + LINEAR_EXP_H_ADDR, + LINEAR_EXP_M_ADDR, + LINEAR_EXP_L_ADDR, + LINEAR_AGAIN_H_ADDR, + LINEAR_AGAIN_L_ADDR, + LINEAR_DGAIN_H_ADDR, + LINEAR_DGAIN_L_ADDR, + LINEAR_VMAX_H_ADDR, + LINEAR_VMAX_L_ADDR, + LINEAR_HOLD, + LINEAR_GAIN_LOGIC_ADDR, + LINEAR_GAIN_DPC_ADDR, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +typedef enum _SC2335_MODE_E { + SC2335_MODE_1920X1080P30 = 0, + SC2335_MODE_LINEAR_NUM, + SC2335_MODE_NUM +} SC2335_MODE_E; + +typedef struct _SC2335_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + char name[64]; +} SC2335_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC2335[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC2335_BusInfo[]; +extern CVI_U16 g_au16SC2335_GainMode[]; +extern CVI_U16 g_au16SC2335_L2SMode[]; +extern const CVI_U8 sc2335_i2c_addr; +extern const CVI_U32 sc2335_addr_byte; +extern const CVI_U32 sc2335_data_byte; +extern void sc2335_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void sc2335_init(VI_PIPE ViPipe); +extern void sc2335_exit(VI_PIPE ViPipe); +extern void sc2335_standby(VI_PIPE ViPipe); +extern void sc2335_restart(VI_PIPE ViPipe); +extern int sc2335_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc2335_read_register(VI_PIPE ViPipe, int addr); +extern int sc2335_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC2335_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc2335/sc2335_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc2335/sc2335_cmos_param.h new file mode 100644 index 000000000..3f55de1a5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc2335/sc2335_cmos_param.h @@ -0,0 +1,125 @@ +#ifndef __SC2335_CMOS_PARAM_H_ +#define __SC2335_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc2335_cmos_ex.h" + +static const SC2335_MODE_S g_astSC2335_mode[SC2335_MODE_NUM] = { + [SC2335_MODE_1920X1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.51, /* 1125 * 30 / 0x7FFF */ + .u32HtsDef = 2560, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 3,//3 + .u16Max = 1125*2 - 10, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 16256, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 32512, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 + #ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 + #endif + }, + .stAuto = { + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + #ifdef ARCH_CV182X + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + #endif + }, + }, +}; + +struct combo_dev_attr_s sc2335_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 0, 1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 8, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC2335_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc2335/sc2335_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc2335/sc2335_sensor_ctl.c new file mode 100644 index 000000000..8ac4d16fb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc2335/sc2335_sensor_ctl.c @@ -0,0 +1,369 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "cvi_sns_ctrl.h" +#include "sc2335_cmos_ex.h" + +#define SC2335_CHIP_ID_HI_ADDR 0x3107 +#define SC2335_CHIP_ID_LO_ADDR 0x3108 +#define SC2335_CHIP_ID 0xcb14 + +static void sc2335_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc2335_i2c_addr = 0x30; /* I2C Address of SC2335 */ +const CVI_U32 sc2335_addr_byte = 2; +const CVI_U32 sc2335_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc2335_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC2335_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc2335_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc2335_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc2335_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc2335_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc2335_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc2335_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc2335_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc2335_write_register(VI_PIPE ViPipe, int addr, int data) +{ + int idx = 0; + int ret; + char buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc2335_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc2335_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc2335_addr_byte + sc2335_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc2335_prog(VI_PIPE ViPipe, int *rom) +{ + int i = 0; + + while (1) { + int lookup = rom[i++]; + int addr = (lookup >> 16) & 0xFFFF; + int data = lookup & 0xFFFF; + + if (addr == 0xFFFE) + delay_ms(data); + else if (addr != 0xFFFF) + sc2335_write_register(ViPipe, addr, data); + } +} + +void sc2335_standby(VI_PIPE ViPipe) +{ + sc2335_write_register(ViPipe, 0x0100, 0x00); +} + +void sc2335_restart(VI_PIPE ViPipe) +{ + sc2335_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc2335_write_register(ViPipe, 0x0100, 0x01); +} + +void sc2335_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC2335[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC2335[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc2335_write_register(ViPipe, + g_pastSC2335[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC2335[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc2335_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc2335_write_register(ViPipe, 0x3221, val); +} + + +int sc2335_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc2335_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc2335_read_register(ViPipe, SC2335_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc2335_read_register(ViPipe, SC2335_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC2335_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + + +/* 1080P30 and 1080P25 */ +static void sc2335_linear_1080p30_init(VI_PIPE ViPipe) +{ + sc2335_write_register(ViPipe, 0x0103, 0x01); + sc2335_write_register(ViPipe, 0x0100, 0x00); + sc2335_write_register(ViPipe, 0x36e9, 0x80); + sc2335_write_register(ViPipe, 0x36f9, 0x80); + sc2335_write_register(ViPipe, 0x301f, 0x02); + sc2335_write_register(ViPipe, 0x3207, 0x3f); + sc2335_write_register(ViPipe, 0x3249, 0x0f); + sc2335_write_register(ViPipe, 0x3253, 0x08); + sc2335_write_register(ViPipe, 0x3271, 0x00); + sc2335_write_register(ViPipe, 0x3273, 0x03); + sc2335_write_register(ViPipe, 0x3301, 0x06); + sc2335_write_register(ViPipe, 0x3302, 0x09); + sc2335_write_register(ViPipe, 0x3304, 0x28); + sc2335_write_register(ViPipe, 0x3306, 0x30); + sc2335_write_register(ViPipe, 0x330b, 0x94); + sc2335_write_register(ViPipe, 0x330c, 0x08); + sc2335_write_register(ViPipe, 0x330d, 0x18); + sc2335_write_register(ViPipe, 0x330e, 0x14); + sc2335_write_register(ViPipe, 0x330f, 0x05); + sc2335_write_register(ViPipe, 0x3310, 0x06); + sc2335_write_register(ViPipe, 0x3314, 0x96); + sc2335_write_register(ViPipe, 0x3316, 0x00); + sc2335_write_register(ViPipe, 0x331e, 0x21); + sc2335_write_register(ViPipe, 0x332b, 0x08); + sc2335_write_register(ViPipe, 0x3333, 0x10); + sc2335_write_register(ViPipe, 0x3338, 0x80); + sc2335_write_register(ViPipe, 0x333a, 0x04); + sc2335_write_register(ViPipe, 0x334c, 0x04); + sc2335_write_register(ViPipe, 0x335f, 0x04); + sc2335_write_register(ViPipe, 0x3364, 0x17); + sc2335_write_register(ViPipe, 0x3366, 0x62); + sc2335_write_register(ViPipe, 0x337c, 0x05); + sc2335_write_register(ViPipe, 0x337d, 0x09); + sc2335_write_register(ViPipe, 0x337e, 0x00); + sc2335_write_register(ViPipe, 0x3390, 0x08); + sc2335_write_register(ViPipe, 0x3391, 0x18); + sc2335_write_register(ViPipe, 0x3392, 0x38); + sc2335_write_register(ViPipe, 0x3393, 0x09); + sc2335_write_register(ViPipe, 0x3394, 0x20); + sc2335_write_register(ViPipe, 0x3395, 0x20); + sc2335_write_register(ViPipe, 0x33a2, 0x07); + sc2335_write_register(ViPipe, 0x33ac, 0x04); + sc2335_write_register(ViPipe, 0x33ae, 0x14); + sc2335_write_register(ViPipe, 0x3614, 0x00); + sc2335_write_register(ViPipe, 0x3622, 0x16); + sc2335_write_register(ViPipe, 0x3630, 0x68); + sc2335_write_register(ViPipe, 0x3631, 0x84); + sc2335_write_register(ViPipe, 0x3637, 0x20); + sc2335_write_register(ViPipe, 0x363a, 0x1f); + sc2335_write_register(ViPipe, 0x363c, 0x0e); + sc2335_write_register(ViPipe, 0x3670, 0x0e); + sc2335_write_register(ViPipe, 0x3674, 0xa1); + sc2335_write_register(ViPipe, 0x3675, 0x9c); + sc2335_write_register(ViPipe, 0x3676, 0x9e); + sc2335_write_register(ViPipe, 0x3677, 0x84); + sc2335_write_register(ViPipe, 0x3678, 0x85); + sc2335_write_register(ViPipe, 0x3679, 0x87); + sc2335_write_register(ViPipe, 0x367c, 0x18); + sc2335_write_register(ViPipe, 0x367d, 0x38); + sc2335_write_register(ViPipe, 0x367e, 0x08); + sc2335_write_register(ViPipe, 0x367f, 0x18); + sc2335_write_register(ViPipe, 0x3690, 0x32); + sc2335_write_register(ViPipe, 0x3691, 0x32); + sc2335_write_register(ViPipe, 0x3692, 0x44); + sc2335_write_register(ViPipe, 0x369c, 0x08); + sc2335_write_register(ViPipe, 0x369d, 0x38); + sc2335_write_register(ViPipe, 0x3908, 0x82); + sc2335_write_register(ViPipe, 0x391f, 0x18); + sc2335_write_register(ViPipe, 0x3e01, 0x8c); + sc2335_write_register(ViPipe, 0x3e02, 0x00); + sc2335_write_register(ViPipe, 0x3f00, 0x0d); + sc2335_write_register(ViPipe, 0x3f04, 0x02); + sc2335_write_register(ViPipe, 0x3f05, 0x0e); + sc2335_write_register(ViPipe, 0x3f09, 0x48); + sc2335_write_register(ViPipe, 0x4505, 0x0a); + sc2335_write_register(ViPipe, 0x4509, 0x20); + sc2335_write_register(ViPipe, 0x481d, 0x0a); + sc2335_write_register(ViPipe, 0x4827, 0x03); + sc2335_write_register(ViPipe, 0x5787, 0x10); + sc2335_write_register(ViPipe, 0x5788, 0x06); + sc2335_write_register(ViPipe, 0x578a, 0x10); + sc2335_write_register(ViPipe, 0x578b, 0x06); + sc2335_write_register(ViPipe, 0x5790, 0x10); + sc2335_write_register(ViPipe, 0x5791, 0x10); + sc2335_write_register(ViPipe, 0x5792, 0x00); + sc2335_write_register(ViPipe, 0x5793, 0x10); + sc2335_write_register(ViPipe, 0x5794, 0x10); + sc2335_write_register(ViPipe, 0x5795, 0x00); + sc2335_write_register(ViPipe, 0x5799, 0x00); + sc2335_write_register(ViPipe, 0x57c7, 0x10); + sc2335_write_register(ViPipe, 0x57c8, 0x06); + sc2335_write_register(ViPipe, 0x57ca, 0x10); + sc2335_write_register(ViPipe, 0x57cb, 0x06); + sc2335_write_register(ViPipe, 0x57d1, 0x10); + sc2335_write_register(ViPipe, 0x57d4, 0x10); + sc2335_write_register(ViPipe, 0x57d9, 0x00); + sc2335_write_register(ViPipe, 0x36e9, 0x20); + sc2335_write_register(ViPipe, 0x36f9, 0x27); + sc2335_write_register(ViPipe, 0x0100, 0x01); + + sc2335_default_reg_init(ViPipe); + + sc2335_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC2335 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +void sc2335_init(VI_PIPE ViPipe) +{ + sc2335_i2c_init(ViPipe); + + //linear mode only + sc2335_linear_1080p30_init(ViPipe); + + g_pastSC2335[ViPipe]->bInit = CVI_TRUE; +} + +void sc2335_exit(VI_PIPE ViPipe) +{ + sc2335_i2c_exit(ViPipe); +} \ No newline at end of file diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc2336/Makefile b/middleware/v2/component/isp/sensor/cv180x/sms_sc2336/Makefile new file mode 100644 index 000000000..cfab5277d --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc2336/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc2336.a +TARGET_SO = $(MW_LIB)/libsns_sc2336.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJ) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc2336/sc2336_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc2336/sc2336_cmos.c new file mode 100644 index 000000000..19d4d014a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc2336/sc2336_cmos.c @@ -0,0 +1,894 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc2336_cmos_ex.h" +#include "sc2336_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC2336_ID 35 +#define SENSOR_SC2336_WIDTH 1920 +#define SENSOR_SC2336_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC2336[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC2336_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC2336[dev]) +#define SC2336_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC2336[dev] = pstCtx) +#define SC2336_SENSOR_RESET_CTX(dev) (g_pastSC2336[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC2336_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC2336_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC2336_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC2336_STATE_S g_astSC2336_State[VI_MAX_PIPE_NUM] = {{0} }; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ + +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC2336 Lines Range*****/ +#define SC2336_FULL_LINES_MAX (0xFFFF) + +/*****SC2336 Register Address*****/ +#define SC2336_SHS1_0_ADDR 0x3E00 +#define SC2336_SHS1_1_ADDR 0x3E01 +#define SC2336_SHS1_2_ADDR 0x3E02 +#define SC2336_AGAIN0_ADDR 0x3E09 +#define SC2336_DGAIN0_ADDR 0x3E06 +#define SC2336_VMAX_ADDR 0x320E +#define SC2336_TABLE_END 0xFFFF + +#define SC2336_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC2336_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC2336_mode[pstSnsState->u8ImgMode]; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC2336_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC2336_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC2336_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC2336_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC2336_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC2336_FULL_LINES_MAX) ? SC2336_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 6; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE != pstSnsState->enWDRMode) { + CVI_U32 u32TmpIntTime = u32IntTime[0]; + /* linear exposure reg range: + * min : 1 + * max : (vts - 6) + * step : 1 + */ + u32TmpIntTime = (u32TmpIntTime > (pstSnsState->au32FL[0] - 6)) ? + (pstSnsState->au32FL[0] - 6) : u32TmpIntTime; + if (!u32TmpIntTime) + u32TmpIntTime = 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = (u32TmpIntTime & 0xF) << 4; + } + + return CVI_SUCCESS; + +} + +struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +}; + +static CVI_U32 Again_table[] = { + 1024, 2048, 4096, 8192, 16384, 32768 +}; + +static CVI_U32 AgainReg[] = { + 0x00, 0x08, 0x09, 0x0b, 0x0f, 0x1f +}; + +static struct gain_tbl_info_s DgainInfo[] = { + { + .gainMax = 2016, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 4096, + .idxBase = 64, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 0, + }, +}; + +static CVI_U32 Dgain_table[] = { + 1024, 1056, 1088, 1120, 1152, 1184, 1216, 1248, 1280, 1312, 1344, 1376, 1408, 1440, 1472, 1504, + 1536, 1568, 1600, 1632, 1664, 1696, 1728, 1760, 1792, 1824, 1856, 1888, 1920, 1952, 1984, 2016, + 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008, + 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, 3904, 3968, 4032, + 4096, +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 tableSize = sizeof(Again_table) / sizeof(CVI_U32); + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[tableSize - 1]) { + *pu32AgainLin = Again_table[tableSize - 1]; + *pu32AgainDb = AgainReg[tableSize - 1]; + return CVI_SUCCESS; + } + + for (CVI_U32 i = 1; i < tableSize; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = AgainReg[i - 1]; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 tableSize = sizeof(Dgain_table) / sizeof(CVI_U32); + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[tableSize - 1]) { + *pu32DgainLin = Dgain_table[tableSize - 1]; + *pu32DgainDb = tableSize - 1; + return CVI_SUCCESS; + } + + for (CVI_U32 i = 1; i < tableSize; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + CVI_S32 i = 0, tbl_num = 0; + + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* Again. */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1_ADDR].u32Data = (u32Dgain & 0xFF); + } + return CVI_SUCCESS; +} + + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + // pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + // pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC2336_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC2336_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC2336_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC2336_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC2336_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc2336_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc2336_addr_byte; + pstI2c_data[i].u32DataByteNum = sc2336_data_byte; + } + + //DOL 2t1 Mode Regs + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + break; + default: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC2336_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC2336_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC2336_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC2336_AGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC2336_DGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC2336_DGAIN0_ADDR + 1; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC2336_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC2336_VMAX_ADDR + 1; + + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC2336_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC2336_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC2336_MODE_S *pstMode = CVI_NULL; + + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC2336_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC2336_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc2336_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC2336_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC2336_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc2336_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= VI_MAX_DEV_NUM) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc2336_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc2336_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc2336_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC2336_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC2336_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC2336_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC2336_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC2336_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC2336_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC2336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC2336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC2336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC2336_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC2336_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC2336_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc2336_standby, + .pfnRestart = sc2336_restart, + .pfnMirrorFlip = sc2336_mirror_flip, + .pfnWriteReg = sc2336_write_register, + .pfnReadReg = sc2336_read_register, + .pfnSetBusInfo = sc2336_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc2336_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc2336/sc2336_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc2336/sc2336_cmos_ex.h new file mode 100644 index 000000000..88eb624cb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc2336/sc2336_cmos_ex.h @@ -0,0 +1,85 @@ +#ifndef __SC2336_CMOS_EX_H_ +#define __SC2336_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc2336_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_2_ADDR, + LINEAR_AGAIN_0_ADDR, + LINEAR_DGAIN_0_ADDR, + LINEAR_DGAIN_1_ADDR, + LINEAR_VMAX_0_ADDR, + LINEAR_VMAX_1_ADDR, + LINEAR_REGS_NUM +}; + + +typedef enum _SC2336_MODE_E { + SC2336_MODE_1080P30 = 0, + SC2336_MODE_LINEAR_NUM, + SC2336_MODE_NUM +} SC2336_MODE_E; + +typedef struct _SC2336_STATE_S { + CVI_U32 u32Sexp_MAX; +} SC2336_STATE_S; + +typedef struct _SC2336_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16SexpMaxReg; + char name[64]; +} SC2336_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC2336[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC2336_BusInfo[]; +extern CVI_U16 g_au16SC2336_GainMode[]; +extern CVI_U16 g_au16SC2336_L2SMode[]; +extern const CVI_U8 sc2336_i2c_addr; +extern const CVI_U32 sc2336_addr_byte; +extern const CVI_U32 sc2336_data_byte; +extern void sc2336_init(VI_PIPE ViPipe); +extern void sc2336_exit(VI_PIPE ViPipe); +extern void sc2336_standby(VI_PIPE ViPipe); +extern void sc2336_restart(VI_PIPE ViPipe); +extern int sc2336_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc2336_read_register(VI_PIPE ViPipe, int addr); +extern void sc2336_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc2336_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC2336_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc2336/sc2336_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc2336/sc2336_cmos_param.h new file mode 100644 index 000000000..1825ccbd2 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc2336/sc2336_cmos_param.h @@ -0,0 +1,125 @@ +#ifndef __SC2336_CMOS_PARAM_H_ +#define __SC2336_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc2336_cmos_ex.h" + +static const SC2336_MODE_S g_astSC2336_mode[SC2336_MODE_NUM] = { + [SC2336_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.51, /* 1125 * 30 / 0xFFFF*/ + .u32HtsDef = 2560, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 12184 - 6, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 32768, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 4096, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {260, 260, 260, 260, 260, 252, 252, 252, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 252, 252, 252, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 252, 252, 252, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 252, 252, 252, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1091, 1091, 1091, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1091, 1091, 1091, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1091, 1091, 1091, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1091, 1091, 1091, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc2336_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 0, 1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 8, + } + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC2336_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc2336/sc2336_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc2336/sc2336_sensor_ctl.c new file mode 100644 index 000000000..635aacdbb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc2336/sc2336_sensor_ctl.c @@ -0,0 +1,409 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc2336_cmos_ex.h" + +static void sc2336_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc2336_i2c_addr = 0x30; /* I2C Address of SC2336 */ +const CVI_U32 sc2336_addr_byte = 2; +const CVI_U32 sc2336_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc2336_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC2336_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc2336_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc2336_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc2336_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + char buf[8]; + int idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc2336_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc2336_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc2336_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc2336_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc2336_write_register(VI_PIPE ViPipe, int addr, int data) +{ + int idx = 0; + int ret; + char buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc2336_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc2336_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc2336_addr_byte + sc2336_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc2336_prog(VI_PIPE ViPipe, int *rom) +{ + int i = 0; + + while (1) { + int lookup = rom[i++]; + int addr = (lookup >> 16) & 0xFFFF; + int data = lookup & 0xFFFF; + + if (addr == 0xFFFE) + delay_ms(data); + else if (addr != 0xFFFF) + sc2336_write_register(ViPipe, addr, data); + } +} + +void sc2336_standby(VI_PIPE ViPipe) +{ + sc2336_write_register(ViPipe, 0x0100, 0x00); +} + +void sc2336_restart(VI_PIPE ViPipe) +{ + sc2336_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc2336_write_register(ViPipe, 0x0100, 0x01); +} + +void sc2336_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC2336[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc2336_write_register(ViPipe, + g_pastSC2336[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC2336[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC2336_CHIP_ID_HI_ADDR 0x3107 +#define SC2336_CHIP_ID_LO_ADDR 0x3108 +#define SC2336_CHIP_ID 0xcb3a + +void sc2336_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc2336_write_register(ViPipe, 0x3221, val); +} + +int sc2336_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc2336_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc2336_read_register(ViPipe, SC2336_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc2336_read_register(ViPipe, SC2336_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC2336_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc2336_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + + bInit = g_pastSC2336[ViPipe]->bInit; + enWDRMode = g_pastSC2336[ViPipe]->enWDRMode; + + sc2336_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_NONE) { + sc2336_linear_1080p30_init(ViPipe); + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_NONE) { + sc2336_linear_1080p30_init(ViPipe); + } + } + g_pastSC2336[ViPipe]->bInit = CVI_TRUE; +} + +void sc2336_exit(VI_PIPE ViPipe) +{ + sc2336_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void sc2336_linear_1080p30_init(VI_PIPE ViPipe) +{ + sc2336_write_register(ViPipe, 0x0103, 0x01); + sc2336_write_register(ViPipe, 0x0100, 0x00); + sc2336_write_register(ViPipe, 0x36e9, 0x80); + sc2336_write_register(ViPipe, 0x37f9, 0x80); + sc2336_write_register(ViPipe, 0x301f, 0x01); + sc2336_write_register(ViPipe, 0x3106, 0x05); + sc2336_write_register(ViPipe, 0x3248, 0x04); + sc2336_write_register(ViPipe, 0x3249, 0x0b); + sc2336_write_register(ViPipe, 0x3253, 0x08); + sc2336_write_register(ViPipe, 0x3301, 0x09); + sc2336_write_register(ViPipe, 0x3302, 0xff); + sc2336_write_register(ViPipe, 0x3303, 0x10); + sc2336_write_register(ViPipe, 0x3306, 0x60); + sc2336_write_register(ViPipe, 0x3307, 0x02); + sc2336_write_register(ViPipe, 0x330a, 0x01); + sc2336_write_register(ViPipe, 0x330b, 0x10); + sc2336_write_register(ViPipe, 0x330c, 0x16); + sc2336_write_register(ViPipe, 0x330d, 0xff); + sc2336_write_register(ViPipe, 0x3318, 0x02); + sc2336_write_register(ViPipe, 0x3321, 0x0a); + sc2336_write_register(ViPipe, 0x3327, 0x0e); + sc2336_write_register(ViPipe, 0x332b, 0x12); + sc2336_write_register(ViPipe, 0x3333, 0x10); + sc2336_write_register(ViPipe, 0x3334, 0x40); + sc2336_write_register(ViPipe, 0x335e, 0x06); + sc2336_write_register(ViPipe, 0x335f, 0x0a); + sc2336_write_register(ViPipe, 0x3364, 0x1f); + sc2336_write_register(ViPipe, 0x337c, 0x02); + sc2336_write_register(ViPipe, 0x337d, 0x0e); + sc2336_write_register(ViPipe, 0x3390, 0x09); + sc2336_write_register(ViPipe, 0x3391, 0x0f); + sc2336_write_register(ViPipe, 0x3392, 0x1f); + sc2336_write_register(ViPipe, 0x3393, 0x20); + sc2336_write_register(ViPipe, 0x3394, 0x20); + sc2336_write_register(ViPipe, 0x3395, 0xff); + sc2336_write_register(ViPipe, 0x33a2, 0x04); + sc2336_write_register(ViPipe, 0x33b1, 0x80); + sc2336_write_register(ViPipe, 0x33b2, 0x68); + sc2336_write_register(ViPipe, 0x33b3, 0x42); + sc2336_write_register(ViPipe, 0x33f9, 0x70); + sc2336_write_register(ViPipe, 0x33fb, 0xd0); + sc2336_write_register(ViPipe, 0x33fc, 0x0f); + sc2336_write_register(ViPipe, 0x33fd, 0x1f); + sc2336_write_register(ViPipe, 0x349f, 0x03); + sc2336_write_register(ViPipe, 0x34a6, 0x0f); + sc2336_write_register(ViPipe, 0x34a7, 0x1f); + sc2336_write_register(ViPipe, 0x34a8, 0x42); + sc2336_write_register(ViPipe, 0x34a9, 0x06); + sc2336_write_register(ViPipe, 0x34aa, 0x01); + sc2336_write_register(ViPipe, 0x34ab, 0x23); + sc2336_write_register(ViPipe, 0x34ac, 0x01); + sc2336_write_register(ViPipe, 0x34ad, 0x84); + sc2336_write_register(ViPipe, 0x3630, 0xf4); + sc2336_write_register(ViPipe, 0x3633, 0x22); + sc2336_write_register(ViPipe, 0x3639, 0xf4); + sc2336_write_register(ViPipe, 0x363c, 0x47); + sc2336_write_register(ViPipe, 0x3670, 0x09); + sc2336_write_register(ViPipe, 0x3674, 0xf4); + sc2336_write_register(ViPipe, 0x3675, 0xfb); + sc2336_write_register(ViPipe, 0x3676, 0xed); + sc2336_write_register(ViPipe, 0x367c, 0x09); + sc2336_write_register(ViPipe, 0x367d, 0x0f); + sc2336_write_register(ViPipe, 0x3690, 0x33); + sc2336_write_register(ViPipe, 0x3691, 0x33); + sc2336_write_register(ViPipe, 0x3692, 0x43); + sc2336_write_register(ViPipe, 0x3698, 0x89); + sc2336_write_register(ViPipe, 0x3699, 0x96); + sc2336_write_register(ViPipe, 0x369a, 0xd0); + sc2336_write_register(ViPipe, 0x369b, 0xd0); + sc2336_write_register(ViPipe, 0x369c, 0x09); + sc2336_write_register(ViPipe, 0x369d, 0x0f); + sc2336_write_register(ViPipe, 0x36a2, 0x09); + sc2336_write_register(ViPipe, 0x36a3, 0x0f); + sc2336_write_register(ViPipe, 0x36a4, 0x1f); + sc2336_write_register(ViPipe, 0x36d0, 0x01); + sc2336_write_register(ViPipe, 0x3722, 0xe1); + sc2336_write_register(ViPipe, 0x3724, 0x41); + sc2336_write_register(ViPipe, 0x3725, 0xc1); + sc2336_write_register(ViPipe, 0x3728, 0x20); + sc2336_write_register(ViPipe, 0x3900, 0x0d); + sc2336_write_register(ViPipe, 0x3905, 0x98); + sc2336_write_register(ViPipe, 0x391b, 0x81); + sc2336_write_register(ViPipe, 0x391c, 0x10); + sc2336_write_register(ViPipe, 0x3933, 0x81); + sc2336_write_register(ViPipe, 0x3934, 0xc5); + sc2336_write_register(ViPipe, 0x3940, 0x68); + sc2336_write_register(ViPipe, 0x3941, 0x00); + sc2336_write_register(ViPipe, 0x3942, 0x01); + sc2336_write_register(ViPipe, 0x3943, 0xc6); + sc2336_write_register(ViPipe, 0x3952, 0x02); + sc2336_write_register(ViPipe, 0x3953, 0x0f); + sc2336_write_register(ViPipe, 0x3e01, 0x45); + sc2336_write_register(ViPipe, 0x3e02, 0xf0); + sc2336_write_register(ViPipe, 0x3e08, 0x1f); + sc2336_write_register(ViPipe, 0x3e1b, 0x14); + sc2336_write_register(ViPipe, 0x440e, 0x02); + sc2336_write_register(ViPipe, 0x4509, 0x38); + sc2336_write_register(ViPipe, 0x5799, 0x06); + sc2336_write_register(ViPipe, 0x5ae0, 0xfe); + sc2336_write_register(ViPipe, 0x5ae1, 0x40); + sc2336_write_register(ViPipe, 0x5ae2, 0x30); + sc2336_write_register(ViPipe, 0x5ae3, 0x28); + sc2336_write_register(ViPipe, 0x5ae4, 0x20); + sc2336_write_register(ViPipe, 0x5ae5, 0x30); + sc2336_write_register(ViPipe, 0x5ae6, 0x28); + sc2336_write_register(ViPipe, 0x5ae7, 0x20); + sc2336_write_register(ViPipe, 0x5ae8, 0x3c); + sc2336_write_register(ViPipe, 0x5ae9, 0x30); + sc2336_write_register(ViPipe, 0x5aea, 0x28); + sc2336_write_register(ViPipe, 0x5aeb, 0x3c); + sc2336_write_register(ViPipe, 0x5aec, 0x30); + sc2336_write_register(ViPipe, 0x5aed, 0x28); + sc2336_write_register(ViPipe, 0x5aee, 0xfe); + sc2336_write_register(ViPipe, 0x5aef, 0x40); + sc2336_write_register(ViPipe, 0x5af4, 0x30); + sc2336_write_register(ViPipe, 0x5af5, 0x28); + sc2336_write_register(ViPipe, 0x5af6, 0x20); + sc2336_write_register(ViPipe, 0x5af7, 0x30); + sc2336_write_register(ViPipe, 0x5af8, 0x28); + sc2336_write_register(ViPipe, 0x5af9, 0x20); + sc2336_write_register(ViPipe, 0x5afa, 0x3c); + sc2336_write_register(ViPipe, 0x5afb, 0x30); + sc2336_write_register(ViPipe, 0x5afc, 0x28); + sc2336_write_register(ViPipe, 0x5afd, 0x3c); + sc2336_write_register(ViPipe, 0x5afe, 0x30); + sc2336_write_register(ViPipe, 0x5aff, 0x28); + sc2336_write_register(ViPipe, 0x36e9, 0x20); + sc2336_write_register(ViPipe, 0x37f9, 0x27); + sc2336_write_register(ViPipe, 0x0100, 0x01); + + sc2336_default_reg_init(ViPipe); + + sc2336_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC2336 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc301iot/Makefile b/middleware/v2/component/isp/sensor/cv180x/sms_sc301iot/Makefile new file mode 100644 index 000000000..cf1e22a03 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc301iot/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc301iot.a +TARGET_SO = $(MW_LIB)/libsns_sc301iot.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc301iot/sc301iot_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc301iot/sc301iot_cmos.c new file mode 100644 index 000000000..8be74706c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc301iot/sc301iot_cmos.c @@ -0,0 +1,921 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc301iot_cmos_ex.h" +#include "sc301iot_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC301IOT_ID 35 +#define SENSOR_SC301IOT_WIDTH 2048 +#define SENSOR_SC301IOT_HEIGHT 1536 +#define SC301IOT_I2C_ADDR_1 0x30 +#define SC301IOT_I2C_ADDR_2 0x32 +#define SC301IOT_I2C_ADDR_IS_VALID(addr) ((addr) == SC301IOT_I2C_ADDR_1 || (addr) == SC301IOT_I2C_ADDR_2) +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC301IOT[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC301IOT_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC301IOT[dev]) +#define SC301IOT_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC301IOT[dev] = pstCtx) +#define SC301IOT_SENSOR_RESET_CTX(dev) (g_pastSC301IOT[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC301IOT_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC301IOT_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC301IOT_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC301IOT Lines Range*****/ +#define SC301IOT_FULL_LINES_MAX (0x7FFF) + +/*****SC301IOT Register Address*****/ +#define SC301IOT_SHS1_0_ADDR 0x3E00 +#define SC301IOT_SHS1_1_ADDR 0x3E01 +#define SC301IOT_SHS1_2_ADDR 0x3E02 +#define SC301IOT_SHS2_0_ADDR 0x3E22 +#define SC301IOT_SHS2_1_ADDR 0x3E04 +#define SC301IOT_SHS2_2_ADDR 0x3E05 +#define SC301IOT_AGAIN_ADDR 0x3E09 +#define SC301IOT_DGAIN1_ADDR 0x3E06 +#define SC301IOT_DGAIN2_ADDR 0x3E10 +#define SC301IOT_VMAX_ADDR 0x320E +#define SC301IOT_MAXSEXP_ADDR 0x3E23 +#define SC301IOT_TABLE_END 0xFFFF + +#define SC301IOT_RES_IS_1536P(w, h) ((w) <= SENSOR_SC301IOT_WIDTH && (h) <= SENSOR_SC301IOT_HEIGHT) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC301IOT_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astSC301IOT_mode[SC301IOT_MODE_1536P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC301IOT_mode[SC301IOT_MODE_1536P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = g_astSC301IOT_mode[SC301IOT_MODE_1536P30].stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = g_astSC301IOT_mode[SC301IOT_MODE_1536P30].stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astSC301IOT_mode[SC301IOT_MODE_1536P30].stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = g_astSC301IOT_mode[SC301IOT_MODE_1536P30].stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC301IOT_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC301IOT_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC301IOT_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC301IOT_MODE_1536P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC301IOT_FULL_LINES_MAX) ? SC301IOT_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + CVI_U32 u32TmpIntTime = u32IntTime[0]; + /* linear exposure reg range: + * min : 2 + * max : (vts - 8) + * step : 1 + */ + u32TmpIntTime = (u32TmpIntTime > (pstSnsState->au32FL[0] - 8)) ? + (pstSnsState->au32FL[0] - 8) : u32TmpIntTime; + if (!u32TmpIntTime) + u32TmpIntTime = 2; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = (u32TmpIntTime & 0xF) << 4; + } + + return CVI_SUCCESS; + +} + +struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +}; + +static struct gain_tbl_info_s DgainInfo[5] = { + { + .gainMax = 2016, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 8064, + .idxBase = 64, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 16128, + .idxBase = 96, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 32256, + .idxBase = 128, + .regGain = 0x0f, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, +}; + +static CVI_U32 Dgain_table[160] = { + 1024, 1055, 1088, 1120, 1152, 1183, 1216, 1248, 1280, 1311, 1344, 1376, 1408, + 1439, 1472, 1504, 1536, 1567, 1600, 1632, 1664, 1695, 1728, 1760, 1792, 1823, + 1856, 1888, 1920, 1951, 1984, 2016, 2048, 2112, 2176, 2240, 2304, 2368, 2432, + 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008, 3072, 3136, 3200, 3264, + 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, 3904, 3968, 4032, 4096, + 4224, 4352, 4480, 4608, 4736, 4864, 4992, 5120, 5248, 5376, 5504, 5632, 5760, + 5888, 6016, 6144, 6272, 6400, 6528, 6656, 6784, 6912, 7040, 7168, 7296, 7424, + 7552, 7680, 7808, 7936, 8064, 8192, 8448, 8704, 8960, 9216, 9472, 9728, 9984, + 10240, 10496, 10752, 11008, 11264, 11520, 11776, 12032, 12288, 12544, 12800, 13056, + 13312, 13568, 13824, 14080, 14336, 14592, 14848, 15104, 15360, 15616, 15872, 16128, + 16384, 16896, 17408, 17920, 18432, 18944, 19456, 19968, 20480, 20992, 21504, 22016, + 22528, 23040, 23552, 24064, 24576, 25088, 25600, 26112, 26624, 27136, 27648, 28160, + 28672, 29184, 29696, 30208, 30720, 31232, 31744, 32256 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 again = *pu32AgainLin; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (again < 1606) { + *pu32AgainDb = 0x00; + *pu32AgainLin = 1024; + } else if (again < 3213) { + *pu32AgainDb = 0x40; + *pu32AgainLin = 1606; + } else if (again < 6426) { + *pu32AgainDb = 0x48; + *pu32AgainLin = 3213; + } else if (again < 12853) { + *pu32AgainDb = 0x49; + *pu32AgainLin = 6426; + } else if (again < 25706) { + *pu32AgainDb = 0x4b; + *pu32AgainLin = 12853; + } else if (again < 51412) { + *pu32AgainDb = 0x4f; + *pu32AgainLin = 25706; + } else { + *pu32AgainDb = 0x5f; + *pu32AgainLin = 51412; + } + + return CVI_SUCCESS; +} +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[ARRAY_SIZE(Dgain_table) - 1]) { + *pu32DgainLin = Dgain_table[ARRAY_SIZE(Dgain_table) - 1]; + *pu32DgainDb = ARRAY_SIZE(Dgain_table) - 1; + return CVI_SUCCESS; + } + + for (i = 1; i < ARRAY_SIZE(Dgain_table); i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1_ADDR].u32Data = (u32Dgain & 0xFF); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + // pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + // pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC301IOT_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC301IOT_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == SC301IOT_MODE_1536P30) + pstSnsState->u8ImgMode = SC301IOT_MODE_1536P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC301IOT_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC301IOT_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc301iot_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc301iot_addr_byte; + pstI2c_data[i].u32DataByteNum = sc301iot_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC301IOT_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC301IOT_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC301IOT_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = SC301IOT_AGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC301IOT_DGAIN1_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC301IOT_DGAIN1_ADDR + 1; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC301IOT_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC301IOT_VMAX_ADDR + 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC301IOT_RES_IS_1536P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC301IOT_MODE_1536P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC301IOT_MODE_S *pstMode = CVI_NULL; + + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC301IOT_MODE_1536P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC301IOT_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc301iot_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC301IOT_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC301IOT_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc301iot_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc301iot_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc301iot_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (SC301IOT_I2C_ADDR_IS_VALID(s32I2cAddr)) + sc301iot_i2c_addr = s32I2cAddr; +} + +static CVI_S32 sc301iot_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC301IOT_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC301IOT_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC301IOT_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC301IOT_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC301IOT_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC301IOT_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC301IOT_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC301IOT_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC301IOT_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC301IOT_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC301IOT_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC301IOT_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc301iot_standby, + .pfnRestart = sc301iot_restart, + .pfnMirrorFlip = sc301iot_mirror_flip, + .pfnWriteReg = sc301iot_write_register, + .pfnReadReg = sc301iot_read_register, + .pfnSetBusInfo = sc301iot_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc301iot_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc301iot/sc301iot_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc301iot/sc301iot_cmos_ex.h new file mode 100644 index 000000000..9a6045682 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc301iot/sc301iot_cmos_ex.h @@ -0,0 +1,78 @@ +#ifndef __SC301IOT_CMOS_EX_H_ +#define __SC301IOT_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc301iot_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_2_ADDR, + LINEAR_AGAIN_ADDR, + LINEAR_DGAIN_0_ADDR, + LINEAR_DGAIN_1_ADDR, + LINEAR_VMAX_0_ADDR, + LINEAR_VMAX_1_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC301IOT_MODE_E { + SC301IOT_MODE_1536P30 = 0, + SC301IOT_MODE_NUM +} SC301IOT_MODE_E; + +typedef struct _SC301IOT_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + char name[64]; +} SC301IOT_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC301IOT[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC301IOT_BusInfo[]; +extern CVI_U16 g_au16SC301IOT_GainMode[]; +extern CVI_U16 g_au16SC301IOT_L2SMode[]; +extern CVI_U8 sc301iot_i2c_addr; +extern const CVI_U32 sc301iot_addr_byte; +extern const CVI_U32 sc301iot_data_byte; +extern void sc301iot_init(VI_PIPE ViPipe); +extern void sc301iot_exit(VI_PIPE ViPipe); +extern void sc301iot_standby(VI_PIPE ViPipe); +extern void sc301iot_restart(VI_PIPE ViPipe); +extern int sc301iot_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc301iot_read_register(VI_PIPE ViPipe, int addr); +extern void sc301iot_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc301iot_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC301IOT_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc301iot/sc301iot_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc301iot/sc301iot_cmos_param.h new file mode 100644 index 000000000..f8a1f284c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc301iot/sc301iot_cmos_param.h @@ -0,0 +1,121 @@ +#ifndef __SC301IOT_CMOS_PARAM_H_ +#define __SC301IOT_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc301iot_cmos_ex.h" + +static const SC301IOT_MODE_S g_astSC301IOT_mode[SC301IOT_MODE_NUM] = { + [SC301IOT_MODE_1536P30] = { + .name = "1536p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2048, + .u32Height = 1536, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2048, + .u32Height = 1536, + }, + .stMaxSize = { + .u32Width = 2048, + .u32Height = 1536, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.46, /* 1600 * 30 / 0x7FFF*/ + .u32HtsDef = 2250, + .u32VtsDef = 1600, + .stExp[0] = { + .u16Min = 2, + .u16Max = 1600 - 8, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 51412, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 32256, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc301iot_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 0, 1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 1, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC301IOT_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc301iot/sc301iot_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc301iot/sc301iot_sensor_ctl.c new file mode 100644 index 000000000..fcb6494c5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc301iot/sc301iot_sensor_ctl.c @@ -0,0 +1,379 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc301iot_cmos_ex.h" + +static void sc301iot_linear_1536p30_init(VI_PIPE ViPipe); + +CVI_U8 sc301iot_i2c_addr = 0x30; /* I2C Address of SC301IOT */ +const CVI_U32 sc301iot_addr_byte = 2; +const CVI_U32 sc301iot_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc301iot_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC301IOT_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc301iot_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc301iot_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc301iot_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + char buf[8]; + int idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc301iot_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc301iot_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc301iot_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc301iot_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc301iot_write_register(VI_PIPE ViPipe, int addr, int data) +{ + int idx = 0; + int ret; + char buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc301iot_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc301iot_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc301iot_addr_byte + sc301iot_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc301iot_standby(VI_PIPE ViPipe) +{ + sc301iot_write_register(ViPipe, 0x0100, 0x00); +} + +void sc301iot_restart(VI_PIPE ViPipe) +{ + sc301iot_write_register(ViPipe, 0x0103, 0x01); + delay_ms(1); +} + +void sc301iot_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC301IOT[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc301iot_write_register(ViPipe, + g_pastSC301IOT[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC301IOT[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC301IOT_CHIP_ID_HI_ADDR 0x3107 +#define SC301IOT_CHIP_ID_LO_ADDR 0x3108 +#define SC301IOT_CHIP_ID 0xcc40 + +void sc301iot_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc301iot_write_register(ViPipe, 0x3221, val); +} + +int sc301iot_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc301iot_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc301iot_read_register(ViPipe, SC301IOT_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc301iot_read_register(ViPipe, SC301IOT_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC301IOT_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc301iot_init(VI_PIPE ViPipe) +{ + sc301iot_i2c_init(ViPipe); + + //linear mode only + sc301iot_linear_1536p30_init(ViPipe); + + g_pastSC301IOT[ViPipe]->bInit = CVI_TRUE; +} + +void sc301iot_exit(VI_PIPE ViPipe) +{ + sc301iot_i2c_exit(ViPipe); +} + +static void sc301iot_linear_1536p30_init(VI_PIPE ViPipe) +{ + sc301iot_write_register(ViPipe, 0x0103, 0x01); + sc301iot_write_register(ViPipe, 0x0100, 0x00); + sc301iot_write_register(ViPipe, 0x36e9, 0x80); + sc301iot_write_register(ViPipe, 0x37f9, 0x80); + sc301iot_write_register(ViPipe, 0x301c, 0x78); + sc301iot_write_register(ViPipe, 0x301f, 0x01); + sc301iot_write_register(ViPipe, 0x30b8, 0x44); + sc301iot_write_register(ViPipe, 0x3208, 0x08); + sc301iot_write_register(ViPipe, 0x3209, 0x00); + sc301iot_write_register(ViPipe, 0x320a, 0x06); + sc301iot_write_register(ViPipe, 0x320b, 0x00); + sc301iot_write_register(ViPipe, 0x320c, 0x04); + sc301iot_write_register(ViPipe, 0x320d, 0x65); + sc301iot_write_register(ViPipe, 0x320e, 0x06); + sc301iot_write_register(ViPipe, 0x320f, 0x40); + sc301iot_write_register(ViPipe, 0x3214, 0x11); + sc301iot_write_register(ViPipe, 0x3215, 0x11); + sc301iot_write_register(ViPipe, 0x3223, 0xd0); + sc301iot_write_register(ViPipe, 0x3231, 0x01); + sc301iot_write_register(ViPipe, 0x3253, 0x0c); + sc301iot_write_register(ViPipe, 0x3274, 0x09); + sc301iot_write_register(ViPipe, 0x3301, 0x08); + sc301iot_write_register(ViPipe, 0x3306, 0x58); + sc301iot_write_register(ViPipe, 0x3308, 0x08); + sc301iot_write_register(ViPipe, 0x330a, 0x00); + sc301iot_write_register(ViPipe, 0x330b, 0xe0); + sc301iot_write_register(ViPipe, 0x330e, 0x10); + sc301iot_write_register(ViPipe, 0x3314, 0x14); + sc301iot_write_register(ViPipe, 0x331e, 0x55); + sc301iot_write_register(ViPipe, 0x331f, 0x7d); + sc301iot_write_register(ViPipe, 0x3333, 0x10); + sc301iot_write_register(ViPipe, 0x3334, 0x40); + sc301iot_write_register(ViPipe, 0x335e, 0x06); + sc301iot_write_register(ViPipe, 0x335f, 0x08); + sc301iot_write_register(ViPipe, 0x3364, 0x5e); + sc301iot_write_register(ViPipe, 0x337c, 0x02); + sc301iot_write_register(ViPipe, 0x337d, 0x0a); + sc301iot_write_register(ViPipe, 0x3390, 0x01); + sc301iot_write_register(ViPipe, 0x3391, 0x03); + sc301iot_write_register(ViPipe, 0x3392, 0x07); + sc301iot_write_register(ViPipe, 0x3393, 0x08); + sc301iot_write_register(ViPipe, 0x3394, 0x08); + sc301iot_write_register(ViPipe, 0x3395, 0x08); + sc301iot_write_register(ViPipe, 0x3396, 0x08); + sc301iot_write_register(ViPipe, 0x3397, 0x09); + sc301iot_write_register(ViPipe, 0x3398, 0x1f); + sc301iot_write_register(ViPipe, 0x3399, 0x08); + sc301iot_write_register(ViPipe, 0x339a, 0x0a); + sc301iot_write_register(ViPipe, 0x339b, 0x40); + sc301iot_write_register(ViPipe, 0x339c, 0x88); + sc301iot_write_register(ViPipe, 0x33a2, 0x04); + sc301iot_write_register(ViPipe, 0x33ad, 0x0c); + sc301iot_write_register(ViPipe, 0x33b1, 0x80); + sc301iot_write_register(ViPipe, 0x33b3, 0x30); + sc301iot_write_register(ViPipe, 0x33f9, 0x68); + sc301iot_write_register(ViPipe, 0x33fb, 0x80); + sc301iot_write_register(ViPipe, 0x33fc, 0x48); + sc301iot_write_register(ViPipe, 0x33fd, 0x5f); + sc301iot_write_register(ViPipe, 0x349f, 0x03); + sc301iot_write_register(ViPipe, 0x34a6, 0x48); + sc301iot_write_register(ViPipe, 0x34a7, 0x5f); + sc301iot_write_register(ViPipe, 0x34a8, 0x30); + sc301iot_write_register(ViPipe, 0x34a9, 0x30); + sc301iot_write_register(ViPipe, 0x34aa, 0x00); + sc301iot_write_register(ViPipe, 0x34ab, 0xf0); + sc301iot_write_register(ViPipe, 0x34ac, 0x01); + sc301iot_write_register(ViPipe, 0x34ad, 0x08); + sc301iot_write_register(ViPipe, 0x34f8, 0x5f); + sc301iot_write_register(ViPipe, 0x34f9, 0x10); + sc301iot_write_register(ViPipe, 0x3630, 0xf0); + sc301iot_write_register(ViPipe, 0x3631, 0x85); + sc301iot_write_register(ViPipe, 0x3632, 0x74); + sc301iot_write_register(ViPipe, 0x3633, 0x22); + sc301iot_write_register(ViPipe, 0x3637, 0x4d); + sc301iot_write_register(ViPipe, 0x3638, 0xcb); + sc301iot_write_register(ViPipe, 0x363a, 0x8b); + sc301iot_write_register(ViPipe, 0x363c, 0x08); + sc301iot_write_register(ViPipe, 0x3640, 0x00); + sc301iot_write_register(ViPipe, 0x3641, 0x38); + sc301iot_write_register(ViPipe, 0x3670, 0x4e); + sc301iot_write_register(ViPipe, 0x3674, 0xc0); + sc301iot_write_register(ViPipe, 0x3675, 0xb0); + sc301iot_write_register(ViPipe, 0x3676, 0xa0); + sc301iot_write_register(ViPipe, 0x3677, 0x83); + sc301iot_write_register(ViPipe, 0x3678, 0x87); + sc301iot_write_register(ViPipe, 0x3679, 0x8a); + sc301iot_write_register(ViPipe, 0x367c, 0x49); + sc301iot_write_register(ViPipe, 0x367d, 0x4f); + sc301iot_write_register(ViPipe, 0x367e, 0x48); + sc301iot_write_register(ViPipe, 0x367f, 0x4b); + sc301iot_write_register(ViPipe, 0x3690, 0x33); + sc301iot_write_register(ViPipe, 0x3691, 0x33); + sc301iot_write_register(ViPipe, 0x3692, 0x44); + sc301iot_write_register(ViPipe, 0x3699, 0x8a); + sc301iot_write_register(ViPipe, 0x369a, 0xa1); + sc301iot_write_register(ViPipe, 0x369b, 0xc2); + sc301iot_write_register(ViPipe, 0x369c, 0x48); + sc301iot_write_register(ViPipe, 0x369d, 0x4f); + sc301iot_write_register(ViPipe, 0x36a2, 0x4b); + sc301iot_write_register(ViPipe, 0x36a3, 0x4f); + sc301iot_write_register(ViPipe, 0x370f, 0x01); + sc301iot_write_register(ViPipe, 0x3714, 0x80); + sc301iot_write_register(ViPipe, 0x3722, 0x09); + sc301iot_write_register(ViPipe, 0x3724, 0x41); + sc301iot_write_register(ViPipe, 0x3725, 0xc1); + sc301iot_write_register(ViPipe, 0x3728, 0x00); + sc301iot_write_register(ViPipe, 0x3771, 0x09); + sc301iot_write_register(ViPipe, 0x3772, 0x05); + sc301iot_write_register(ViPipe, 0x3773, 0x05); + sc301iot_write_register(ViPipe, 0x377a, 0x48); + sc301iot_write_register(ViPipe, 0x377b, 0x49); + sc301iot_write_register(ViPipe, 0x3905, 0x8d); + sc301iot_write_register(ViPipe, 0x391d, 0x08); + sc301iot_write_register(ViPipe, 0x3922, 0x1a); + sc301iot_write_register(ViPipe, 0x3926, 0x21); + sc301iot_write_register(ViPipe, 0x3933, 0x80); + sc301iot_write_register(ViPipe, 0x3934, 0x0d); + sc301iot_write_register(ViPipe, 0x3937, 0x6a); + sc301iot_write_register(ViPipe, 0x3939, 0x00); + sc301iot_write_register(ViPipe, 0x393a, 0x0e); + sc301iot_write_register(ViPipe, 0x39dc, 0x02); + sc301iot_write_register(ViPipe, 0x3e00, 0x00); + sc301iot_write_register(ViPipe, 0x3e01, 0x63); + sc301iot_write_register(ViPipe, 0x3e02, 0x80); + sc301iot_write_register(ViPipe, 0x3e03, 0x0b); + sc301iot_write_register(ViPipe, 0x3e1b, 0x2a); + sc301iot_write_register(ViPipe, 0x4407, 0x34); + sc301iot_write_register(ViPipe, 0x440e, 0x02); + sc301iot_write_register(ViPipe, 0x5001, 0x40); + sc301iot_write_register(ViPipe, 0x5007, 0x80); + sc301iot_write_register(ViPipe, 0x36e9, 0x24); + sc301iot_write_register(ViPipe, 0x37f9, 0x24); + + sc301iot_default_reg_init(ViPipe); + + sc301iot_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC301IOT 1536P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc3332/Makefile b/middleware/v2/component/isp/sensor/cv180x/sms_sc3332/Makefile new file mode 100644 index 000000000..90edabd68 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc3332/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc3332.a +TARGET_SO = $(MW_LIB)/libsns_sc3332.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc3332/sc3332_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc3332/sc3332_cmos.c new file mode 100644 index 000000000..9dd51f537 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc3332/sc3332_cmos.c @@ -0,0 +1,933 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc3332_cmos_ex.h" +#include "sc3332_cmos_param.h" + + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC3332_ID 3336 +#define SC3332_I2C_ADDR_1 0x30 +#define SC3332_I2C_ADDR_2 0x32 +#define SC3332_I2C_ADDR_IS_VALID(addr) ((addr) == SC3332_I2C_ADDR_1 || (addr) == SC3332_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC3332[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC3332_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC3332[dev]) +#define SC3332_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC3332[dev] = pstCtx) +#define SC3332_SENSOR_RESET_CTX(dev) (g_pastSC3332[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC3332_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC3332_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC3332_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc3332_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC3332 Lines Range*****/ +#define SC3332_FULL_LINES_MAX (0xFFFF) + +/*****SC3332 Register Address*****/ +#define SC3332_EXP_H_ADDR (0x3e00) +#define SC3332_EXP_M_ADDR (0x3e01) +#define SC3332_EXP_L_ADDR (0x3e02) + +#define SC3332_AGAIN_ADDR (0x3e09) + +#define SC3332_DGAIN_H_ADDR (0x3e06) +#define SC3332_DGAIN_L_ADDR (0x3e07) + +#define SC3332_VMAX_H_ADDR (0x320e) +#define SC3332_VMAX_L_ADDR (0x320f) + +#define SC3332_RES_IS_1296P(w, h) ((w) == 2304 && (h) == 1296) + +#define SC3332_EXPACCURACY (1) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC3332_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC3332_mode[pstSnsState->u8ImgMode]; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC3332_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC3332_EXPACCURACY; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = pstAeSnsDft->u32MaxIntTime; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC3332_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC3332_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC3332_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC3332_MODE_2304X1296P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC3332_FULL_LINES_MAX) ? SC3332_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 10; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 0 + * max : vts - 10 + * step : 1 + */ + u32MinTime = 0; + u32MaxTime = pstSnsState->au32FL[0] - 10; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_M_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_ADDR].u32Data = ((u32TmpIntTime & 0x000F) << 4); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +typedef struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} gain_tbl_info_s; + +static struct gain_tbl_info_s DgainInfo[4] = { + { + .gainMax = 2016, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 8064, + .idxBase = 64, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 16128, + .idxBase = 96, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, +}; + +static CVI_U32 Dgain_table[128] = { + 1024, 1055, 1088, 1120, 1152, 1183, 1216, 1248, 1280, 1311, 1344, 1376, + 1408, 1439, 1472, 1504, 1536, 1567, 1600, 1632, 1664, 1695, 1728, 1760, + 1792, 1823, 1856, 1888, 1920, 1951, 1984, 2016, 2048, 2112, 2176, 2240, + 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008, + 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, + 3840, 3904, 3968, 4032, 4096, 4224, 4352, 4480, 4608, 4736, 4864, 4992, + 5120, 5248, 5376, 5504, 5632, 5760, 5888, 6016, 6144, 6272, 6400, 6528, + 6656, 6784, 6912, 7040, 7168, 7296, 7424, 7552, 7680, 7808, 7936, 8064, + 8192, 8448, 8704, 8960, 9216, 9472, 9728, 9984, 10240, 10496, 10752, 11008, + 11264, 11520, 11776, 12032, 12288, 12544, 12800, 13056, 13312, 13568, 13824, + 14080, 14336, 14592, 14848, 15104, 15360, 15616, 15872, 16128 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 again = *pu32AgainLin; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (again < 2048) { + *pu32AgainDb = 0x00; + *pu32AgainLin = 1024; + } else if (again < 4096) { + *pu32AgainDb = 0x08; + *pu32AgainLin = 2048; + } else if (again < 8192) { + *pu32AgainDb = 0x09; + *pu32AgainLin = 4096; + } else if (again < 16384) { + *pu32AgainDb = 0x0b; + *pu32AgainLin = 8192; + } else if (again < 32768) { + *pu32AgainDb = 0x0f; + *pu32AgainLin = 16384; + } else { + *pu32AgainDb = 0x1f; + *pu32AgainLin = 32768; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[127]) { + *pu32DgainLin = Dgain_table[127]; + *pu32DgainDb = 127; + return CVI_SUCCESS; + } + + for (i = 1; i < 128; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L_ADDR].u32Data = (u32Dgain & 0xFF); + + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC3332_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC3332_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC3332_MODE_2304X1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC3332_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = ISP_SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC3332_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc3332_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc3332_addr_byte; + pstI2c_data[i].u32DataByteNum = sc3332_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC3332_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_M_ADDR].u32RegAddr = SC3332_EXP_M_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC3332_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = SC3332_AGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC3332_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC3332_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC3332_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC3332_VMAX_L_ADDR; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC3332_RES_IS_1296P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC3332_MODE_2304X1296P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeSc3332_MirrorFip[ViPipe] != eSnsMirrorFlip) { + sc3332_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeSc3332_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC3332_MODE_S *pstMode = CVI_NULL; + + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC3332_MODE_2304X1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC3332_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc3332_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC3332_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC3332_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc3332_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc3332_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc3332_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (SC3332_I2C_ADDR_IS_VALID(s32I2cAddr)) + sc3332_i2c_addr = s32I2cAddr; +} + +static CVI_S32 sc3332_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC3332_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC3332_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC3332_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC3332_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC3332_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC3332_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC3332_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC3332_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC3332_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC3332_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC3332_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC3332_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc3332_standby, + .pfnRestart = sc3332_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = sc3332_write_register, + .pfnReadReg = sc3332_read_register, + .pfnSetBusInfo = sc3332_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc3332_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc3332/sc3332_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc3332/sc3332_cmos_ex.h new file mode 100644 index 000000000..99f3443a3 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc3332/sc3332_cmos_ex.h @@ -0,0 +1,80 @@ +#ifndef __SC3332_CMOS_EX_H_ +#define __SC3332_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc3332_linear_regs_e { + LINEAR_EXP_H_ADDR, + LINEAR_EXP_M_ADDR, + LINEAR_EXP_L_ADDR, + LINEAR_AGAIN_ADDR, + LINEAR_DGAIN_H_ADDR, + LINEAR_DGAIN_L_ADDR, + LINEAR_VMAX_H_ADDR, + LINEAR_VMAX_L_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC3332_MODE_E { + SC3332_MODE_2304X1296P30 = 0, + SC3332_MODE_LINEAR_NUM, + SC3332_MODE_2304X1296P30_WDR = SC3332_MODE_LINEAR_NUM, + SC3332_MODE_NUM +} SC3332_MODE_E; + +typedef struct _SC3332_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + char name[64]; +} SC3332_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC3332[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC3332_BusInfo[]; +extern CVI_U16 g_au16SC3332_GainMode[]; +extern CVI_U16 g_au16SC3332_L2SMode[]; +extern CVI_U8 sc3332_i2c_addr; +extern const CVI_U32 sc3332_addr_byte; +extern const CVI_U32 sc3332_data_byte; +extern void sc3332_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void sc3332_init(VI_PIPE ViPipe); +extern void sc3332_exit(VI_PIPE ViPipe); +extern void sc3332_standby(VI_PIPE ViPipe); +extern void sc3332_restart(VI_PIPE ViPipe); +extern int sc3332_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc3332_read_register(VI_PIPE ViPipe, int addr); +extern int sc3332_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC3332_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc3332/sc3332_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc3332/sc3332_cmos_param.h new file mode 100644 index 000000000..fb991d11e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc3332/sc3332_cmos_param.h @@ -0,0 +1,121 @@ +#ifndef __SC3332_CMOS_PARAM_H_ +#define __SC3332_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc3332_cmos_ex.h" + +static const SC3332_MODE_S g_astSC3332_mode[SC3332_MODE_NUM] = { + [SC3332_MODE_2304X1296P30] = { + .name = "1296p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2304, + .u32Height = 1296, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2304, + .u32Height = 1296, + }, + .stMaxSize = { + .u32Width = 2304, + .u32Height = 1296, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.61, /* 1350 * 30 / 0xFFFF */ + .u32HtsDef = 4938, + .u32VtsDef = 1344, + .stExp[0] = { + .u16Min = 2, + .u16Max = 1344,//vts - 6 + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 32768, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 16128, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc3332_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {3, 2, 4, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC3332_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc3332/sc3332_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc3332/sc3332_sensor_ctl.c new file mode 100644 index 000000000..d8b92b8a1 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc3332/sc3332_sensor_ctl.c @@ -0,0 +1,379 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc3332_cmos_ex.h" + +#define SC3332_CHIP_ID_HI_ADDR 0x3107 +#define SC3332_CHIP_ID_LO_ADDR 0x3108 +#define SC3332_CHIP_ID 0xcc44 + +static void sc3332_linear_1296P30_init(VI_PIPE ViPipe); + +CVI_U8 sc3332_i2c_addr = 0x30; /* I2C Address of SC3332 */ +const CVI_U32 sc3332_addr_byte = 2; +const CVI_U32 sc3332_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc3332_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC3332_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc3332_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc3332_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc3332_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc3332_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc3332_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc3332_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc3332_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc3332_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc3332_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc3332_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc3332_addr_byte + sc3332_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc3332_prog(VI_PIPE ViPipe, int *rom) +{ + int i = 0; + + while (1) { + int lookup = rom[i++]; + int addr = (lookup >> 16) & 0xFFFF; + int data = lookup & 0xFFFF; + + if (addr == 0xFFFE) + delay_ms(data); + else if (addr != 0xFFFF) + sc3332_write_register(ViPipe, addr, data); + } +} + +void sc3332_standby(VI_PIPE ViPipe) +{ + sc3332_write_register(ViPipe, 0x0100, 0x00); +} + +void sc3332_restart(VI_PIPE ViPipe) +{ + sc3332_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc3332_write_register(ViPipe, 0x0100, 0x01); +} + +void sc3332_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC3332[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC3332[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc3332_write_register(ViPipe, + g_pastSC3332[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC3332[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc3332_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc3332_write_register(ViPipe, 0x3221, val); +} + +int sc3332_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc3332_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc3332_read_register(ViPipe, SC3332_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc3332_read_register(ViPipe, SC3332_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC3332_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void sc3332_init(VI_PIPE ViPipe) +{ + sc3332_i2c_init(ViPipe); + + //linear mode only + sc3332_linear_1296P30_init(ViPipe); + + g_pastSC3332[ViPipe]->bInit = CVI_TRUE; +} + +void sc3332_exit(VI_PIPE ViPipe) +{ + sc3332_i2c_exit(ViPipe); +} + +/* 1296P30 and 1296P25 */ +static void sc3332_linear_1296P30_init(VI_PIPE ViPipe) +{ + sc3332_write_register(ViPipe, 0x0103, 0x01); + sc3332_write_register(ViPipe, 0x36e9, 0x80); + sc3332_write_register(ViPipe, 0x37f9, 0x80); + sc3332_write_register(ViPipe, 0x301f, 0x01); + sc3332_write_register(ViPipe, 0x30b8, 0x44); + sc3332_write_register(ViPipe, 0x3253, 0x10); + sc3332_write_register(ViPipe, 0x3301, 0x08); + sc3332_write_register(ViPipe, 0x3302, 0xff); + sc3332_write_register(ViPipe, 0x3305, 0x00); + sc3332_write_register(ViPipe, 0x3306, 0x90); + sc3332_write_register(ViPipe, 0x3308, 0x18); + sc3332_write_register(ViPipe, 0x330a, 0x01); + sc3332_write_register(ViPipe, 0x330b, 0xc0); + sc3332_write_register(ViPipe, 0x330d, 0x70); + sc3332_write_register(ViPipe, 0x330e, 0x30); + sc3332_write_register(ViPipe, 0x3314, 0x15); + sc3332_write_register(ViPipe, 0x3333, 0x10); + sc3332_write_register(ViPipe, 0x3334, 0x40); + sc3332_write_register(ViPipe, 0x335e, 0x06); + sc3332_write_register(ViPipe, 0x335f, 0x0a); + sc3332_write_register(ViPipe, 0x3364, 0x5e); + sc3332_write_register(ViPipe, 0x337d, 0x0e); + sc3332_write_register(ViPipe, 0x3390, 0x08); + sc3332_write_register(ViPipe, 0x3391, 0x09); + sc3332_write_register(ViPipe, 0x3392, 0x0f); + sc3332_write_register(ViPipe, 0x3393, 0x10); + sc3332_write_register(ViPipe, 0x3394, 0x80); + sc3332_write_register(ViPipe, 0x3395, 0xff); + sc3332_write_register(ViPipe, 0x33a2, 0x04); + sc3332_write_register(ViPipe, 0x33ad, 0x2c); + sc3332_write_register(ViPipe, 0x33b3, 0x48); + sc3332_write_register(ViPipe, 0x33f8, 0x00); + sc3332_write_register(ViPipe, 0x33f9, 0xc0); + sc3332_write_register(ViPipe, 0x33fa, 0x00); + sc3332_write_register(ViPipe, 0x33fb, 0xf0); + sc3332_write_register(ViPipe, 0x33fc, 0x0b); + sc3332_write_register(ViPipe, 0x33fd, 0x0f); + sc3332_write_register(ViPipe, 0x349f, 0x03); + sc3332_write_register(ViPipe, 0x34a6, 0x0b); + sc3332_write_register(ViPipe, 0x34a7, 0x0f); + sc3332_write_register(ViPipe, 0x34a8, 0x40); + sc3332_write_register(ViPipe, 0x34a9, 0x30); + sc3332_write_register(ViPipe, 0x34aa, 0x01); + sc3332_write_register(ViPipe, 0x34ab, 0xf0); + sc3332_write_register(ViPipe, 0x34ac, 0x02); + sc3332_write_register(ViPipe, 0x34ad, 0x10); + sc3332_write_register(ViPipe, 0x34f8, 0x1f); + sc3332_write_register(ViPipe, 0x34f9, 0x30); + sc3332_write_register(ViPipe, 0x3630, 0xf0); + sc3332_write_register(ViPipe, 0x3631, 0x8c); + sc3332_write_register(ViPipe, 0x3632, 0x78); + sc3332_write_register(ViPipe, 0x3633, 0x33); + sc3332_write_register(ViPipe, 0x363a, 0xcc); + sc3332_write_register(ViPipe, 0x363c, 0x0f); + sc3332_write_register(ViPipe, 0x363f, 0xc0); + sc3332_write_register(ViPipe, 0x3641, 0x00); + sc3332_write_register(ViPipe, 0x3650, 0x33); // LP 0x33 + sc3332_write_register(ViPipe, 0x3670, 0x5e); + sc3332_write_register(ViPipe, 0x3674, 0xf0); + sc3332_write_register(ViPipe, 0x3675, 0xf0); + sc3332_write_register(ViPipe, 0x3676, 0xd0); + sc3332_write_register(ViPipe, 0x3677, 0x87); + sc3332_write_register(ViPipe, 0x3678, 0x8a); + sc3332_write_register(ViPipe, 0x3679, 0x8d); + sc3332_write_register(ViPipe, 0x367c, 0x08); + sc3332_write_register(ViPipe, 0x367d, 0x0f); + sc3332_write_register(ViPipe, 0x367e, 0x08); + sc3332_write_register(ViPipe, 0x367f, 0x0f); + sc3332_write_register(ViPipe, 0x3690, 0x74); + sc3332_write_register(ViPipe, 0x3691, 0x78); + sc3332_write_register(ViPipe, 0x3692, 0x78); + sc3332_write_register(ViPipe, 0x3696, 0x33); + sc3332_write_register(ViPipe, 0x3697, 0x33); + sc3332_write_register(ViPipe, 0x3698, 0x45); + sc3332_write_register(ViPipe, 0x369c, 0x0b); + sc3332_write_register(ViPipe, 0x369d, 0x0f); + sc3332_write_register(ViPipe, 0x36a0, 0x09); + sc3332_write_register(ViPipe, 0x36a1, 0x0f); + sc3332_write_register(ViPipe, 0x36b0, 0x88); + sc3332_write_register(ViPipe, 0x36b1, 0x91); + sc3332_write_register(ViPipe, 0x36b2, 0xa4); + sc3332_write_register(ViPipe, 0x36b3, 0xcf); + sc3332_write_register(ViPipe, 0x36b4, 0x09); + sc3332_write_register(ViPipe, 0x36b5, 0x0b); + sc3332_write_register(ViPipe, 0x36b6, 0x0f); + sc3332_write_register(ViPipe, 0x370f, 0x01); + sc3332_write_register(ViPipe, 0x3722, 0x05); + sc3332_write_register(ViPipe, 0x3724, 0x31); + sc3332_write_register(ViPipe, 0x3771, 0x09); + sc3332_write_register(ViPipe, 0x3772, 0x05); + sc3332_write_register(ViPipe, 0x3773, 0x05); + sc3332_write_register(ViPipe, 0x377a, 0x0b); + sc3332_write_register(ViPipe, 0x377b, 0x0f); + sc3332_write_register(ViPipe, 0x3904, 0x04); + sc3332_write_register(ViPipe, 0x3905, 0x8c); + sc3332_write_register(ViPipe, 0x391d, 0x01); + sc3332_write_register(ViPipe, 0x3922, 0x1f); + sc3332_write_register(ViPipe, 0x3925, 0x0f); + sc3332_write_register(ViPipe, 0x3926, 0x21); + sc3332_write_register(ViPipe, 0x3933, 0x80); + sc3332_write_register(ViPipe, 0x3934, 0x03); + sc3332_write_register(ViPipe, 0x3937, 0x6f); + sc3332_write_register(ViPipe, 0x39dc, 0x02); + sc3332_write_register(ViPipe, 0x3e00, 0x00); + sc3332_write_register(ViPipe, 0x3e01, 0x54); + sc3332_write_register(ViPipe, 0x3e02, 0x00); + sc3332_write_register(ViPipe, 0x440e, 0x02); + sc3332_write_register(ViPipe, 0x4509, 0x28); + sc3332_write_register(ViPipe, 0x450d, 0x32); + sc3332_write_register(ViPipe, 0x5780, 0x66); + sc3332_write_register(ViPipe, 0x578d, 0x40); + sc3332_write_register(ViPipe, 0x36e9, 0x54); + sc3332_write_register(ViPipe, 0x37f9, 0x27); + + sc3332_default_reg_init(ViPipe); + + sc3332_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC3332 1296P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc3335/Makefile b/middleware/v2/component/isp/sensor/cv180x/sms_sc3335/Makefile new file mode 100644 index 000000000..3275dbe5c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc3335/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc3335.a +TARGET_SO = $(MW_LIB)/libsns_sc3335.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc3335/sc3335_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc3335/sc3335_cmos.c new file mode 100644 index 000000000..ef346714b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc3335/sc3335_cmos.c @@ -0,0 +1,1080 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc3335_cmos_ex.h" +#include "sc3335_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC3335_ID 3335 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC3335[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC3335_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC3335[dev]) +#define SC3335_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC3335[dev] = pstCtx) +#define SC3335_SENSOR_RESET_CTX(dev) (g_pastSC3335[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC3335_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC3335_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC3335_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc3335_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC3335 Lines Range*****/ +#define SC3335_FULL_LINES_MAX (0x7FFF) + +/*****SC3335 Register Address*****/ +#define SC3335_EXP_H_ADDR (0x3e00) +#define SC3335_EXP_M_ADDR (0x3e01) +#define SC3335_EXP_L_ADDR (0x3e02) + +#define SC3335_AGAIN_H_ADDR (0x3e08) +#define SC3335_AGAIN_L_ADDR (0x3e09) + +#define SC3335_DGAIN_H_ADDR (0x3e06) +#define SC3335_DGAIN_L_ADDR (0x3e07) + +#define SC3335_VMAX_H_ADDR (0x320e) +#define SC3335_VMAX_L_ADDR (0x320f) + +#define SC3335_GAIN_LOGIC_H_ADDR (0x363c) +#define SC3335_GAIN_LOGIC_L_ADDR (0x330e) + +#define SC3335_GAIN_DPC_ADDR (0x5799) +#define SC3335_HOLD_ADDR (0x3812) + +#define SC3335_RES_IS_1296P(w, h) ((w) <= 2304 && (h) <= 1296) + +#define SC3335_EXPACCURACY (0.5) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC3335_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC3335_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC3335_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC3335_EXPACCURACY; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = pstAeSnsDft->u32MaxIntTime; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC3335_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC3335_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC3335_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC3335_MODE_2304X1296P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC3335_FULL_LINES_MAX) ? SC3335_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = 2 * pstSnsState->u32FLStd - 10; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 3 + * max : 2 * vts - 10 + * step : 1 + */ + u32MinTime = 3; + u32MaxTime = 2 * pstSnsState->au32FL[0] - 10; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_M_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_ADDR].u32Data = ((u32TmpIntTime & 0x000F) << 4); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +typedef struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} gain_tbl_info_s; + +static struct gain_tbl_info_s AgainInfo[4] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x03, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x07, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 8128, + .idxBase = 128, + .regGain = 0x0F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 16256, + .idxBase = 192, + .regGain = 0x1F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, +}; +static CVI_U32 Again_table[256] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, 1248, 1263, 1280, + 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, 1472, 1487, 1504, 1519, 1536, 1552, + 1567, 1584, 1600, 1615, 1632, 1647, 1664, 1680, 1695, 1712, 1728, 1743, 1760, 1775, 1792, 1808, 1823, + 1840, 1856, 1871, 1888, 1903, 1920, 1936, 1951, 1968, 1984, 1999, 2016, 2031, 2048, 2079, 2112, 2144, + 2176, 2207, 2240, 2272, 2304, 2335, 2368, 2400, 2432, 2463, 2496, 2528, 2560, 2591, 2624, 2656, 2688, + 2719, 2752, 2784, 2816, 2847, 2880, 2912, 2944, 2975, 3008, 3040, 3072, 3103, 3136, 3168, 3200, 3231, + 3264, 3296, 3328, 3359, 3392, 3424, 3456, 3487, 3520, 3552, 3584, 3615, 3648, 3680, 3712, 3743, 3776, + 3808, 3840, 3871, 3904, 3936, 3968, 3999, 4032, 4064, 4096, 4160, 4224, 4288, 4352, 4416, 4480, 4544, + 4608, 4672, 4736, 4800, 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, 5504, 5568, 5632, + 5696, 5760, 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, 6464, 6528, 6592, 6656, 6720, + 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, 7424, 7488, 7552, 7616, 7680, 7744, 7808, + 7872, 7936, 8000, 8064, 8128, 8192, 8320, 8448, 8576, 8704, 8832, 8960, 9088, 9216, 9344, 9472, 9600, + 9728, 9856, 9984, 10112, 10240, 10368, 10496, 10624, 10752, 10880, 11008, 11136, 11264, 11392, 11520, + 11648, 11776, 11904, 12032, 12160, 12288, 12416, 12544, 12672, 12800, 12928, 13056, 13184, 13312, 13440, + 13568, 13696, 13824, 13952, 14080, 14208, 14336, 14464, 14592, 14720, 14848, 14976, 15104, 15232, 15360, + 15488, 15616, 15744, 15872, 16000, 16128, 16256 +}; + +static struct gain_tbl_info_s DgainInfo[5] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 8128, + .idxBase = 128, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 16256, + .idxBase = 192, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 32512, + .idxBase = 256, + .regGain = 0x0F, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, +}; + +static CVI_U32 Dgain_table[320] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, 1248, + 1263, 1280, 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, 1472, 1487, + 1504, 1519, 1536, 1552, 1567, 1584, 1600, 1615, 1632, 1647, 1664, 1680, 1695, 1712, 1728, + 1743, 1760, 1775, 1792, 1808, 1823, 1840, 1856, 1871, 1888, 1903, 1920, 1936, 1951, 1968, + 1984, 1999, 2016, 2031, 2048, 2079, 2112, 2144, 2176, 2207, 2240, 2272, 2304, 2335, 2368, + 2400, 2432, 2463, 2496, 2528, 2560, 2591, 2624, 2656, 2688, 2719, 2752, 2784, 2816, 2847, + 2880, 2912, 2944, 2975, 3008, 3040, 3072, 3103, 3136, 3168, 3200, 3231, 3264, 3296, 3328, + 3359, 3392, 3424, 3456, 3487, 3520, 3552, 3584, 3615, 3648, 3680, 3712, 3743, 3776, 3808, + 3840, 3871, 3904, 3936, 3968, 3999, 4032, 4064, 4096, 4160, 4224, 4288, 4352, 4416, 4480, + 4544, 4608, 4672, 4736, 4800, 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, + 5504, 5568, 5632, 5696, 5760, 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, + 6464, 6528, 6592, 6656, 6720, 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, + 7424, 7488, 7552, 7616, 7680, 7744, 7808, 7872, 7936, 8000, 8064, 8128, 8192, 8320, 8448, + 8576, 8704, 8832, 8960, 9088, 9216, 9344, 9472, 9600, 9728, 9856, 9984, 10112, 10240, 10368, + 10496, 10624, 10752, 10880, 11008, 11136, 11264, 11392, 11520, 11648, 11776, 11904, 12032, + 12160, 12288, 12416, 12544, 12672, 12800, 12928, 13056, 13184, 13312, 13440, 13568, 13696, + 13824, 13952, 14080, 14208, 14336, 14464, 14592, 14720, 14848, 14976, 15104, 15232, 15360, + 15488, 15616, 15744, 15872, 16000, 16128, 16256, 16384, 16640, 16896, 17152, 17408, 17664, + 17920, 18176, 18432, 18688, 18944, 19200, 19456, 19712, 19968, 20224, 20480, 20736, 20992, + 21248, 21504, 21760, 22016, 22272, 22528, 22784, 23040, 23296, 23552, 23808, 24064, 24320, + 24576, 24832, 25088, 25344, 25600, 25856, 26112, 26368, 26624, 26880, 27136, 27392, 27648, + 27904, 28160, 28416, 28672, 28928, 29184, 29440, 29696, 29952, 30208, 30464, 30720, 30976, + 31232, 31488, 31744, 32000, 32256, 32512 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[255]) { + *pu32AgainLin = Again_table[255]; + *pu32AgainDb = 255; + return CVI_SUCCESS; + } + + for (i = 1; i < 256; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[319]) { + *pu32DgainLin = Dgain_table[319]; + *pu32DgainDb = 319; + return CVI_SUCCESS; + } + + for (i = 1; i < 320; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L_ADDR].u32Data = (u32Again & 0xFF); + + /* gain logic setting. */ + if (sc3335_read_register(ViPipe, 0x3109) == 1) { + if (info->regGain < 0x07) { //gain < 2x + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_H_ADDR].u32Data = 0x05; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_L_ADDR].u32Data = 0x29; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } else if (info->regGain < 0x1F) { //2x <= gain < 8x + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_H_ADDR].u32Data = 0x07; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_L_ADDR].u32Data = 0x25; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } else { //gain > 8x + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_H_ADDR].u32Data = 0x07; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_L_ADDR].u32Data = 0x18; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } + } else { //2 == i2c_read(0x3109) || 3 == i2c_read(0x3109) + if (info->regGain < 0x07) { //gain < 2x + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_H_ADDR].u32Data = 0x06; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_L_ADDR].u32Data = 0x29; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } else if (info->regGain < 0x1F) { //2x <= gain < 8x + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_H_ADDR].u32Data = 0x08; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_L_ADDR].u32Data = 0x25; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } else { //gain > 8x + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_H_ADDR].u32Data = 0x08; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_L_ADDR].u32Data = 0x18; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } + } + + /* gain DPC setting. */ + if ((info->regGain > 0x0F) || (info->regGain == 0x0F && u32Again >= 0x60)) { //gain >= 6x + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_DPC_ADDR].u32Data = 0x07; + } else if ((info->regGain < 0x0F) || (info->regGain == 0x0F && u32Again == 0x40)) { //gain <= 4x + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_DPC_ADDR].u32Data = 0x00; + } + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L_ADDR].u32Data = (u32Dgain & 0xFF); + + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC3335_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC3335_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC3335_MODE_2304X1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC3335_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC3335_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc3335_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc3335_addr_byte; + pstI2c_data[i].u32DataByteNum = sc3335_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC3335_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_M_ADDR].u32RegAddr = SC3335_EXP_M_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC3335_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H_ADDR].u32RegAddr = SC3335_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L_ADDR].u32RegAddr = SC3335_AGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC3335_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC3335_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC3335_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC3335_VMAX_L_ADDR; + pstI2c_data[LINEAR_GAIN_DPC_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_DPC_ADDR].u32RegAddr = SC3335_GAIN_DPC_ADDR; + pstI2c_data[LINEAR_HOLD].u32RegAddr = SC3335_HOLD_ADDR; + pstI2c_data[LINEAR_GAIN_LOGIC_H_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_LOGIC_H_ADDR].u32RegAddr = SC3335_GAIN_LOGIC_H_ADDR; + pstI2c_data[LINEAR_GAIN_LOGIC_L_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_LOGIC_L_ADDR].u32RegAddr = SC3335_GAIN_LOGIC_L_ADDR; + pstI2c_data[LINEAR_REL].u32RegAddr = SC3335_HOLD_ADDR; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update group hold or not*/ + if ((pstCfg0->snsCfg.astI2cData[LINEAR_GAIN_LOGIC_H_ADDR].bUpdate == CVI_TRUE) + || (pstCfg0->snsCfg.astI2cData[LINEAR_GAIN_LOGIC_L_ADDR].bUpdate == CVI_TRUE)) { + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + + /* DPC updata when A/Dgain change */ + if ((pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H_ADDR].bUpdate == CVI_TRUE) + || (pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L_ADDR].bUpdate == CVI_TRUE) + || (pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H_ADDR].bUpdate == CVI_TRUE) + || (pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L_ADDR].bUpdate == CVI_TRUE)) { + pstI2c_data[LINEAR_GAIN_DPC_ADDR].bUpdate = CVI_TRUE; + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC3335_RES_IS_1296P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC3335_MODE_2304X1296P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeSc3335_MirrorFip[ViPipe] != eSnsMirrorFlip) { + sc3335_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeSc3335_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC3335_MODE_S *pstMode = CVI_NULL; + + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC3335_MODE_2304X1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC3335_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc3335_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC3335_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC3335_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc3335_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc3335_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc3335_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc3335_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC3335_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC3335_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC3335_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC3335_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC3335_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC3335_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC3335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC3335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC3335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC3335_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC3335_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC3335_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc3335_standby, + .pfnRestart = sc3335_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = sc3335_write_register, + .pfnReadReg = sc3335_read_register, + .pfnSetBusInfo = sc3335_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc3335_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc3335/sc3335_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc3335/sc3335_cmos_ex.h new file mode 100644 index 000000000..8dc546b12 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc3335/sc3335_cmos_ex.h @@ -0,0 +1,86 @@ +#ifndef __SC3335_CMOS_EX_H_ +#define __SC3335_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc3335_linear_regs_e { + LINEAR_EXP_H_ADDR, + LINEAR_EXP_M_ADDR, + LINEAR_EXP_L_ADDR, + LINEAR_AGAIN_H_ADDR, + LINEAR_AGAIN_L_ADDR, + LINEAR_DGAIN_H_ADDR, + LINEAR_DGAIN_L_ADDR, + LINEAR_VMAX_H_ADDR, + LINEAR_VMAX_L_ADDR, + LINEAR_GAIN_DPC_ADDR, + LINEAR_HOLD, + LINEAR_GAIN_LOGIC_H_ADDR, + LINEAR_GAIN_LOGIC_L_ADDR, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +typedef enum _SC3335_MODE_E { + SC3335_MODE_2304X1296P30 = 0, + SC3335_MODE_LINEAR_NUM, + SC3335_MODE_2304X1296P30_WDR = SC3335_MODE_LINEAR_NUM, + SC3335_MODE_NUM +} SC3335_MODE_E; + +typedef struct _SC3335_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + char name[64]; +} SC3335_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC3335[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC3335_BusInfo[]; +extern CVI_U16 g_au16SC3335_GainMode[]; +extern CVI_U16 g_au16SC3335_L2SMode[]; +extern const CVI_U8 sc3335_i2c_addr; +extern const CVI_U32 sc3335_addr_byte; +extern const CVI_U32 sc3335_data_byte; +extern void sc3335_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void sc3335_init(VI_PIPE ViPipe); +extern void sc3335_exit(VI_PIPE ViPipe); +extern void sc3335_standby(VI_PIPE ViPipe); +extern void sc3335_restart(VI_PIPE ViPipe); +extern int sc3335_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc3335_read_register(VI_PIPE ViPipe, int addr); +extern int sc3335_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC3335_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc3335/sc3335_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc3335/sc3335_cmos_param.h new file mode 100644 index 000000000..138b6085a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc3335/sc3335_cmos_param.h @@ -0,0 +1,125 @@ +#ifndef __SC3335_CMOS_PARAM_H_ +#define __SC3335_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc3335_cmos_ex.h" + +static const SC3335_MODE_S g_astSC3335_mode[SC3335_MODE_NUM] = { + [SC3335_MODE_2304X1296P30] = { + .name = "1296p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2304, + .u32Height = 1296, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2304, + .u32Height = 1296, + }, + .stMaxSize = { + .u32Width = 2304, + .u32Height = 1296, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.24, /* 1350 * 30 / 0x7FFF */ + .u32HtsDef = 2500, + .u32VtsDef = 1350, + .stExp[0] = { + .u16Min = 3,//3 + .u16Max = 1350 * 2 - 10,//2 * vts - 10 + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 16256, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 32512, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc3335_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {1, 3, 0, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 8, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC3335_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc3335/sc3335_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc3335/sc3335_sensor_ctl.c new file mode 100644 index 000000000..a30ee1218 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc3335/sc3335_sensor_ctl.c @@ -0,0 +1,336 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc3335_cmos_ex.h" + +#define SC3335_CHIP_ID_HI_ADDR 0x3107 +#define SC3335_CHIP_ID_LO_ADDR 0x3108 +#define SC3335_CHIP_ID 0xcc1a + +static void sc3335_linear_1296P30_init(VI_PIPE ViPipe); + +const CVI_U8 sc3335_i2c_addr = 0x30; /* I2C Address of SC3335 */ +const CVI_U32 sc3335_addr_byte = 2; +const CVI_U32 sc3335_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc3335_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC3335_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc3335_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc3335_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc3335_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc3335_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc3335_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc3335_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc3335_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc3335_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc3335_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc3335_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc3335_addr_byte + sc3335_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc3335_standby(VI_PIPE ViPipe) +{ + sc3335_write_register(ViPipe, 0x0100, 0x00); +} + +void sc3335_restart(VI_PIPE ViPipe) +{ + sc3335_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc3335_write_register(ViPipe, 0x0100, 0x01); +} + +void sc3335_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC3335[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC3335[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc3335_write_register(ViPipe, + g_pastSC3335[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC3335[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc3335_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc3335_write_register(ViPipe, 0x3221, val); +} + + +int sc3335_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + delay_ms(4); + if (sc3335_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc3335_read_register(ViPipe, SC3335_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc3335_read_register(ViPipe, SC3335_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC3335_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void sc3335_init(VI_PIPE ViPipe) +{ + sc3335_i2c_init(ViPipe); + + //linear mode only + sc3335_linear_1296P30_init(ViPipe); + + g_pastSC3335[ViPipe]->bInit = CVI_TRUE; +} + +void sc3335_exit(VI_PIPE ViPipe) +{ + sc3335_i2c_exit(ViPipe); +} + +/* 1296P30 and 1296P25 */ +static void sc3335_linear_1296P30_init(VI_PIPE ViPipe) +{ + sc3335_write_register(ViPipe, 0x0103, 0x01); + delay_ms(33); + sc3335_write_register(ViPipe, 0x0100, 0x00); + sc3335_write_register(ViPipe, 0x36e9, 0x80); + sc3335_write_register(ViPipe, 0x36f9, 0x80); + sc3335_write_register(ViPipe, 0x301f, 0x01); + sc3335_write_register(ViPipe, 0x3253, 0x04); + sc3335_write_register(ViPipe, 0x3301, 0x04); + sc3335_write_register(ViPipe, 0x3302, 0x10); + sc3335_write_register(ViPipe, 0x3304, 0x40); + sc3335_write_register(ViPipe, 0x3306, 0x40); + sc3335_write_register(ViPipe, 0x3309, 0x50); + sc3335_write_register(ViPipe, 0x330b, 0xb6); + sc3335_write_register(ViPipe, 0x330e, 0x29); + sc3335_write_register(ViPipe, 0x3310, 0x06); + sc3335_write_register(ViPipe, 0x3314, 0x96); + sc3335_write_register(ViPipe, 0x331e, 0x39); + sc3335_write_register(ViPipe, 0x331f, 0x49); + sc3335_write_register(ViPipe, 0x3320, 0x09); + sc3335_write_register(ViPipe, 0x3333, 0x10); + sc3335_write_register(ViPipe, 0x334c, 0x01); + sc3335_write_register(ViPipe, 0x3364, 0x17); + sc3335_write_register(ViPipe, 0x3367, 0x01); + sc3335_write_register(ViPipe, 0x3390, 0x04); + sc3335_write_register(ViPipe, 0x3391, 0x08); + sc3335_write_register(ViPipe, 0x3392, 0x38); + sc3335_write_register(ViPipe, 0x3393, 0x05); + sc3335_write_register(ViPipe, 0x3394, 0x09); + sc3335_write_register(ViPipe, 0x3395, 0x16); + sc3335_write_register(ViPipe, 0x33ac, 0x0c); + sc3335_write_register(ViPipe, 0x33ae, 0x1c); + sc3335_write_register(ViPipe, 0x3622, 0x16); + sc3335_write_register(ViPipe, 0x3637, 0x22); + sc3335_write_register(ViPipe, 0x363a, 0x1f); + sc3335_write_register(ViPipe, 0x363c, 0x05); + sc3335_write_register(ViPipe, 0x3670, 0x0e); + sc3335_write_register(ViPipe, 0x3674, 0xb0); + sc3335_write_register(ViPipe, 0x3675, 0x88); + sc3335_write_register(ViPipe, 0x3676, 0x68); + sc3335_write_register(ViPipe, 0x3677, 0x84); + sc3335_write_register(ViPipe, 0x3678, 0x85); + sc3335_write_register(ViPipe, 0x3679, 0x86); + sc3335_write_register(ViPipe, 0x367c, 0x18); + sc3335_write_register(ViPipe, 0x367d, 0x38); + sc3335_write_register(ViPipe, 0x367e, 0x08); + sc3335_write_register(ViPipe, 0x367f, 0x18); + sc3335_write_register(ViPipe, 0x3690, 0x43); + sc3335_write_register(ViPipe, 0x3691, 0x43); + sc3335_write_register(ViPipe, 0x3692, 0x44); + sc3335_write_register(ViPipe, 0x369c, 0x18); + sc3335_write_register(ViPipe, 0x369d, 0x38); + sc3335_write_register(ViPipe, 0x36ea, 0x3b); + sc3335_write_register(ViPipe, 0x36eb, 0x0d); + sc3335_write_register(ViPipe, 0x36ec, 0x1c); + sc3335_write_register(ViPipe, 0x36ed, 0x24); + sc3335_write_register(ViPipe, 0x36fa, 0x3b); + sc3335_write_register(ViPipe, 0x36fb, 0x00); + sc3335_write_register(ViPipe, 0x36fc, 0x10); + sc3335_write_register(ViPipe, 0x36fd, 0x24); + sc3335_write_register(ViPipe, 0x3908, 0x82); + sc3335_write_register(ViPipe, 0x391f, 0x18); + sc3335_write_register(ViPipe, 0x3e01, 0xa8); + sc3335_write_register(ViPipe, 0x3e02, 0x20); + sc3335_write_register(ViPipe, 0x3f09, 0x48); + sc3335_write_register(ViPipe, 0x4505, 0x08); + sc3335_write_register(ViPipe, 0x4509, 0x20); + sc3335_write_register(ViPipe, 0x5799, 0x00); + sc3335_write_register(ViPipe, 0x59e0, 0x60); + sc3335_write_register(ViPipe, 0x59e1, 0x08); + sc3335_write_register(ViPipe, 0x59e2, 0x3f); + sc3335_write_register(ViPipe, 0x59e3, 0x18); + sc3335_write_register(ViPipe, 0x59e4, 0x18); + sc3335_write_register(ViPipe, 0x59e5, 0x3f); + sc3335_write_register(ViPipe, 0x59e6, 0x06); + sc3335_write_register(ViPipe, 0x59e7, 0x02); + sc3335_write_register(ViPipe, 0x59e8, 0x38); + sc3335_write_register(ViPipe, 0x59e9, 0x10); + sc3335_write_register(ViPipe, 0x59ea, 0x0c); + sc3335_write_register(ViPipe, 0x59eb, 0x10); + sc3335_write_register(ViPipe, 0x59ec, 0x04); + sc3335_write_register(ViPipe, 0x59ed, 0x02); + sc3335_write_register(ViPipe, 0x36e9, 0x23); + sc3335_write_register(ViPipe, 0x36f9, 0x23); + + sc3335_default_reg_init(ViPipe); + + sc3335_write_register(ViPipe, 0x0100, 0x01); + + delay_ms(100); + + printf("ViPipe:%d,===SC3335 1296P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc3336/Makefile b/middleware/v2/component/isp/sensor/cv180x/sms_sc3336/Makefile new file mode 100644 index 000000000..b6eacab4c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc3336/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc3336.a +TARGET_SO = $(MW_LIB)/libsns_sc3336.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc3336/sc3336_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc3336/sc3336_cmos.c new file mode 100644 index 000000000..73a73b14f --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc3336/sc3336_cmos.c @@ -0,0 +1,946 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc3336_cmos_ex.h" +#include "sc3336_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC3336_ID 3336 +#define SC3336_I2C_ADDR_1 0x30 +#define SC3336_I2C_ADDR_2 0x32 +#define SC3336_I2C_ADDR_IS_VALID(addr) ((addr) == SC3336_I2C_ADDR_1 || (addr) == SC3336_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC3336[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC3336_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC3336[dev]) +#define SC3336_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC3336[dev] = pstCtx) +#define SC3336_SENSOR_RESET_CTX(dev) (g_pastSC3336[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC3336_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC3336_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC3336_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc3336_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC3336 Lines Range*****/ +#define SC3336_FULL_LINES_MAX (0x7FFF) + +/*****SC3336 Register Address*****/ +#define SC3336_EXP_H_ADDR (0x3e00) +#define SC3336_EXP_M_ADDR (0x3e01) +#define SC3336_EXP_L_ADDR (0x3e02) + +#define SC3336_AGAIN_ADDR (0x3e09) + +#define SC3336_DGAIN_H_ADDR (0x3e06) +#define SC3336_DGAIN_L_ADDR (0x3e07) + +#define SC3336_VMAX_H_ADDR (0x320e) +#define SC3336_VMAX_L_ADDR (0x320f) + +#define SC3336_RES_IS_1296P(w, h) ((w) == 2304 && (h) == 1296) + +#define SC3336_EXPACCURACY (1) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC3336_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC3336_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC3336_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC3336_EXPACCURACY; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = pstAeSnsDft->u32MaxIntTime; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC3336_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC3336_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC3336_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC3336_MODE_2304X1296P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC3336_FULL_LINES_MAX) ? SC3336_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 10; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 0 + * max : vts - 10 + * step : 1 + */ + u32MinTime = 0; + u32MaxTime = pstSnsState->au32FL[0] - 10; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_M_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_ADDR].u32Data = ((u32TmpIntTime & 0x000F) << 4); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +typedef struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} gain_tbl_info_s; + +static struct gain_tbl_info_s DgainInfo[4] = { + { + .gainMax = 2016, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 8064, + .idxBase = 64, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 16128, + .idxBase = 96, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, +}; + +static CVI_U32 Dgain_table[128] = { + 1024, 1055, 1088, 1120, 1152, 1183, 1216, 1248, 1280, 1311, 1344, 1376, + 1408, 1439, 1472, 1504, 1536, 1567, 1600, 1632, 1664, 1695, 1728, 1760, + 1792, 1823, 1856, 1888, 1920, 1951, 1984, 2016, 2048, 2112, 2176, 2240, + 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008, + 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, + 3840, 3904, 3968, 4032, 4096, 4224, 4352, 4480, 4608, 4736, 4864, 4992, + 5120, 5248, 5376, 5504, 5632, 5760, 5888, 6016, 6144, 6272, 6400, 6528, + 6656, 6784, 6912, 7040, 7168, 7296, 7424, 7552, 7680, 7808, 7936, 8064, + 8192, 8448, 8704, 8960, 9216, 9472, 9728, 9984, 10240, 10496, 10752, 11008, + 11264, 11520, 11776, 12032, 12288, 12544, 12800, 13056, 13312, 13568, 13824, + 14080, 14336, 14592, 14848, 15104, 15360, 15616, 15872, 16128 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 again = *pu32AgainLin; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (again < 1556) { + *pu32AgainDb = 0x00; + *pu32AgainLin = 1024; + } else if (again < 3122) { + *pu32AgainDb = 0x40; + *pu32AgainLin = 1556; + } else if (again < 6225) { + *pu32AgainDb = 0x48; + *pu32AgainLin = 3122; + } else if (again < 12451) { + *pu32AgainDb = 0x49; + *pu32AgainLin = 6225; + } else if (again < 24903) { + *pu32AgainDb = 0x4b; + *pu32AgainLin = 12451; + } else if (again < 49807) { + *pu32AgainDb = 0x4f; + *pu32AgainLin = 24903; + } else { + *pu32AgainDb = 0x5f; + *pu32AgainLin = 49807; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[127]) { + *pu32DgainLin = Dgain_table[127]; + *pu32DgainDb = 127; + return CVI_SUCCESS; + } + + for (i = 1; i < 128; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L_ADDR].u32Data = (u32Dgain & 0xFF); + + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC3336_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC3336_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC3336_MODE_2304X1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC3336_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC3336_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc3336_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc3336_addr_byte; + pstI2c_data[i].u32DataByteNum = sc3336_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC3336_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_M_ADDR].u32RegAddr = SC3336_EXP_M_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC3336_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = SC3336_AGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC3336_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC3336_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC3336_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC3336_VMAX_L_ADDR; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC3336_RES_IS_1296P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC3336_MODE_2304X1296P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeSc3336_MirrorFip[ViPipe] != eSnsMirrorFlip) { + sc3336_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeSc3336_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC3336_MODE_S *pstMode = CVI_NULL; + + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC3336_MODE_2304X1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC3336_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc3336_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC3336_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC3336_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc3336_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc3336_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc3336_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (SC3336_I2C_ADDR_IS_VALID(s32I2cAddr)) + sc3336_i2c_addr = s32I2cAddr; +} + +static CVI_S32 sc3336_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC3336_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC3336_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC3336_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC3336_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC3336_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC3336_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC3336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC3336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC3336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC3336_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC3336_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC3336_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc3336_standby, + .pfnRestart = sc3336_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = sc3336_write_register, + .pfnReadReg = sc3336_read_register, + .pfnSetBusInfo = sc3336_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc3336_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc3336/sc3336_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc3336/sc3336_cmos_ex.h new file mode 100644 index 000000000..9f0557466 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc3336/sc3336_cmos_ex.h @@ -0,0 +1,80 @@ +#ifndef __SC3336_CMOS_EX_H_ +#define __SC3336_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc3336_linear_regs_e { + LINEAR_EXP_H_ADDR, + LINEAR_EXP_M_ADDR, + LINEAR_EXP_L_ADDR, + LINEAR_AGAIN_ADDR, + LINEAR_DGAIN_H_ADDR, + LINEAR_DGAIN_L_ADDR, + LINEAR_VMAX_H_ADDR, + LINEAR_VMAX_L_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC3336_MODE_E { + SC3336_MODE_2304X1296P30 = 0, + SC3336_MODE_LINEAR_NUM, + SC3336_MODE_2304X1296P30_WDR = SC3336_MODE_LINEAR_NUM, + SC3336_MODE_NUM +} SC3336_MODE_E; + +typedef struct _SC3336_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + char name[64]; +} SC3336_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC3336[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC3336_BusInfo[]; +extern CVI_U16 g_au16SC3336_GainMode[]; +extern CVI_U16 g_au16SC3336_L2SMode[]; +extern CVI_U8 sc3336_i2c_addr; +extern const CVI_U32 sc3336_addr_byte; +extern const CVI_U32 sc3336_data_byte; +extern void sc3336_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void sc3336_init(VI_PIPE ViPipe); +extern void sc3336_exit(VI_PIPE ViPipe); +extern void sc3336_standby(VI_PIPE ViPipe); +extern void sc3336_restart(VI_PIPE ViPipe); +extern int sc3336_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc3336_read_register(VI_PIPE ViPipe, int addr); +extern int sc3336_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC3336_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc3336/sc3336_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc3336/sc3336_cmos_param.h new file mode 100644 index 000000000..f3d2a4623 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc3336/sc3336_cmos_param.h @@ -0,0 +1,121 @@ +#ifndef __SC3336_CMOS_PARAM_H_ +#define __SC3336_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc3336_cmos_ex.h" + +static const SC3336_MODE_S g_astSC3336_mode[SC3336_MODE_NUM] = { + [SC3336_MODE_2304X1296P30] = { + .name = "1296p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2304, + .u32Height = 1296, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2304, + .u32Height = 1296, + }, + .stMaxSize = { + .u32Width = 2304, + .u32Height = 1296, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.24, /* 1350 * 30 / 0x7FFF */ + .u32HtsDef = 4938, + .u32VtsDef = 1350, + .stExp[0] = { + .u16Min = 0, + .u16Max = 1340,//vts - 10 + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 49807, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 16128, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc3336_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {0, 1, 2, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC3336_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc3336/sc3336_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc3336/sc3336_sensor_ctl.c new file mode 100644 index 000000000..8baf914e7 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc3336/sc3336_sensor_ctl.c @@ -0,0 +1,377 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc3336_cmos_ex.h" + +#define SC3336_CHIP_ID_HI_ADDR 0x3107 +#define SC3336_CHIP_ID_LO_ADDR 0x3108 +#define SC3336_CHIP_ID 0xcc41 + +static void sc3336_linear_1296P30_init(VI_PIPE ViPipe); + +CVI_U8 sc3336_i2c_addr = 0x30; /* I2C Address of SC3336 */ +const CVI_U32 sc3336_addr_byte = 2; +const CVI_U32 sc3336_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc3336_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC3336_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc3336_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc3336_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc3336_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc3336_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc3336_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc3336_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc3336_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc3336_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc3336_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc3336_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc3336_addr_byte + sc3336_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc3336_standby(VI_PIPE ViPipe) +{ + sc3336_write_register(ViPipe, 0x0100, 0x00); +} + +void sc3336_restart(VI_PIPE ViPipe) +{ + sc3336_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc3336_write_register(ViPipe, 0x0100, 0x01); +} + +void sc3336_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC3336[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC3336[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc3336_write_register(ViPipe, + g_pastSC3336[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC3336[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc3336_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc3336_write_register(ViPipe, 0x3221, val); +} + +int sc3336_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + delay_ms(4); + if (sc3336_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc3336_read_register(ViPipe, SC3336_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc3336_read_register(ViPipe, SC3336_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC3336_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void sc3336_init(VI_PIPE ViPipe) +{ + sc3336_i2c_init(ViPipe); + + //linear mode only + sc3336_linear_1296P30_init(ViPipe); + + g_pastSC3336[ViPipe]->bInit = CVI_TRUE; +} + +void sc3336_exit(VI_PIPE ViPipe) +{ + sc3336_i2c_exit(ViPipe); +} + +/* 1296P30 and 1296P25 */ +static void sc3336_linear_1296P30_init(VI_PIPE ViPipe) +{ + sc3336_write_register(ViPipe, 0x0103, 0x01); + sc3336_write_register(ViPipe, 0x36e9, 0x80); + sc3336_write_register(ViPipe, 0x37f9, 0x80); + sc3336_write_register(ViPipe, 0x301f, 0x01); + sc3336_write_register(ViPipe, 0x30b8, 0x33); + sc3336_write_register(ViPipe, 0x3253, 0x10); + sc3336_write_register(ViPipe, 0x325f, 0x20); + sc3336_write_register(ViPipe, 0x3301, 0x04); + sc3336_write_register(ViPipe, 0x3306, 0x50); + sc3336_write_register(ViPipe, 0x3309, 0xa8); + sc3336_write_register(ViPipe, 0x330a, 0x00); + sc3336_write_register(ViPipe, 0x330b, 0xd8); + sc3336_write_register(ViPipe, 0x3314, 0x13); + sc3336_write_register(ViPipe, 0x331f, 0x99); + sc3336_write_register(ViPipe, 0x3333, 0x10); + sc3336_write_register(ViPipe, 0x3334, 0x40); + sc3336_write_register(ViPipe, 0x335e, 0x06); + sc3336_write_register(ViPipe, 0x335f, 0x0a); + sc3336_write_register(ViPipe, 0x3364, 0x5e); + sc3336_write_register(ViPipe, 0x337c, 0x02); + sc3336_write_register(ViPipe, 0x337d, 0x0e); + sc3336_write_register(ViPipe, 0x3390, 0x01); + sc3336_write_register(ViPipe, 0x3391, 0x03); + sc3336_write_register(ViPipe, 0x3392, 0x07); + sc3336_write_register(ViPipe, 0x3393, 0x04); + sc3336_write_register(ViPipe, 0x3394, 0x04); + sc3336_write_register(ViPipe, 0x3395, 0x04); + sc3336_write_register(ViPipe, 0x3396, 0x08); + sc3336_write_register(ViPipe, 0x3397, 0x0b); + sc3336_write_register(ViPipe, 0x3398, 0x1f); + sc3336_write_register(ViPipe, 0x3399, 0x04); + sc3336_write_register(ViPipe, 0x339a, 0x0a); + sc3336_write_register(ViPipe, 0x339b, 0x3a); + sc3336_write_register(ViPipe, 0x339c, 0xa0); + sc3336_write_register(ViPipe, 0x33a2, 0x04); + sc3336_write_register(ViPipe, 0x33ac, 0x08); + sc3336_write_register(ViPipe, 0x33ad, 0x1c); + sc3336_write_register(ViPipe, 0x33ae, 0x10); + sc3336_write_register(ViPipe, 0x33af, 0x30); + sc3336_write_register(ViPipe, 0x33b1, 0x80); + sc3336_write_register(ViPipe, 0x33b3, 0x48); + sc3336_write_register(ViPipe, 0x33f9, 0x60); + sc3336_write_register(ViPipe, 0x33fb, 0x74); + sc3336_write_register(ViPipe, 0x33fc, 0x4b); + sc3336_write_register(ViPipe, 0x33fd, 0x5f); + sc3336_write_register(ViPipe, 0x349f, 0x03); + sc3336_write_register(ViPipe, 0x34a6, 0x4b); + sc3336_write_register(ViPipe, 0x34a7, 0x5f); + sc3336_write_register(ViPipe, 0x34a8, 0x20); + sc3336_write_register(ViPipe, 0x34a9, 0x18); + sc3336_write_register(ViPipe, 0x34ab, 0xe8); + sc3336_write_register(ViPipe, 0x34ac, 0x01); + sc3336_write_register(ViPipe, 0x34ad, 0x00); + sc3336_write_register(ViPipe, 0x34f8, 0x5f); + sc3336_write_register(ViPipe, 0x34f9, 0x18); + sc3336_write_register(ViPipe, 0x3630, 0xc0); + sc3336_write_register(ViPipe, 0x3631, 0x84); + sc3336_write_register(ViPipe, 0x3632, 0x64); + sc3336_write_register(ViPipe, 0x3633, 0x32); + sc3336_write_register(ViPipe, 0x363b, 0x03); + sc3336_write_register(ViPipe, 0x363c, 0x08); + sc3336_write_register(ViPipe, 0x3641, 0x38); + sc3336_write_register(ViPipe, 0x3670, 0x4e); + sc3336_write_register(ViPipe, 0x3674, 0xc0); + sc3336_write_register(ViPipe, 0x3675, 0xc0); + sc3336_write_register(ViPipe, 0x3676, 0xc0); + sc3336_write_register(ViPipe, 0x3677, 0x86); + sc3336_write_register(ViPipe, 0x3678, 0x86); + sc3336_write_register(ViPipe, 0x3679, 0x86); + sc3336_write_register(ViPipe, 0x367c, 0x48); + sc3336_write_register(ViPipe, 0x367d, 0x49); + sc3336_write_register(ViPipe, 0x367e, 0x4b); + sc3336_write_register(ViPipe, 0x367f, 0x5f); + sc3336_write_register(ViPipe, 0x3690, 0x32); + sc3336_write_register(ViPipe, 0x3691, 0x32); + sc3336_write_register(ViPipe, 0x3692, 0x42); + sc3336_write_register(ViPipe, 0x369c, 0x4b); + sc3336_write_register(ViPipe, 0x369d, 0x5f); + sc3336_write_register(ViPipe, 0x36b0, 0x87); + sc3336_write_register(ViPipe, 0x36b1, 0x90); + sc3336_write_register(ViPipe, 0x36b2, 0xa1); + sc3336_write_register(ViPipe, 0x36b3, 0xd8); + sc3336_write_register(ViPipe, 0x36b4, 0x49); + sc3336_write_register(ViPipe, 0x36b5, 0x4b); + sc3336_write_register(ViPipe, 0x36b6, 0x4f); + sc3336_write_register(ViPipe, 0x370f, 0x01); + sc3336_write_register(ViPipe, 0x3722, 0x09); + sc3336_write_register(ViPipe, 0x3724, 0x41); + sc3336_write_register(ViPipe, 0x3725, 0xc1); + sc3336_write_register(ViPipe, 0x3771, 0x09); + sc3336_write_register(ViPipe, 0x3772, 0x09); + sc3336_write_register(ViPipe, 0x3773, 0x05); + sc3336_write_register(ViPipe, 0x377a, 0x48); + sc3336_write_register(ViPipe, 0x377b, 0x5f); + sc3336_write_register(ViPipe, 0x3904, 0x04); + sc3336_write_register(ViPipe, 0x3905, 0x8c); + sc3336_write_register(ViPipe, 0x391d, 0x04); + sc3336_write_register(ViPipe, 0x3921, 0x20); + sc3336_write_register(ViPipe, 0x3926, 0x21); + sc3336_write_register(ViPipe, 0x3933, 0x80); + sc3336_write_register(ViPipe, 0x3934, 0x0a); + sc3336_write_register(ViPipe, 0x3935, 0x00); + sc3336_write_register(ViPipe, 0x3936, 0x2a); + sc3336_write_register(ViPipe, 0x3937, 0x6a); + sc3336_write_register(ViPipe, 0x3938, 0x6a); + sc3336_write_register(ViPipe, 0x39dc, 0x02); + sc3336_write_register(ViPipe, 0x3e01, 0x53); + sc3336_write_register(ViPipe, 0x3e02, 0xe0); + sc3336_write_register(ViPipe, 0x3e09, 0x00); + sc3336_write_register(ViPipe, 0x440e, 0x02); + sc3336_write_register(ViPipe, 0x4509, 0x20); + sc3336_write_register(ViPipe, 0x5ae0, 0xfe); + sc3336_write_register(ViPipe, 0x5ae1, 0x40); + sc3336_write_register(ViPipe, 0x5ae2, 0x38); + sc3336_write_register(ViPipe, 0x5ae3, 0x30); + sc3336_write_register(ViPipe, 0x5ae4, 0x28); + sc3336_write_register(ViPipe, 0x5ae5, 0x38); + sc3336_write_register(ViPipe, 0x5ae6, 0x30); + sc3336_write_register(ViPipe, 0x5ae7, 0x28); + sc3336_write_register(ViPipe, 0x5ae8, 0x3f); + sc3336_write_register(ViPipe, 0x5ae9, 0x34); + sc3336_write_register(ViPipe, 0x5aea, 0x2c); + sc3336_write_register(ViPipe, 0x5aeb, 0x3f); + sc3336_write_register(ViPipe, 0x5aec, 0x34); + sc3336_write_register(ViPipe, 0x5aed, 0x2c); + sc3336_write_register(ViPipe, 0x36e9, 0x54); + sc3336_write_register(ViPipe, 0x37f9, 0x27); + + sc3336_default_reg_init(ViPipe); + + sc3336_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC3336 1296P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc401ai/Makefile b/middleware/v2/component/isp/sensor/cv180x/sms_sc401ai/Makefile new file mode 100644 index 000000000..8a86adaba --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc401ai/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc401ai.a +TARGET_SO = $(MW_LIB)/libsns_sc401ai.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc401ai/sc401ai_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc401ai/sc401ai_cmos.c new file mode 100644 index 000000000..b75871c9d --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc401ai/sc401ai_cmos.c @@ -0,0 +1,1035 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc401ai_cmos_ex.h" +#include "sc401ai_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC401AI_ID 401 +#define SC401AI_I2C_ADDR_1 0x30 +#define SC401AI_I2C_ADDR_2 0x32 +#define SC401AI_I2C_ADDR_IS_VALID(addr) ((addr) == SC401AI_I2C_ADDR_1 || (addr) == SC401AI_I2C_ADDR_2) + +#define SENSOR_SC401AI_WIDTH 2560 +#define SENSOR_SC401AI_HEIGHT 1440 + +#define SC401AI_EXPACCURACY (0.5) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC401AI[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC401AI_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC401AI[dev]) +#define SC401AI_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC401AI[dev] = pstCtx) +#define SC401AI_SENSOR_RESET_CTX(dev) (g_pastSC401AI[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC401AI_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC401AI_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC401AI_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC401AI Lines Range*****/ +#define SC401AI_FULL_LINES_MAX (0x7FFF) + +/*****SC401AI Register Address*****/ +#define SC401AI_SHS1_0_ADDR 0x3E00 //bit[3:0] H +#define SC401AI_SHS1_1_ADDR 0x3E01 //bit[7:0] M +#define SC401AI_SHS1_2_ADDR 0x3E02 //bit[7:4] L + +#define SC401AI_AGAIN_ADDR 0x3E08 +#define SC401AI_A_FINEGAIN_ADDR 0x3E09 +#define SC401AI_DGAIN_ADDR 0x3E06 +#define SC401AI_D_FINEGAIN_ADDR 0x3E07 + +#define SC401AI_VMAX_ADDR 0x320E //(0x320e[6:0],0x320f) + +#define SC401AI_RES_IS_1440P(w, h) ((w) == 2560 && (h) == 1440) +#define SC401AI_RES_IS_1296P(w, h) ((w) == 2304 && (h) == 1296) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC401AI_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC401AI_EXPACCURACY; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astSC401AI_mode[pstSnsState->u8ImgMode].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC401AI_mode[pstSnsState->u8ImgMode].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = g_astSC401AI_mode[pstSnsState->u8ImgMode].stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = g_astSC401AI_mode[pstSnsState->u8ImgMode].stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astSC401AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = g_astSC401AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = g_astSC401AI_mode[pstSnsState->u8ImgMode].stExp[0].u32Max; + pstAeSnsDft->u32MinIntTime = g_astSC401AI_mode[pstSnsState->u8ImgMode].stExp[0].u32Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC401AI_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC401AI_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC401AI_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC401AI_MODE_1440P30: + case SC401AI_MODE_1296P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC401AI_FULL_LINES_MAX) ? SC401AI_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0x7F00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = (pstSnsState->u32FLStd << 1) - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + CVI_U32 u32TmpIntTime = u32IntTime[0]; + /* linear exposure reg range: + * min : 3 + * max : 2 * (vts - 8) + * step : 1(1 means step is 0.5 line) + */ + u32TmpIntTime = (u32TmpIntTime > ((pstSnsState->au32FL[0] << 1) - 8)) ? + ((pstSnsState->au32FL[0] << 1) - 8) : u32TmpIntTime; + if (!u32TmpIntTime) + u32TmpIntTime = 3; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); //bit[15:12] + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); //bit[11:4] + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = ((u32TmpIntTime & 0x000F) << 4); //bit[7:4] + + return CVI_SUCCESS; + +} + +struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +}; + +static struct gain_tbl_info_s AgainInfo[5] = { + { + .gainMax = 1487, + .idxBase = 0, + .regGain = 0x03, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 2984, + .idxBase = 30, + .regGain = 0x23, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 5969, + .idxBase = 94, + .regGain = 0x27, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 11939, + .idxBase = 158, + .regGain = 0x2F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 23879, + .idxBase = 222, + .regGain = 0x3F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, +}; + +static CVI_U32 Again_table[286] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, 1248, 1263, 1280, + 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, 1472, 1487, 1504, 1527, 1551, 1574, + 1598, 1622, 1645, 1669, 1692, 1716, 1739, 1762, 1785, 1809, 1832, 1856, 1880, 1903, 1927, 1950, 1974, + 1997, 2021, 2044, 2068, 2092, 2115, 2139, 2162, 2186, 2209, 2233, 2256, 2279, 2302, 2326, 2350, 2373, + 2397, 2420, 2444, 2467, 2491, 2514, 2538, 2562, 2585, 2609, 2632, 2656, 2679, 2703, 2726, 2750, 2772, + 2796, 2820, 2843, 2867, 2890, 2914, 2937, 2961, 2984, 3008, 3055, 3102, 3149, 3196, 3244, 3290, 3337, + 3384, 3431, 3478, 3525, 3572, 3619, 3666, 3714, 3761, 3807, 3854, 3901, 3948, 3995, 4042, 4089, 4136, + 4184, 4231, 4277, 4324, 4371, 4418, 4465, 4512, 4559, 4606, 4654, 4701, 4748, 4794, 4841, 4888, 4935, + 4982, 5029, 5076, 5124, 5171, 5218, 5265, 5311, 5358, 5405, 5452, 5499, 5547, 5594, 5641, 5688, 5735, + 5781, 5828, 5875, 5922, 5969, 6017, 6111, 6205, 6298, 6392, 6487, 6581, 6675, 6769, 6862, 6957, 7051, + 7145, 7239, 7332, 7427, 7521, 7615, 7709, 7802, 7897, 7991, 8085, 8179, 8273, 8367, 8461, 8555, 8649, + 8743, 8837, 8931, 9025, 9119, 9213, 9307, 9401, 9495, 9589, 9683, 9778, 9871, 9965, 10059, 10153, 10248, + 10341, 10435, 10529, 10624, 10718, 10811, 10905, 10999, 11094, 11188, 11282, 11375, 11469, 11564, 11658, + 11752, 11845, 11939, 12034, 12222, 12409, 12598, 12786, 12974, 13162, 13349, 13538, 13726, 13914, 14102, + 14290, 14478, 14666, 14854, 15042, 15230, 15418, 15606, 15795, 15982, 16171, 16358, 16546, 16735, 16922, + 17111, 17299, 17486, 17675, 17862, 18051, 18239, 18426, 18615, 18803, 18991, 19179, 19366, 19555, 19743, + 19931, 20119, 20307, 20495, 20683, 20871, 21059, 21248, 21435, 21623, 21812, 21999, 22188, 22375, 22563, + 22752, 22939, 23128, 23316, 23503, 23692, 23879 +}; + +static struct gain_tbl_info_s DgainInfo[5] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 8128, + .idxBase = 128, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 16256, + .idxBase = 192, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 32512, + .idxBase = 256, + .regGain = 0x0f, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, +}; + +static CVI_U32 Dgain_table[320] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, 1248, + 1263, 1280, 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, 1472, 1487, + 1504, 1519, 1536, 1552, 1567, 1584, 1600, 1615, 1632, 1647, 1664, 1680, 1695, 1712, 1728, + 1743, 1760, 1775, 1792, 1808, 1823, 1840, 1856, 1871, 1888, 1903, 1920, 1936, 1951, 1968, + 1984, 1999, 2016, 2031, 2048, 2079, 2112, 2144, 2176, 2207, 2240, 2272, 2304, 2335, 2368, + 2400, 2432, 2463, 2496, 2528, 2560, 2591, 2624, 2656, 2688, 2719, 2752, 2784, 2816, 2847, + 2880, 2912, 2944, 2975, 3008, 3040, 3072, 3103, 3136, 3168, 3200, 3231, 3264, 3296, 3328, + 3359, 3392, 3424, 3456, 3487, 3520, 3552, 3584, 3615, 3648, 3680, 3712, 3743, 3776, 3808, + 3840, 3871, 3904, 3936, 3968, 3999, 4032, 4064, 4096, 4160, 4224, 4288, 4352, 4416, 4480, + 4544, 4608, 4672, 4736, 4800, 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, + 5504, 5568, 5632, 5696, 5760, 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, + 6464, 6528, 6592, 6656, 6720, 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, + 7424, 7488, 7552, 7616, 7680, 7744, 7808, 7872, 7936, 8000, 8064, 8128, 8192, 8320, 8448, + 8576, 8704, 8832, 8960, 9088, 9216, 9344, 9472, 9600, 9728, 9856, 9984, 10112, 10240, 10368, + 10496, 10624, 10752, 10880, 11008, 11136, 11264, 11392, 11520, 11648, 11776, 11904, 12032, + 12160, 12288, 12416, 12544, 12672, 12800, 12928, 13056, 13184, 13312, 13440, 13568, 13696, + 13824, 13952, 14080, 14208, 14336, 14464, 14592, 14720, 14848, 14976, 15104, 15232, 15360, + 15488, 15616, 15744, 15872, 16000, 16128, 16256, 16384, 16640, 16896, 17152, 17408, 17664, + 17920, 18176, 18432, 18688, 18944, 19200, 19456, 19712, 19968, 20224, 20480, 20736, 20992, + 21248, 21504, 21760, 22016, 22272, 22528, 22784, 23040, 23296, 23552, 23808, 24064, 24320, + 24576, 24832, 25088, 25344, 25600, 25856, 26112, 26368, 26624, 26880, 27136, 27392, 27648, + 27904, 28160, 28416, 28672, 28928, 29184, 29440, 29696, 29952, 30208, 30464, 30720, 30976, + 31232, 31488, 31744, 32000, 32256, 32512 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[285]) { + *pu32AgainLin = Again_table[285]; + *pu32AgainDb = 285; + return CVI_SUCCESS; + } + + for (i = 1; i < 286; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[319]) { + *pu32DgainLin = Dgain_table[319]; + *pu32DgainDb = 319; + return CVI_SUCCESS; + } + + for (i = 1; i < 320; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_A_FINEGAIN_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_D_FINEGAIN_ADDR].u32Data = (u32Dgain & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + (void) u16ManRatioEnable; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC401AI_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC401AI_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == SC401AI_MODE_1440P30) + pstSnsState->u8ImgMode = SC401AI_MODE_1440P30; + else if (pstSnsState->u8ImgMode == SC401AI_MODE_1296P30) + pstSnsState->u8ImgMode = SC401AI_MODE_1296P30; + + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC401AI_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC401AI_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc401ai_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc401ai_addr_byte; + pstI2c_data[i].u32DataByteNum = sc401ai_data_byte; + } + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC401AI_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC401AI_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC401AI_SHS1_2_ADDR; + + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = SC401AI_AGAIN_ADDR; + pstI2c_data[LINEAR_A_FINEGAIN_ADDR].u32RegAddr = SC401AI_A_FINEGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_ADDR].u32RegAddr = SC401AI_DGAIN_ADDR; + pstI2c_data[LINEAR_D_FINEGAIN_ADDR].u32RegAddr = SC401AI_D_FINEGAIN_ADDR; + + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC401AI_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC401AI_VMAX_ADDR + 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC401AI_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = SC401AI_MODE_1440P30; + else if (SC401AI_RES_IS_1296P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = SC401AI_MODE_1296P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC401AI_MODE_S *pstMode = CVI_NULL; + + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC401AI_MODE_1440P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC401AI_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc401ai_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC401AI_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC401AI_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc401ai_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc401ai_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc401ai_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (SC401AI_I2C_ADDR_IS_VALID(s32I2cAddr)) + sc401ai_i2c_addr = s32I2cAddr; +} + +static CVI_S32 sc401ai_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC401AI_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC401AI_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC401AI_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC401AI_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC401AI_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC401AI_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC401AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC401AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC401AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC401AI_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC401AI_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC401AI_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc401ai_standby, + .pfnRestart = sc401ai_restart, + .pfnMirrorFlip = sc401ai_mirror_flip, + .pfnWriteReg = sc401ai_write_register, + .pfnReadReg = sc401ai_read_register, + .pfnSetBusInfo = sc401ai_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc401ai_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc401ai/sc401ai_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc401ai/sc401ai_cmos_ex.h new file mode 100644 index 000000000..c7c3d3339 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc401ai/sc401ai_cmos_ex.h @@ -0,0 +1,80 @@ +#ifndef __SC401AI_CMOS_EX_H_ +#define __SC401AI_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc401ai_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_2_ADDR, + LINEAR_AGAIN_ADDR, + LINEAR_A_FINEGAIN_ADDR, + LINEAR_DGAIN_ADDR, + LINEAR_D_FINEGAIN_ADDR, + LINEAR_VMAX_0_ADDR, + LINEAR_VMAX_1_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC401AI_MODE_E { + SC401AI_MODE_1440P30 = 0, + SC401AI_MODE_1296P30, + SC401AI_MODE_NUM +} SC401AI_MODE_E; + +typedef struct _SC401AI_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_LARGE_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} SC401AI_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC401AI[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC401AI_BusInfo[]; +extern CVI_U16 g_au16SC401AI_GainMode[]; +extern CVI_U16 g_au16SC401AI_L2SMode[]; +extern CVI_U8 sc401ai_i2c_addr; +extern const CVI_U32 sc401ai_addr_byte; +extern const CVI_U32 sc401ai_data_byte; +extern void sc401ai_init(VI_PIPE ViPipe); +extern void sc401ai_exit(VI_PIPE ViPipe); +extern void sc401ai_standby(VI_PIPE ViPipe); +extern void sc401ai_restart(VI_PIPE ViPipe); +extern int sc401ai_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc401ai_read_register(VI_PIPE ViPipe, int addr); +extern void sc401ai_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc401ai_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC401AI_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc401ai/sc401ai_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc401ai/sc401ai_cmos_param.h new file mode 100644 index 000000000..a5603f355 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc401ai/sc401ai_cmos_param.h @@ -0,0 +1,262 @@ +#ifndef __SC401AI_CMOS_PARAM_H_ +#define __SC401AI_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc401ai_cmos_ex.h" + +static const SC401AI_MODE_S g_astSC401AI_mode[SC401AI_MODE_NUM] = { + [SC401AI_MODE_1440P30] = { + .name = "1440p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.37, /* 1500 * 30 / 0x7FFF*/ + .u32HtsDef = 2800, + .u32VtsDef = 1500, + .stExp[0] = { + .u32Min = 3, + .u32Max = 2992, //2*vts - 8 + .u32Def = 1500, //30fps + .u32Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 23879, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 32512, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [SC401AI_MODE_1296P30] = { + .name = "1296p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2304, + .u32Height = 1296, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2304, + .u32Height = 1296, + }, + .stMaxSize = { + .u32Width = 2304, + .u32Height = 1296, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.65, /* 1800 * 30 / 0x7FFF*/ + .u32HtsDef = 2333, + .u32VtsDef = 1800, + .stExp[0] = { + .u32Min = 3, + .u32Max = 3592, //2*vts - 8 + .u32Def = 1800, //30fps + .u32Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 23879, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 32512, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.02792946062982082367, 3.36534714698791503906}, //B: slope, intercept + {0.02071751467883586884, 5.34583568572998046875}, //Gb: slope, intercept + {0.02110148966312408447, 5.02954530715942382813}, //Gr: slope, intercept + {0.02168512716889381409, 4.89776754379272460938}, //R: slope, intercept + }, + { //iso 200 + {0.03194080293178558350, 5.61192893981933593750}, //B: slope, intercept + {0.02428408525884151459, 7.94834280014038085938}, //Gb: slope, intercept + {0.02499442733824253082, 7.72430133819580078125}, //Gr: slope, intercept + {0.02584112435579299927, 7.20574426651000976563}, //R: slope, intercept + }, + { //iso 400 + {0.04612467437982559204, 6.88752269744873046875}, //B: slope, intercept + {0.03022909909486770630, 11.05101776123046875000}, //Gb: slope, intercept + {0.03175539523363113403, 10.60332489013671875000}, //Gr: slope, intercept + {0.03522306308150291443, 9.36425399780273437500}, //R: slope, intercept + }, + { //iso 800 + {0.06092500314116477966, 9.79670524597167968750}, //B: slope, intercept + {0.03984217345714569092, 15.30182266235351562500}, //Gb: slope, intercept + {0.04019560664892196655, 14.93132972717285156250}, //Gr: slope, intercept + {0.04470816254615783691, 13.26843166351318359375}, //R: slope, intercept + }, + { //iso 1600 + {0.08295634388923645020, 14.20334625244140625000}, //B: slope, intercept + {0.05075264349579811096, 20.99221038818359375000}, //Gb: slope, intercept + {0.05426201224327087402, 20.08068656921386718750}, //Gr: slope, intercept + {0.05945669487118721008, 19.02898788452148437500}, //R: slope, intercept + }, + { //iso 3200 + {0.09782519936561584473, 21.84967994689941406250}, //B: slope, intercept + {0.06690908223390579224, 26.53993988037109375000}, //Gb: slope, intercept + {0.06954573839902877808, 25.74129104614257812500}, //Gr: slope, intercept + {0.09061723947525024414, 22.98998260498046875000}, //R: slope, intercept + }, + { //iso 6400 + {0.14311420917510986328, 28.96467971801757812500}, //B: slope, intercept + {0.08148498833179473877, 37.93062591552734375000}, //Gb: slope, intercept + {0.08273542672395706177, 38.37096405029296875000}, //Gr: slope, intercept + {0.12093253433704376221, 33.31475067138671875000}, //R: slope, intercept + }, + { //iso 12800 + {0.17958122491836547852, 43.49506759643554687500}, //B: slope, intercept + {0.09839969873428344727, 55.43268966674804687500}, //Gb: slope, intercept + {0.10201884806156158447, 52.97607040405273437500}, //Gr: slope, intercept + {0.15302789211273193359, 47.54779434204101562500}, //R: slope, intercept + }, + { //iso 25600 + {0.25833165645599365234, 56.96470642089843750000}, //B: slope, intercept + {0.13260601460933685303, 74.69016265869140625000}, //Gb: slope, intercept + {0.14035490155220031738, 75.44366455078125000000}, //Gr: slope, intercept + {0.23465165495872497559, 60.52228164672851562500}, //R: slope, intercept + }, + { //iso 51200 + {0.37595292925834655762, 78.54853057861328125000}, //B: slope, intercept + {0.21475413441658020020, 102.12300872802734375000}, //Gb: slope, intercept + {0.20840260386466979980, 103.65763854980468750000}, //Gr: slope, intercept + {0.34428051114082336426, 87.83551025390625000000}, //R: slope, intercept + }, + { //iso 102400 + {0.51122575998306274414, 113.49224090576171875000}, //B: slope, intercept + {0.29245173931121826172, 154.26939392089843750000}, //Gb: slope, intercept + {0.31501635909080505371, 148.29017639160156250000}, //Gr: slope, intercept + {0.47034618258476257324, 124.06208038330078125000}, //R: slope, intercept + }, + { //iso 204800 + {0.67213481664657592773, 134.71751403808593750000}, //B: slope, intercept + {0.40368056297302246094, 189.80801391601562500000}, //Gb: slope, intercept + {0.43581819534301757813, 186.44682312011718750000}, //Gr: slope, intercept + {0.60127359628677368164, 160.66384887695312500000}, //R: slope, intercept + }, + { //iso 409600 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 819200 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc401ai_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {0, 1, 2, -1, -1}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC401AI_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc401ai/sc401ai_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc401ai/sc401ai_sensor_ctl.c new file mode 100644 index 000000000..d13239be9 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc401ai/sc401ai_sensor_ctl.c @@ -0,0 +1,493 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc401ai_cmos_ex.h" + +static void sc401ai_linear_1440p30_init(VI_PIPE ViPipe); +static void sc401ai_linear_1296p30_init(VI_PIPE ViPipe); + +CVI_U8 sc401ai_i2c_addr = 0x30; /* I2C Address of SC401AI */ +const CVI_U32 sc401ai_addr_byte = 2; +const CVI_U32 sc401ai_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc401ai_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC401AI_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc401ai_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc401ai_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc401ai_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc401ai_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc401ai_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc401ai_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc401ai_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc401ai_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc401ai_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc401ai_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc401ai_addr_byte + sc401ai_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc401ai_standby(VI_PIPE ViPipe) +{ + sc401ai_write_register(ViPipe, 0x0100, 0x00); +} + +void sc401ai_restart(VI_PIPE ViPipe) +{ + sc401ai_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc401ai_write_register(ViPipe, 0x0100, 0x01); +} + +void sc401ai_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC401AI[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc401ai_write_register(ViPipe, + g_pastSC401AI[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC401AI[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC401AI_CHIP_ID_HI_ADDR 0x3107 +#define SC401AI_CHIP_ID_LO_ADDR 0x3108 +#define SC401AI_CHIP_ID 0xcd2e + +void sc401ai_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc401ai_write_register(ViPipe, 0x3221, val); +} + +int sc401ai_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + delay_ms(4); + if (sc401ai_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc401ai_read_register(ViPipe, SC401AI_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc401ai_read_register(ViPipe, SC401AI_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC401AI_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc401ai_init(VI_PIPE ViPipe) +{ + CVI_U8 u8ImgMode = g_pastSC401AI[ViPipe]->u8ImgMode; + + sc401ai_i2c_init(ViPipe); + + if (u8ImgMode == SC401AI_MODE_1440P30) + sc401ai_linear_1440p30_init(ViPipe); + else if (u8ImgMode == SC401AI_MODE_1296P30) + sc401ai_linear_1296p30_init(ViPipe); + + g_pastSC401AI[ViPipe]->bInit = CVI_TRUE; +} + +void sc401ai_exit(VI_PIPE ViPipe) +{ + sc401ai_i2c_exit(ViPipe); +} + +/* 1440P30 and 1440P25 */ +static void sc401ai_linear_1440p30_init(VI_PIPE ViPipe) +{ + sc401ai_write_register(ViPipe, 0x0103, 0x01); + sc401ai_write_register(ViPipe, 0x0100, 0x00); + sc401ai_write_register(ViPipe, 0x36e9, 0x80); + sc401ai_write_register(ViPipe, 0x36f9, 0x80); + sc401ai_write_register(ViPipe, 0x3018, 0x3a); + sc401ai_write_register(ViPipe, 0x3019, 0x0c); + sc401ai_write_register(ViPipe, 0x301c, 0x78); + sc401ai_write_register(ViPipe, 0x301f, 0x05); + sc401ai_write_register(ViPipe, 0x3208, 0x0a); + sc401ai_write_register(ViPipe, 0x3209, 0x00); + sc401ai_write_register(ViPipe, 0x320a, 0x05); + sc401ai_write_register(ViPipe, 0x320b, 0xa0); + sc401ai_write_register(ViPipe, 0x320e, 0x05);//vts + sc401ai_write_register(ViPipe, 0x320f, 0xdc); + sc401ai_write_register(ViPipe, 0x3214, 0x11); + sc401ai_write_register(ViPipe, 0x3215, 0x11); + sc401ai_write_register(ViPipe, 0x3223, 0x80); + sc401ai_write_register(ViPipe, 0x3250, 0x00); + sc401ai_write_register(ViPipe, 0x3253, 0x08); + sc401ai_write_register(ViPipe, 0x3274, 0x01); + sc401ai_write_register(ViPipe, 0x3301, 0x20); + sc401ai_write_register(ViPipe, 0x3302, 0x18); + sc401ai_write_register(ViPipe, 0x3303, 0x10); + sc401ai_write_register(ViPipe, 0x3304, 0x50); + sc401ai_write_register(ViPipe, 0x3306, 0x38); + sc401ai_write_register(ViPipe, 0x3308, 0x18); + sc401ai_write_register(ViPipe, 0x3309, 0x60); + sc401ai_write_register(ViPipe, 0x330b, 0xc0); + sc401ai_write_register(ViPipe, 0x330d, 0x10); + sc401ai_write_register(ViPipe, 0x330e, 0x18); + sc401ai_write_register(ViPipe, 0x330f, 0x04); + sc401ai_write_register(ViPipe, 0x3310, 0x02); + sc401ai_write_register(ViPipe, 0x331c, 0x04); + sc401ai_write_register(ViPipe, 0x331e, 0x41); + sc401ai_write_register(ViPipe, 0x331f, 0x51); + sc401ai_write_register(ViPipe, 0x3320, 0x09); + sc401ai_write_register(ViPipe, 0x3333, 0x10); + sc401ai_write_register(ViPipe, 0x334c, 0x08); + sc401ai_write_register(ViPipe, 0x3356, 0x09); + sc401ai_write_register(ViPipe, 0x3364, 0x17); + sc401ai_write_register(ViPipe, 0x338e, 0xfd); + sc401ai_write_register(ViPipe, 0x3390, 0x08); + sc401ai_write_register(ViPipe, 0x3391, 0x18); + sc401ai_write_register(ViPipe, 0x3392, 0x38); + sc401ai_write_register(ViPipe, 0x3393, 0x20); + sc401ai_write_register(ViPipe, 0x3394, 0x20); + sc401ai_write_register(ViPipe, 0x3395, 0x20); + sc401ai_write_register(ViPipe, 0x3396, 0x08); + sc401ai_write_register(ViPipe, 0x3397, 0x18); + sc401ai_write_register(ViPipe, 0x3398, 0x38); + sc401ai_write_register(ViPipe, 0x3399, 0x20); + sc401ai_write_register(ViPipe, 0x339a, 0x20); + sc401ai_write_register(ViPipe, 0x339b, 0x20); + sc401ai_write_register(ViPipe, 0x339c, 0x20); + sc401ai_write_register(ViPipe, 0x33ac, 0x10); + sc401ai_write_register(ViPipe, 0x33ae, 0x18); + sc401ai_write_register(ViPipe, 0x33af, 0x19); + sc401ai_write_register(ViPipe, 0x360f, 0x01); + sc401ai_write_register(ViPipe, 0x3620, 0x08); + sc401ai_write_register(ViPipe, 0x3637, 0x25); + sc401ai_write_register(ViPipe, 0x363a, 0x12); + sc401ai_write_register(ViPipe, 0x3670, 0x0a); + sc401ai_write_register(ViPipe, 0x3671, 0x07); + sc401ai_write_register(ViPipe, 0x3672, 0x57); + sc401ai_write_register(ViPipe, 0x3673, 0x5e); + sc401ai_write_register(ViPipe, 0x3674, 0x84); + sc401ai_write_register(ViPipe, 0x3675, 0x88); + sc401ai_write_register(ViPipe, 0x3676, 0x8a); + sc401ai_write_register(ViPipe, 0x367a, 0x58); + sc401ai_write_register(ViPipe, 0x367b, 0x78); + sc401ai_write_register(ViPipe, 0x367c, 0x58); + sc401ai_write_register(ViPipe, 0x367d, 0x78); + sc401ai_write_register(ViPipe, 0x3690, 0x33); + sc401ai_write_register(ViPipe, 0x3691, 0x43); + sc401ai_write_register(ViPipe, 0x3692, 0x34); + sc401ai_write_register(ViPipe, 0x369c, 0x40); + sc401ai_write_register(ViPipe, 0x369d, 0x78); + sc401ai_write_register(ViPipe, 0x36ea, 0x39); + sc401ai_write_register(ViPipe, 0x36eb, 0x0d); + sc401ai_write_register(ViPipe, 0x36ec, 0x1c); + sc401ai_write_register(ViPipe, 0x36ed, 0x24); + sc401ai_write_register(ViPipe, 0x36fa, 0x39); + sc401ai_write_register(ViPipe, 0x36fb, 0x33); + sc401ai_write_register(ViPipe, 0x36fc, 0x10); + sc401ai_write_register(ViPipe, 0x36fd, 0x14); + sc401ai_write_register(ViPipe, 0x3908, 0x41); + sc401ai_write_register(ViPipe, 0x396c, 0x0e); + sc401ai_write_register(ViPipe, 0x3e00, 0x00); + sc401ai_write_register(ViPipe, 0x3e01, 0xb6); + sc401ai_write_register(ViPipe, 0x3e02, 0x00); + sc401ai_write_register(ViPipe, 0x3e03, 0x0b); + sc401ai_write_register(ViPipe, 0x3e08, 0x03); + sc401ai_write_register(ViPipe, 0x3e09, 0x40); + sc401ai_write_register(ViPipe, 0x3e1b, 0x2a); + sc401ai_write_register(ViPipe, 0x4509, 0x30); + sc401ai_write_register(ViPipe, 0x4819, 0x08); + sc401ai_write_register(ViPipe, 0x481b, 0x05); + sc401ai_write_register(ViPipe, 0x481d, 0x11); + sc401ai_write_register(ViPipe, 0x481f, 0x04); + sc401ai_write_register(ViPipe, 0x4821, 0x09); + sc401ai_write_register(ViPipe, 0x4823, 0x04); + sc401ai_write_register(ViPipe, 0x4825, 0x04); + sc401ai_write_register(ViPipe, 0x4827, 0x04); + sc401ai_write_register(ViPipe, 0x4829, 0x07); + sc401ai_write_register(ViPipe, 0x57a8, 0xd0); + sc401ai_write_register(ViPipe, 0x36e9, 0x14); + sc401ai_write_register(ViPipe, 0x36f9, 0x14); + sc401ai_write_register(ViPipe, 0x5001, 0x44); //Support sid pull up + + sc401ai_default_reg_init(ViPipe); + + sc401ai_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC401AI 1440P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +/* 1440P30 and 1440P25 */ +static void sc401ai_linear_1296p30_init(VI_PIPE ViPipe) +{ + sc401ai_write_register(ViPipe, 0x0103, 0x01); + sc401ai_write_register(ViPipe, 0x0100, 0x00); + sc401ai_write_register(ViPipe, 0x36e9, 0x80); + sc401ai_write_register(ViPipe, 0x36f9, 0x80); + sc401ai_write_register(ViPipe, 0x3018, 0x3a); + sc401ai_write_register(ViPipe, 0x3019, 0x0c); + sc401ai_write_register(ViPipe, 0x301c, 0x78); + sc401ai_write_register(ViPipe, 0x301f, 0x05); + sc401ai_write_register(ViPipe, 0x3200, 0x00); + sc401ai_write_register(ViPipe, 0x3201, 0x80); + sc401ai_write_register(ViPipe, 0x3202, 0x00); + sc401ai_write_register(ViPipe, 0x3203, 0x48); + sc401ai_write_register(ViPipe, 0x3204, 0x09); + sc401ai_write_register(ViPipe, 0x3205, 0x87); + sc401ai_write_register(ViPipe, 0x3206, 0x05); + sc401ai_write_register(ViPipe, 0x3207, 0x5f); + sc401ai_write_register(ViPipe, 0x3208, 0x09); + sc401ai_write_register(ViPipe, 0x3209, 0x00); + sc401ai_write_register(ViPipe, 0x320a, 0x05); + sc401ai_write_register(ViPipe, 0x320b, 0x10); + sc401ai_write_register(ViPipe, 0x320e, 0x07); + sc401ai_write_register(ViPipe, 0x320f, 0x08); + sc401ai_write_register(ViPipe, 0x3210, 0x00); + sc401ai_write_register(ViPipe, 0x3211, 0x04); + sc401ai_write_register(ViPipe, 0x3212, 0x00); + sc401ai_write_register(ViPipe, 0x3213, 0x04); + sc401ai_write_register(ViPipe, 0x3214, 0x11); + sc401ai_write_register(ViPipe, 0x3215, 0x11); + sc401ai_write_register(ViPipe, 0x3223, 0x80); + sc401ai_write_register(ViPipe, 0x3250, 0x00); + sc401ai_write_register(ViPipe, 0x3253, 0x08); + sc401ai_write_register(ViPipe, 0x3274, 0x01); + sc401ai_write_register(ViPipe, 0x3301, 0x20); + sc401ai_write_register(ViPipe, 0x3302, 0x18); + sc401ai_write_register(ViPipe, 0x3303, 0x10); + sc401ai_write_register(ViPipe, 0x3304, 0x50); + sc401ai_write_register(ViPipe, 0x3306, 0x38); + sc401ai_write_register(ViPipe, 0x3308, 0x18); + sc401ai_write_register(ViPipe, 0x3309, 0x60); + sc401ai_write_register(ViPipe, 0x330b, 0xc0); + sc401ai_write_register(ViPipe, 0x330d, 0x10); + sc401ai_write_register(ViPipe, 0x330e, 0x18); + sc401ai_write_register(ViPipe, 0x330f, 0x04); + sc401ai_write_register(ViPipe, 0x3310, 0x02); + sc401ai_write_register(ViPipe, 0x331c, 0x04); + sc401ai_write_register(ViPipe, 0x331e, 0x41); + sc401ai_write_register(ViPipe, 0x331f, 0x51); + sc401ai_write_register(ViPipe, 0x3320, 0x09); + sc401ai_write_register(ViPipe, 0x3333, 0x10); + sc401ai_write_register(ViPipe, 0x334c, 0x08); + sc401ai_write_register(ViPipe, 0x3356, 0x09); + sc401ai_write_register(ViPipe, 0x3364, 0x17); + sc401ai_write_register(ViPipe, 0x338e, 0xfd); + sc401ai_write_register(ViPipe, 0x3390, 0x08); + sc401ai_write_register(ViPipe, 0x3391, 0x18); + sc401ai_write_register(ViPipe, 0x3392, 0x38); + sc401ai_write_register(ViPipe, 0x3393, 0x20); + sc401ai_write_register(ViPipe, 0x3394, 0x20); + sc401ai_write_register(ViPipe, 0x3395, 0x20); + sc401ai_write_register(ViPipe, 0x3396, 0x08); + sc401ai_write_register(ViPipe, 0x3397, 0x18); + sc401ai_write_register(ViPipe, 0x3398, 0x38); + sc401ai_write_register(ViPipe, 0x3399, 0x20); + sc401ai_write_register(ViPipe, 0x339a, 0x20); + sc401ai_write_register(ViPipe, 0x339b, 0x20); + sc401ai_write_register(ViPipe, 0x339c, 0x20); + sc401ai_write_register(ViPipe, 0x33ac, 0x10); + sc401ai_write_register(ViPipe, 0x33ae, 0x18); + sc401ai_write_register(ViPipe, 0x33af, 0x19); + sc401ai_write_register(ViPipe, 0x360f, 0x01); + sc401ai_write_register(ViPipe, 0x3620, 0x08); + sc401ai_write_register(ViPipe, 0x3637, 0x25); + sc401ai_write_register(ViPipe, 0x363a, 0x12); + sc401ai_write_register(ViPipe, 0x3670, 0x0a); + sc401ai_write_register(ViPipe, 0x3671, 0x07); + sc401ai_write_register(ViPipe, 0x3672, 0x57); + sc401ai_write_register(ViPipe, 0x3673, 0x5e); + sc401ai_write_register(ViPipe, 0x3674, 0x84); + sc401ai_write_register(ViPipe, 0x3675, 0x88); + sc401ai_write_register(ViPipe, 0x3676, 0x8a); + sc401ai_write_register(ViPipe, 0x367a, 0x58); + sc401ai_write_register(ViPipe, 0x367b, 0x78); + sc401ai_write_register(ViPipe, 0x367c, 0x58); + sc401ai_write_register(ViPipe, 0x367d, 0x78); + sc401ai_write_register(ViPipe, 0x3690, 0x33); + sc401ai_write_register(ViPipe, 0x3691, 0x43); + sc401ai_write_register(ViPipe, 0x3692, 0x34); + sc401ai_write_register(ViPipe, 0x369c, 0x40); + sc401ai_write_register(ViPipe, 0x369d, 0x78); + sc401ai_write_register(ViPipe, 0x36ea, 0x39); + sc401ai_write_register(ViPipe, 0x36eb, 0x0d); + sc401ai_write_register(ViPipe, 0x36ec, 0x1c); + sc401ai_write_register(ViPipe, 0x36ed, 0x24); + sc401ai_write_register(ViPipe, 0x36fa, 0x39); + sc401ai_write_register(ViPipe, 0x36fb, 0x33); + sc401ai_write_register(ViPipe, 0x36fc, 0x10); + sc401ai_write_register(ViPipe, 0x36fd, 0x14); + sc401ai_write_register(ViPipe, 0x3908, 0x41); + sc401ai_write_register(ViPipe, 0x396c, 0x0e); + sc401ai_write_register(ViPipe, 0x3e00, 0x00); + sc401ai_write_register(ViPipe, 0x3e01, 0xb6); + sc401ai_write_register(ViPipe, 0x3e02, 0x00); + sc401ai_write_register(ViPipe, 0x3e03, 0x0b); + sc401ai_write_register(ViPipe, 0x3e08, 0x03); + sc401ai_write_register(ViPipe, 0x3e09, 0x40); + sc401ai_write_register(ViPipe, 0x3e1b, 0x2a); + sc401ai_write_register(ViPipe, 0x4509, 0x30); + sc401ai_write_register(ViPipe, 0x4819, 0x08); + sc401ai_write_register(ViPipe, 0x481b, 0x05); + sc401ai_write_register(ViPipe, 0x481d, 0x11); + sc401ai_write_register(ViPipe, 0x481f, 0x04); + sc401ai_write_register(ViPipe, 0x4821, 0x09); + sc401ai_write_register(ViPipe, 0x4823, 0x04); + sc401ai_write_register(ViPipe, 0x4825, 0x04); + sc401ai_write_register(ViPipe, 0x4827, 0x04); + sc401ai_write_register(ViPipe, 0x4829, 0x07); + sc401ai_write_register(ViPipe, 0x57a8, 0xd0); + sc401ai_write_register(ViPipe, 0x36e9, 0x14); + sc401ai_write_register(ViPipe, 0x36f9, 0x14); + sc401ai_write_register(ViPipe, 0x5001, 0x44); //Support sid pull up + + sc401ai_default_reg_init(ViPipe); + + sc401ai_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC401AI 1296P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc4336/Makefile b/middleware/v2/component/isp/sensor/cv180x/sms_sc4336/Makefile new file mode 100644 index 000000000..3190f8c09 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc4336/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc4336.a +TARGET_SO = $(MW_LIB)/libsns_sc4336.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc4336/sc4336_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc4336/sc4336_cmos.c new file mode 100644 index 000000000..59545137e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc4336/sc4336_cmos.c @@ -0,0 +1,916 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc4336_cmos_ex.h" +#include "sc4336_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC4336_ID 4336 +#define SENSOR_SC4336_WIDTH 2560 +#define SENSOR_SC4336_HEIGHT 1440 +#define SC4336_I2C_ADDR_1 0x30 +#define SC4336_I2C_ADDR_2 0x32 +#define SC4336_I2C_ADDR_IS_VALID(addr) ((addr) == SC4336_I2C_ADDR_1 || (addr) == SC4336_I2C_ADDR_2) + +#define SC4336_EXPACCURACY (1) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC4336[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC4336_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC4336[dev]) +#define SC4336_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC4336[dev] = pstCtx) +#define SC4336_SENSOR_RESET_CTX(dev) (g_pastSC4336[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC4336_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC4336_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC4336_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc4336_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC4336 Lines Range*****/ +#define SC4336_FULL_LINES_MAX (0x7FFF) + +/*****SC4336 Register Address*****/ +#define SC4336_EXP_ADDR 0x3E00 +#define SC4336_AGAIN_ADDR 0x3E09 +#define SC4336_DGAIN_ADDR 0x3E06 +#define SC4336_VMAX_ADDR 0x320E + +#define SC4336_RES_IS_1440P(w, h) ((w) == 2560 && (h) == 1440) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC4336_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC4336_EXPACCURACY; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stAgainAccu.f32Accuracy = 6; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astSC4336_mode[pstSnsState->u8ImgMode].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC4336_mode[pstSnsState->u8ImgMode].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = g_astSC4336_mode[pstSnsState->u8ImgMode].stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = g_astSC4336_mode[pstSnsState->u8ImgMode].stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astSC4336_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = g_astSC4336_mode[pstSnsState->u8ImgMode].stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = g_astSC4336_mode[pstSnsState->u8ImgMode].stExp[0].u32Max; + pstAeSnsDft->u32MinIntTime = g_astSC4336_mode[pstSnsState->u8ImgMode].stExp[0].u32Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC4336_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC4336_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC4336_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC4336_MODE_1440P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC4336_FULL_LINES_MAX) ? SC4336_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0x7F00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = (pstSnsState->u32FLStd << 1) - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* linear exposure reg range: + * min : 0 + * max : vts - 8 + * step : 1 + */ + u32MinTime = 0; + u32MaxTime = pstSnsState->au32FL[0] - 8; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); //bit[15:12] + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); //bit[11:4] + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = ((u32TmpIntTime & 0x000F) << 4); //bit[3:0] + + return CVI_SUCCESS; +} + +struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +}; + +static struct gain_tbl_info_s DgainInfo[] = { + { + .gainMax = 2016, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 8064, + .idxBase = 64, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 16128, + .idxBase = 96, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, +}; + +static CVI_U32 Dgain_table[] = { + 1024, 1055, 1088, 1120, 1152, 1183, 1216, 1248, 1280, 1311, 1344, 1376, 1408, 1439, 1472, + 1504, 1536, 1567, 1600, 1632, 1664, 1695, 1728, 1760, 1792, 1823, 1856, 1888, 1920, 1951, + 1984, 2016, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, + 2816, 2880, 2944, 3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, + 3840, 3904, 3968, 4032, 4096, 4224, 4352, 4480, 4608, 4736, 4864, 4992, 5120, 5248, 5376, + 5504, 5632, 5760, 5888, 6016, 6144, 6272, 6400, 6528, 6656, 6784, 6912, 7040, 7168, 7296, + 7424, 7552, 7680, 7808, 7936, 8064, 8192, 8448, 8704, 8960, 9216, 9472, 9728, 9984, 10240, + 10496, 10752, 11008, 11264, 11520, 11776, 12032, 12288, 12544, 12800, 13056, 13312, + 13568, 13824, 14080, 14336, 14592, 14848, 15104, 15360, 15616, 15872, 16128 +}; + +static const CVI_U32 dgain_table_size = ARRAY_SIZE(Dgain_table); + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 again = *pu32AgainLin; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (again < 2048) { + *pu32AgainDb = 0x00; + *pu32AgainLin = 1024; + } else if (again < 4096) { + *pu32AgainDb = 0x08; + *pu32AgainLin = 2048; + } else if (again < 8192) { + *pu32AgainDb = 0x09; + *pu32AgainLin = 4096; + } else if (again < 16384) { + *pu32AgainDb = 0x0B; + *pu32AgainLin = 8192; + } else if (again < 32768) { + *pu32AgainDb = 0x0F; + *pu32AgainLin = 16384; + } else { + *pu32AgainDb = 0x1F; + *pu32AgainLin = 32768; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 i; + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[dgain_table_size - 1]) { + *pu32DgainLin = Dgain_table[dgain_table_size - 1]; + *pu32DgainDb = dgain_table_size - 1; + return CVI_SUCCESS; + } + + for (i = 1; i < dgain_table_size; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + /* find Again register setting. */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_D_FINEGAIN_ADDR].u32Data = (u32Dgain & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC4336_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC4336_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC4336_MODE_1440P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC4336_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC4336_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc4336_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc4336_addr_byte; + pstI2c_data[i].u32DataByteNum = sc4336_data_byte; + } + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC4336_EXP_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC4336_EXP_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC4336_EXP_ADDR + 2; + + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = SC4336_AGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_ADDR].u32RegAddr = SC4336_DGAIN_ADDR; + pstI2c_data[LINEAR_D_FINEGAIN_ADDR].u32RegAddr = SC4336_DGAIN_ADDR + 1; + + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC4336_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC4336_VMAX_ADDR + 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC4336_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC4336_MODE_1440P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeSc4336_MirrorFip[ViPipe] != eSnsMirrorFlip) { + sc4336_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeSc4336_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC4336_MODE_S *pstMode = CVI_NULL; + + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC4336_MODE_1440P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC4336_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc4336_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC4336_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC4336_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc4336_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc4336_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc4336_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (SC4336_I2C_ADDR_IS_VALID(s32I2cAddr)) + sc4336_i2c_addr = s32I2cAddr; +} + +static CVI_S32 sc4336_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC4336_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC4336_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC4336_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC4336_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC4336_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC4336_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC4336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC4336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC4336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC4336_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC4336_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC4336_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc4336_standby, + .pfnRestart = sc4336_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = sc4336_write_register, + .pfnReadReg = sc4336_read_register, + .pfnSetBusInfo = sc4336_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc4336_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc4336/sc4336_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc4336/sc4336_cmos_ex.h new file mode 100644 index 000000000..fdf3ae46a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc4336/sc4336_cmos_ex.h @@ -0,0 +1,78 @@ +#ifndef __SC4336_CMOS_EX_H_ +#define __SC4336_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc4336_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_2_ADDR, + LINEAR_AGAIN_ADDR, + LINEAR_DGAIN_ADDR, + LINEAR_D_FINEGAIN_ADDR, + LINEAR_VMAX_0_ADDR, + LINEAR_VMAX_1_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC4336_MODE_E { + SC4336_MODE_1440P30 = 0, + SC4336_MODE_NUM +} SC4336_MODE_E; + +typedef struct _SC4336_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_LARGE_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} SC4336_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC4336[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC4336_BusInfo[]; +extern CVI_U16 g_au16SC4336_GainMode[]; +extern CVI_U16 g_au16SC4336_L2SMode[]; +extern CVI_U8 sc4336_i2c_addr; +extern const CVI_U32 sc4336_addr_byte; +extern const CVI_U32 sc4336_data_byte; +extern void sc4336_init(VI_PIPE ViPipe); +extern void sc4336_exit(VI_PIPE ViPipe); +extern void sc4336_standby(VI_PIPE ViPipe); +extern void sc4336_restart(VI_PIPE ViPipe); +extern int sc4336_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc4336_read_register(VI_PIPE ViPipe, int addr); +extern void sc4336_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc4336_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC4336_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc4336/sc4336_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc4336/sc4336_cmos_param.h new file mode 100644 index 000000000..84fb617d0 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc4336/sc4336_cmos_param.h @@ -0,0 +1,121 @@ +#ifndef __SC4336_CMOS_PARAM_H_ +#define __SC4336_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc4336_cmos_ex.h" + +static const SC4336_MODE_S g_astSC4336_mode[SC4336_MODE_NUM] = { + [SC4336_MODE_1440P30] = { + .name = "1440p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.37, /* 1500 * 30 / 0x7FFF*/ + .u32HtsDef = 2800, + .u32VtsDef = 1500, + .stExp[0] = { + .u32Min = 0, + .u32Max = 1500 - 8, //vts - 8 + .u32Def = 400, + .u32Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 32768, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16128, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc4336_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 1, 3, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC4336_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc4336/sc4336_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc4336/sc4336_sensor_ctl.c new file mode 100644 index 000000000..838a363a4 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc4336/sc4336_sensor_ctl.c @@ -0,0 +1,382 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc4336_cmos_ex.h" + +static void sc4336_linear_1440p30_init(VI_PIPE ViPipe); + +CVI_U8 sc4336_i2c_addr = 0x30; /* I2C Address of SC4336 */ +const CVI_U32 sc4336_addr_byte = 2; +const CVI_U32 sc4336_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc4336_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC4336_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc4336_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc4336_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc4336_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc4336_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc4336_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc4336_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc4336_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc4336_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc4336_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc4336_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc4336_addr_byte + sc4336_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc4336_standby(VI_PIPE ViPipe) +{ + sc4336_write_register(ViPipe, 0x0100, 0x00); +} + +void sc4336_restart(VI_PIPE ViPipe) +{ + sc4336_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc4336_write_register(ViPipe, 0x0100, 0x01); +} + +void sc4336_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC4336[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc4336_write_register(ViPipe, + g_pastSC4336[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC4336[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void sc4336_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc4336_write_register(ViPipe, 0x3221, val); +} + +#define SC4336_CHIP_ID_HI_ADDR 0x3107 +#define SC4336_CHIP_ID_LO_ADDR 0x3108 +#define SC4336_CHIP_ID 0xdc42 + +int sc4336_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + if (sc4336_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + delay_ms(5); + + nVal = sc4336_read_register(ViPipe, SC4336_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc4336_read_register(ViPipe, SC4336_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC4336_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc4336_init(VI_PIPE ViPipe) +{ + sc4336_i2c_init(ViPipe); + + sc4336_linear_1440p30_init(ViPipe); + + g_pastSC4336[ViPipe]->bInit = CVI_TRUE; +} + +void sc4336_exit(VI_PIPE ViPipe) +{ + sc4336_i2c_exit(ViPipe); +} + +/* 1440P30 and 1440P25 */ +static void sc4336_linear_1440p30_init(VI_PIPE ViPipe) +{ + sc4336_write_register(ViPipe, 0x0103, 0x01); + sc4336_write_register(ViPipe, 0x36e9, 0x80); + sc4336_write_register(ViPipe, 0x37f9, 0x80); + sc4336_write_register(ViPipe, 0x301f, 0x01); + sc4336_write_register(ViPipe, 0x30b8, 0x44); + sc4336_write_register(ViPipe, 0x3253, 0x10); + sc4336_write_register(ViPipe, 0x3301, 0x0a); + sc4336_write_register(ViPipe, 0x3302, 0xff); + sc4336_write_register(ViPipe, 0x3305, 0x00); + sc4336_write_register(ViPipe, 0x3306, 0x90); + sc4336_write_register(ViPipe, 0x3308, 0x08); + sc4336_write_register(ViPipe, 0x330a, 0x01); + sc4336_write_register(ViPipe, 0x330b, 0xb0); + sc4336_write_register(ViPipe, 0x330d, 0xf0); + sc4336_write_register(ViPipe, 0x3333, 0x10); + sc4336_write_register(ViPipe, 0x335e, 0x06); + sc4336_write_register(ViPipe, 0x335f, 0x0a); + sc4336_write_register(ViPipe, 0x3364, 0x5e); + sc4336_write_register(ViPipe, 0x337d, 0x0e); + sc4336_write_register(ViPipe, 0x338f, 0x20); + sc4336_write_register(ViPipe, 0x3390, 0x08); + sc4336_write_register(ViPipe, 0x3391, 0x09); + sc4336_write_register(ViPipe, 0x3392, 0x0f); + sc4336_write_register(ViPipe, 0x3393, 0x18); + sc4336_write_register(ViPipe, 0x3394, 0x60); + sc4336_write_register(ViPipe, 0x3395, 0xff); + sc4336_write_register(ViPipe, 0x3396, 0x08); + sc4336_write_register(ViPipe, 0x3397, 0x09); + sc4336_write_register(ViPipe, 0x3398, 0x0f); + sc4336_write_register(ViPipe, 0x3399, 0x0a); + sc4336_write_register(ViPipe, 0x339a, 0x18); + sc4336_write_register(ViPipe, 0x339b, 0x60); + sc4336_write_register(ViPipe, 0x339c, 0xff); + sc4336_write_register(ViPipe, 0x33a2, 0x04); + sc4336_write_register(ViPipe, 0x33ad, 0x0c); + sc4336_write_register(ViPipe, 0x33b2, 0x40); + sc4336_write_register(ViPipe, 0x33b3, 0x30); + sc4336_write_register(ViPipe, 0x33f8, 0x00); + sc4336_write_register(ViPipe, 0x33f9, 0xa0); + sc4336_write_register(ViPipe, 0x33fa, 0x00); + sc4336_write_register(ViPipe, 0x33fb, 0xe0); + sc4336_write_register(ViPipe, 0x33fc, 0x09); + sc4336_write_register(ViPipe, 0x33fd, 0x1f); + sc4336_write_register(ViPipe, 0x349f, 0x03); + sc4336_write_register(ViPipe, 0x34a6, 0x09); + sc4336_write_register(ViPipe, 0x34a7, 0x1f); + sc4336_write_register(ViPipe, 0x34a8, 0x28); + sc4336_write_register(ViPipe, 0x34a9, 0x28); + sc4336_write_register(ViPipe, 0x34aa, 0x01); + sc4336_write_register(ViPipe, 0x34ab, 0xd0); + sc4336_write_register(ViPipe, 0x34ac, 0x02); + sc4336_write_register(ViPipe, 0x34ad, 0x10); + sc4336_write_register(ViPipe, 0x34f8, 0x1f); + sc4336_write_register(ViPipe, 0x34f9, 0x20); + sc4336_write_register(ViPipe, 0x3630, 0xc0); + sc4336_write_register(ViPipe, 0x3631, 0x84); + sc4336_write_register(ViPipe, 0x3633, 0x44); + sc4336_write_register(ViPipe, 0x3637, 0x4c); + sc4336_write_register(ViPipe, 0x3641, 0x38); + sc4336_write_register(ViPipe, 0x3650, 0x33); + sc4336_write_register(ViPipe, 0x3670, 0x56); + sc4336_write_register(ViPipe, 0x3674, 0xc0); + sc4336_write_register(ViPipe, 0x3675, 0xa0); + sc4336_write_register(ViPipe, 0x3676, 0xa0); + sc4336_write_register(ViPipe, 0x3677, 0x84); + sc4336_write_register(ViPipe, 0x3678, 0x88); + sc4336_write_register(ViPipe, 0x3679, 0x8d); + sc4336_write_register(ViPipe, 0x367c, 0x09); + sc4336_write_register(ViPipe, 0x367d, 0x0b); + sc4336_write_register(ViPipe, 0x367e, 0x08); + sc4336_write_register(ViPipe, 0x367f, 0x0f); + sc4336_write_register(ViPipe, 0x3696, 0x44); + sc4336_write_register(ViPipe, 0x3697, 0x54); + sc4336_write_register(ViPipe, 0x3698, 0x54); + sc4336_write_register(ViPipe, 0x36a0, 0x0f); + sc4336_write_register(ViPipe, 0x36a1, 0x1f); + sc4336_write_register(ViPipe, 0x36b0, 0x81); + sc4336_write_register(ViPipe, 0x36b1, 0x83); + sc4336_write_register(ViPipe, 0x36b2, 0x85); + sc4336_write_register(ViPipe, 0x36b3, 0x8b); + sc4336_write_register(ViPipe, 0x36b4, 0x09); + sc4336_write_register(ViPipe, 0x36b5, 0x0b); + sc4336_write_register(ViPipe, 0x36b6, 0x0f); + sc4336_write_register(ViPipe, 0x370f, 0x01); + sc4336_write_register(ViPipe, 0x3722, 0x09); + sc4336_write_register(ViPipe, 0x3724, 0x21); + sc4336_write_register(ViPipe, 0x3771, 0x09); + sc4336_write_register(ViPipe, 0x3772, 0x05); + sc4336_write_register(ViPipe, 0x3773, 0x05); + sc4336_write_register(ViPipe, 0x377a, 0x0f); + sc4336_write_register(ViPipe, 0x377b, 0x1f); + sc4336_write_register(ViPipe, 0x3905, 0x8c); + sc4336_write_register(ViPipe, 0x391d, 0x04); + sc4336_write_register(ViPipe, 0x3926, 0x21); + sc4336_write_register(ViPipe, 0x3933, 0x80); + sc4336_write_register(ViPipe, 0x3934, 0x03); + sc4336_write_register(ViPipe, 0x3935, 0x00); + sc4336_write_register(ViPipe, 0x3936, 0x08); + sc4336_write_register(ViPipe, 0x3937, 0x74); + sc4336_write_register(ViPipe, 0x3938, 0x6f); + sc4336_write_register(ViPipe, 0x3939, 0x00); + sc4336_write_register(ViPipe, 0x393a, 0x00); + sc4336_write_register(ViPipe, 0x39dc, 0x02); + sc4336_write_register(ViPipe, 0x3e00, 0x00); + sc4336_write_register(ViPipe, 0x3e01, 0x5d); + sc4336_write_register(ViPipe, 0x3e02, 0x40); + sc4336_write_register(ViPipe, 0x440e, 0x02); + sc4336_write_register(ViPipe, 0x4509, 0x28); + sc4336_write_register(ViPipe, 0x450d, 0x32); + sc4336_write_register(ViPipe, 0x5000, 0x06); + sc4336_write_register(ViPipe, 0x5799, 0x46); + sc4336_write_register(ViPipe, 0x579a, 0x77); + sc4336_write_register(ViPipe, 0x57d9, 0x46); + sc4336_write_register(ViPipe, 0x57da, 0x77); + sc4336_write_register(ViPipe, 0x5ae0, 0xfe); + sc4336_write_register(ViPipe, 0x5ae1, 0x40); + sc4336_write_register(ViPipe, 0x5ae2, 0x38); + sc4336_write_register(ViPipe, 0x5ae3, 0x30); + sc4336_write_register(ViPipe, 0x5ae4, 0x28); + sc4336_write_register(ViPipe, 0x5ae5, 0x38); + sc4336_write_register(ViPipe, 0x5ae6, 0x30); + sc4336_write_register(ViPipe, 0x5ae7, 0x28); + sc4336_write_register(ViPipe, 0x5ae8, 0x3f); + sc4336_write_register(ViPipe, 0x5ae9, 0x34); + sc4336_write_register(ViPipe, 0x5aea, 0x2c); + sc4336_write_register(ViPipe, 0x5aeb, 0x3f); + sc4336_write_register(ViPipe, 0x5aec, 0x34); + sc4336_write_register(ViPipe, 0x5aed, 0x2c); + sc4336_write_register(ViPipe, 0x36e9, 0x44); + sc4336_write_register(ViPipe, 0x37f9, 0x44); + + sc4336_default_reg_init(ViPipe); + + sc4336_write_register(ViPipe, 0x0100, 0x01); + + delay_ms(100); + + printf("ViPipe:%d,===SC4336 1440P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc500ai/Makefile b/middleware/v2/component/isp/sensor/cv180x/sms_sc500ai/Makefile new file mode 100644 index 000000000..997724472 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc500ai/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc500ai.a +TARGET_SO = $(MW_LIB)/libsns_sc500ai.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc500ai/sc500ai_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc500ai/sc500ai_cmos.c new file mode 100644 index 000000000..c552e3b45 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc500ai/sc500ai_cmos.c @@ -0,0 +1,1341 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc500ai_cmos_ex.h" +#include "sc500ai_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC500AI_ID 500 +#define SENSOR_SC500AI_WIDTH 2880 +#define SENSOR_SC500AI_HEIGHT 1620 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC500AI[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC500AI_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC500AI[dev]) +#define SC500AI_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC500AI[dev] = pstCtx) +#define SC500AI_SENSOR_RESET_CTX(dev) (g_pastSC500AI[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC500AI_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC500AI_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC500AI_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC500AI_STATE_S g_astSC500AI_State[VI_MAX_PIPE_NUM] = {{0} }; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC500AI Lines Range*****/ +#define SC500AI_FULL_LINES_MAX (0x7FFF) +#define SC500AI_FULL_LINES_MAX_2TO1_WDR (0x7FFF) + +/*****SC500AI Register Address*****/ +#define SC500AI_SHS1_0_ADDR 0x3E00 +#define SC500AI_SHS1_1_ADDR 0x3E01 +#define SC500AI_SHS1_2_ADDR 0x3E02 +#define SC500AI_SHS2_0_ADDR 0x3E22 +#define SC500AI_SHS2_1_ADDR 0x3E04 +#define SC500AI_SHS2_2_ADDR 0x3E05 +#define SC500AI_AGAIN1_ADDR 0x3E08 +#define SC500AI_DGAIN1_ADDR 0x3E06 +#define SC500AI_AGAIN2_ADDR 0x3E12 +#define SC500AI_DGAIN2_ADDR 0x3E10 +#define SC500AI_VMAX_ADDR 0x320E +#define SC500AI_MAXSEXP_ADDR 0x3E23 +#define SC500AI_TABLE_END 0xFFFF + +#define SC500AI_RES_IS_1620P(w, h) ((w) <= 2880 && (h) <= 1620) +#define SC500AI_RES_IS_1440P(w, h) ((w) <= 2560 && (h) <= 1440) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC500AI_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 0.5; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astSC500AI_mode[SC500AI_MODE_1620P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC500AI_mode[SC500AI_MODE_1620P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = g_astSC500AI_mode[SC500AI_MODE_1620P30].stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = g_astSC500AI_mode[SC500AI_MODE_1620P30].stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astSC500AI_mode[SC500AI_MODE_1620P30].stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = g_astSC500AI_mode[SC500AI_MODE_1620P30].stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = 2 * (pstSnsState->u32FLStd - 5); + pstAeSnsDft->u32MinIntTime = 3; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astSC500AI_mode[SC500AI_MODE_1620P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC500AI_mode[SC500AI_MODE_1620P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = 2 * (pstSnsState->u32FLStd - 16); + pstAeSnsDft->u32MinIntTime = 5; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = g_astSC500AI_mode[SC500AI_MODE_1620P30_WDR].stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = g_astSC500AI_mode[SC500AI_MODE_1620P30_WDR].stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astSC500AI_mode[SC500AI_MODE_1620P30_WDR].stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = g_astSC500AI_mode[SC500AI_MODE_1620P30_WDR].stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + CVI_U16 u16MaxSexpReg; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC500AI_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC500AI_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC500AI_mode[pstSnsState->u8ImgMode].f32MinFps; + u16MaxSexpReg = g_astSC500AI_mode[pstSnsState->u8ImgMode].u16SexpMaxReg; + + switch (pstSnsState->u8ImgMode) { + case SC500AI_MODE_1620P30_WDR: + case SC500AI_MODE_1440P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + u16MaxSexpReg = u16MaxSexpReg * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC500AI_FULL_LINES_MAX_2TO1_WDR) ? SC500AI_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case SC500AI_MODE_1620P30: + case SC500AI_MODE_1440P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC500AI_FULL_LINES_MAX) ? SC500AI_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + g_astSC500AI_State[ViPipe].u32Sexp_MAX = u16MaxSexpReg; + } + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + pstSnsRegsInfo->astI2cData[WDR2_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_MAXSEXP_0_ADDR].u32Data = ((u16MaxSexpReg & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_MAXSEXP_1_ADDR].u32Data = u16MaxSexpReg & 0xFF; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = 2 * (pstSnsState->u32FLStd - 5); + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + CVI_U16 u16SexpReg, u16LexpReg; + CVI_U32 u32MaxLExp; + CVI_U32 u32MaxSexp = 2 * g_astSC500AI_State[ViPipe].u32Sexp_MAX - 14; + + /* short exposure reg range: + * min : 5 + * max : 2 * reg_sexp_max - 14 + * step : 4 + */ + pstSnsState->au32WDRIntTime[0] = (u32ShortIntTime > u32MaxSexp) ? u32MaxSexp : u32ShortIntTime; + if (pstSnsState->au32WDRIntTime[0] < 5) + pstSnsState->au32WDRIntTime[0] = 5; + u16SexpReg = ((CVI_U16)pstSnsState->au32WDRIntTime[0] & ~0x3) + 1; + pstSnsState->au32WDRIntTime[0] = u16SexpReg; + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + + /* long exposure reg range: + * min : 5 + * max : 2 * (vts - max sexp) - 18 + * step : 4 + */ + u32MaxLExp = 2 * (pstSnsState->au32FL[0] - g_astSC500AI_State[ViPipe].u32Sexp_MAX) - 18; + pstSnsState->au32WDRIntTime[1] = (u32LongIntTime > u32MaxLExp) ? u32MaxLExp : u32LongIntTime; + if (pstSnsState->au32WDRIntTime[1] < 5) + pstSnsState->au32WDRIntTime[1] = 5; + u16LexpReg = ((CVI_U16)pstSnsState->au32WDRIntTime[1] & ~0x3) + 1; + pstSnsState->au32WDRIntTime[1] = u16LexpReg; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + pstSnsRegsInfo->astI2cData[WDR2_SHS1_0_ADDR].u32Data = ((u16LexpReg & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[WDR2_SHS1_1_ADDR].u32Data = ((u16LexpReg & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[WDR2_SHS1_2_ADDR].u32Data = (u16LexpReg & 0xF) << 4; + + pstSnsRegsInfo->astI2cData[WDR2_SHS2_0_ADDR].u32Data = ((u16SexpReg & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[WDR2_SHS2_1_ADDR].u32Data = ((u16SexpReg & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[WDR2_SHS2_2_ADDR].u32Data = (u16SexpReg & 0xF) << 4; + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + CVI_U32 u32TmpIntTime = u32IntTime[0]; + CVI_U32 maxExp = 2 * pstSnsState->au32FL[0] - 10; + + /* linear exposure reg range: + * min : 3 + * max : 2 * vts - 10 + * step : 1 + */ + u32TmpIntTime = (u32TmpIntTime > maxExp) ? maxExp : u32TmpIntTime; + if (u32TmpIntTime < 3) + u32TmpIntTime = 3; + u32IntTime[0] = u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = (u32TmpIntTime & 0xF) << 4; + } + + return CVI_SUCCESS; + +} + +struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +}; + +static struct gain_tbl_info_s AgainInfo[5] = { + { + .gainMax = 1536, + .idxBase = 0, + .regGain = 0x03, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 3080, + .idxBase = 33, + .regGain = 0x23, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 6161, + .idxBase = 97, + .regGain = 0x27, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 12321, + .idxBase = 161, + .regGain = 0x2F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 24644, + .idxBase = 225, + .regGain = 0x3F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, +}; + +static CVI_U32 Again_table[289] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, + 1248, 1263, 1280, 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, + 1472, 1487, 1504, 1519, 1536, 1552, 1576, 1600, 1625, 1649, 1673, 1697, 1722, 1746, + 1770, 1795, 1819, 1843, 1867, 1892, 1915, 1940, 1965, 1988, 2013, 2037, 2061, 2085, + 2110, 2135, 2158, 2183, 2207, 2231, 2255, 2280, 2304, 2328, 2353, 2376, 2401, 2425, + 2449, 2473, 2498, 2523, 2546, 2571, 2595, 2619, 2643, 2668, 2692, 2716, 2741, 2764, + 2789, 2813, 2837, 2862, 2886, 2911, 2934, 2959, 2983, 3007, 3032, 3056, 3080, 3104, + 3152, 3202, 3250, 3299, 3347, 3395, 3444, 3492, 3540, 3590, 3638, 3687, 3735, 3783, + 3832, 3880, 3929, 3978, 4026, 4075, 4123, 4171, 4220, 4269, 4317, 4366, 4414, 4463, + 4511, 4559, 4609, 4657, 4705, 4754, 4802, 4851, 4899, 4947, 4997, 5045, 5093, 5142, + 5190, 5239, 5287, 5336, 5385, 5433, 5481, 5530, 5578, 5627, 5676, 5724, 5773, 5821, + 5869, 5918, 5966, 6016, 6064, 6112, 6161, 6209, 6306, 6404, 6500, 6597, 6694, 6792, + 6888, 6985, 7083, 7180, 7276, 7373, 7471, 7568, 7664, 7761, 7859, 7956, 8052, 8150, + 8247, 8344, 8440, 8538, 8635, 8732, 8828, 8926, 9023, 9120, 9217, 9314, 9411, 9508, + 9605, 9702, 9799, 9896, 9993, 10090, 10187, 10285, 10381, 10478, 10575, 10673, 10769, + 10866, 10963, 11061, 11157, 11254, 11352, 11449, 11545, 11642, 11740, 11837, 11933, + 12030, 12128, 12225, 12321, 12419, 12613, 12807, 13001, 13195, 13389, 13583, 13777, + 13971, 14166, 14359, 14554, 14747, 14942, 15135, 15330, 15523, 15718, 15911, 16106, + 16300, 16494, 16688, 16882, 17076, 17270, 17464, 17658, 17852, 18046, 18240, 18435, + 18628, 18823, 19016, 19211, 19404, 19599, 19792, 19987, 20180, 20375, 20569, 20763, + 20957, 21151, 21345, 21539, 21733, 21927, 22121, 22316, 22509, 22704, 22897, 23092, + 23285, 23480, 23673, 23868, 24061, 24256, 24450, 24644, +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[288]) { + *pu32AgainLin = Again_table[288]; + *pu32AgainDb = 288; + return CVI_SUCCESS; + } + + for (i = 1; i < 289; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 dgain = *pu32DgainLin; + CVI_U32 dgainBase; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + + /* range check */ + if (dgain > g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max) { + *pu32DgainLin = g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + *pu32DgainDb = g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + return CVI_SUCCESS; + } + if (dgain < 1024) { + *pu32DgainLin = 1024; + *pu32DgainDb = 1024; + return CVI_SUCCESS; + } + /* find the base then use 1/128 as step */ + if (dgain < 2048) + dgainBase = 1024; + else if (dgain < 4096) + dgainBase = 2048; + else if (dgain < 8192) + dgainBase = 4096; + else if (dgain < 16384) + dgainBase = 8192; + else + dgainBase = 16384; + dgain = dgain * 128 / dgainBase; + *pu32DgainLin = dgainBase * dgain / 128; + *pu32DgainDb = *pu32DgainLin; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + CVI_U32 dgainReg; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u16Mode = g_au16SC500AI_GainMode[ViPipe]; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + static bool bGainLogicChanged[VI_MAX_PIPE_NUM] = {true}; + CVI_U32 dgainBase; + + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + // control sensor DPC to fix high-gain noise + if (Again_table[u32Again] >= 30720 && bGainLogicChanged[ViPipe]) { + sc500ai_write_register(ViPipe, 0x5799, 0x7); + bGainLogicChanged[ViPipe] = false; + } else if (Again_table[u32Again] <= 20480 && !bGainLogicChanged[ViPipe]) { + sc500ai_write_register(ViPipe, 0x5799, 0x0); + bGainLogicChanged[ViPipe] = true; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + if (u32Dgain > g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max) + u32Dgain = g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + if (u32Dgain < 1024) + u32Dgain = 1024; + /* find the base then use 1/128 as step */ + if (u32Dgain < 2048) { + dgainBase = 1024; + dgainReg = 0x0; + } else if (u32Dgain < 4096) { + dgainBase = 2048; + dgainReg = 0x1; + } else if (u32Dgain < 8192) { + dgainBase = 4096; + dgainReg = 0x3; + } else if (u32Dgain < 16384) { + dgainBase = 8192; + dgainReg = 0x7; + } else { + dgainBase = 16384; + dgainReg = 0xf; + } + u32Dgain = u32Dgain * 128 / dgainBase; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0_ADDR].u32Data = (dgainReg & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1_ADDR].u32Data = (u32Dgain & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + /* find SEF Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find SEF Dgain register setting. */ + if (u32Dgain > g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max) + u32Dgain = g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + if (u32Dgain < 1024) + u32Dgain = 1024; + /* find the base then use 1/128 as step */ + if (u32Dgain < 2048) { + dgainBase = 1024; + dgainReg = 0x0; + } else if (u32Dgain < 4096) { + dgainBase = 2048; + dgainReg = 0x1; + } else if (u32Dgain < 8192) { + dgainBase = 4096; + dgainReg = 0x3; + } else if (u32Dgain < 16384) { + dgainBase = 8192; + dgainReg = 0x7; + } else { + dgainBase = 16384; + dgainReg = 0xf; + } + u32Dgain = u32Dgain * 128 / dgainBase; + + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_0_ADDR].u32Data = (dgainReg & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_1_ADDR].u32Data = (u32Dgain & 0xFF); + + u32Again = pu32Again[1]; + u32Dgain = pu32Dgain[1]; + + /* find LEF Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find LEF Dgain register setting. */ + if (u32Dgain > g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max) + u32Dgain = g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + if (u32Dgain < 1024) + u32Dgain = 1024; + /* find the base then use 1/128 as step */ + if (u32Dgain < 2048) { + dgainBase = 1024; + dgainReg = 0x0; + } else if (u32Dgain < 4096) { + dgainBase = 2048; + dgainReg = 0x1; + } else if (u32Dgain < 8192) { + dgainBase = 4096; + dgainReg = 0x3; + } else if (u32Dgain < 16384) { + dgainBase = 8192; + dgainReg = 0x7; + } else { + dgainBase = 16384; + dgainReg = 0xf; + } + u32Dgain = u32Dgain * 128 / dgainBase; + + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_0_ADDR].u32Data = (dgainReg & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_1_ADDR].u32Data = (u32Dgain & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_0_ADDR].u32Data = (info->regGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_1_ADDR].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + if (u32Dgain > g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max) + u32Dgain = g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + if (u32Dgain < 1024) + u32Dgain = 1024; + /* find the base then use 1/128 as step */ + if (u32Dgain < 2048) { + dgainBase = 1024; + dgainReg = 0x0; + } else if (u32Dgain < 4096) { + dgainBase = 2048; + dgainReg = 0x1; + } else if (u32Dgain < 8192) { + dgainBase = 4096; + dgainReg = 0x3; + } else if (u32Dgain < 16384) { + dgainBase = 8192; + dgainReg = 0x7; + } else { + dgainBase = 16384; + dgainReg = 0xf; + } + u32Dgain = u32Dgain * 128 / dgainBase; + + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_0_ADDR].u32Data = (dgainReg & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_0_ADDR].u32Data = (dgainReg & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_1_ADDR].u32Data = (u32Dgain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_1_ADDR].u32Data = (u32Dgain & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0; + CVI_U32 u32ShortTimeMinLimit = 5; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32MaxSexp = 2 * g_astSC500AI_State[ViPipe].u32Sexp_MAX - 14; + + (void) u16ManRatioEnable; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + /* short exposure reg range: + * min : 5 + * max : 2 * (max sexp - 7) + * step : 4 + * long exposure reg range: + * min : 5 + * max : 2 * (vts - max sexp - 9) + * step : 4 + */ + u32IntTimeMaxTmp = ((2 * pstSnsState->au32FL[0] - 16) * 0x40) / (au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32MaxSexp) ? u32MaxSexp : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp < u32ShortTimeMinLimit) ? u32ShortTimeMinLimit : u32IntTimeMaxTmp; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + syslog(LOG_DEBUG, "ViPipe = %d ratio = %d, (%d, %d)\n", ViPipe, au32Ratio[0], + u32IntTimeMaxTmp, u32ShortTimeMinLimit); + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC500AI_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC500AI_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == SC500AI_MODE_1620P30_WDR) + pstSnsState->u8ImgMode = SC500AI_MODE_1620P30; + else if (pstSnsState->u8ImgMode == SC500AI_MODE_1440P30_WDR) + pstSnsState->u8ImgMode = SC500AI_MODE_1440P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC500AI_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == SC500AI_MODE_1620P30) + pstSnsState->u8ImgMode = SC500AI_MODE_1620P30_WDR; + else if (pstSnsState->u8ImgMode == SC500AI_MODE_1440P30) + pstSnsState->u8ImgMode = SC500AI_MODE_1440P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astSC500AI_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "2to1 line WDR 1080p mode(60fps->30fps)\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC500AI_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc500ai_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc500ai_addr_byte; + pstI2c_data[i].u32DataByteNum = sc500ai_data_byte; + } + + //DOL 2t1 Mode Regs + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + //WDR Mode Regs + pstI2c_data[WDR2_SHS1_0_ADDR].u32RegAddr = SC500AI_SHS1_0_ADDR; + pstI2c_data[WDR2_SHS1_1_ADDR].u32RegAddr = SC500AI_SHS1_1_ADDR; + pstI2c_data[WDR2_SHS1_2_ADDR].u32RegAddr = SC500AI_SHS1_2_ADDR; + pstI2c_data[WDR2_SHS2_0_ADDR].u32RegAddr = SC500AI_SHS2_0_ADDR; + pstI2c_data[WDR2_SHS2_1_ADDR].u32RegAddr = SC500AI_SHS2_1_ADDR; + pstI2c_data[WDR2_SHS2_2_ADDR].u32RegAddr = SC500AI_SHS2_2_ADDR; + pstI2c_data[WDR2_AGAIN1_0_ADDR].u32RegAddr = SC500AI_AGAIN1_ADDR; + pstI2c_data[WDR2_AGAIN1_1_ADDR].u32RegAddr = SC500AI_AGAIN1_ADDR + 1; + pstI2c_data[WDR2_DGAIN1_0_ADDR].u32RegAddr = SC500AI_DGAIN1_ADDR; + pstI2c_data[WDR2_DGAIN1_1_ADDR].u32RegAddr = SC500AI_DGAIN1_ADDR + 1; + pstI2c_data[WDR2_AGAIN2_0_ADDR].u32RegAddr = SC500AI_AGAIN2_ADDR; + pstI2c_data[WDR2_AGAIN2_1_ADDR].u32RegAddr = SC500AI_AGAIN2_ADDR + 1; + pstI2c_data[WDR2_DGAIN2_0_ADDR].u32RegAddr = SC500AI_DGAIN2_ADDR; + pstI2c_data[WDR2_DGAIN2_1_ADDR].u32RegAddr = SC500AI_DGAIN2_ADDR + 1; + pstI2c_data[WDR2_VMAX_0_ADDR].u32RegAddr = SC500AI_VMAX_ADDR; + pstI2c_data[WDR2_VMAX_1_ADDR].u32RegAddr = SC500AI_VMAX_ADDR + 1; + pstI2c_data[WDR2_MAXSEXP_0_ADDR].u32RegAddr = SC500AI_MAXSEXP_ADDR; + pstI2c_data[WDR2_MAXSEXP_1_ADDR].u32RegAddr = SC500AI_MAXSEXP_ADDR + 1; + + break; + default: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC500AI_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC500AI_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC500AI_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC500AI_AGAIN1_ADDR; + pstI2c_data[LINEAR_AGAIN_1_ADDR].u32RegAddr = SC500AI_AGAIN1_ADDR + 1; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC500AI_DGAIN1_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC500AI_DGAIN1_ADDR + 1; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC500AI_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC500AI_VMAX_ADDR + 1; + + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC500AI_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC500AI_MODE_1440P30; + } else if (SC500AI_RES_IS_1620P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC500AI_MODE_1620P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (SC500AI_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC500AI_MODE_1440P30_WDR; + } else if (SC500AI_RES_IS_1620P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC500AI_MODE_1620P30_WDR; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC500AI_MODE_S *pstMode = CVI_NULL; + + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC500AI_MODE_1620P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC500AI_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc500ai_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC500AI_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC500AI_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } else { + pstRxAttr->mac_clk = RX_MAC_CLK_400M; + } + if (pstSnsState->u8ImgMode == SC500AI_MODE_1440P30) + pstRxAttr->mipi_attr.dphy.hs_settle = 8; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc500ai_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc500ai_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc500ai_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc500ai_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC500AI_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC500AI_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC500AI_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC500AI_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC500AI_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC500AI_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC500AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC500AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC500AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC500AI_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC500AI_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC500AI_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc500ai_standby, + .pfnRestart = sc500ai_restart, + .pfnMirrorFlip = sc500ai_mirror_flip, + .pfnWriteReg = sc500ai_write_register, + .pfnReadReg = sc500ai_read_register, + .pfnSetBusInfo = sc500ai_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc500ai_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc500ai/sc500ai_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc500ai/sc500ai_cmos_ex.h new file mode 100644 index 000000000..7438fd9c5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc500ai/sc500ai_cmos_ex.h @@ -0,0 +1,110 @@ +#ifndef __SC500AI_CMOS_EX_H_ +#define __SC500AI_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc500ai_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_2_ADDR, + LINEAR_AGAIN_0_ADDR, + LINEAR_AGAIN_1_ADDR, + LINEAR_DGAIN_0_ADDR, + LINEAR_DGAIN_1_ADDR, + LINEAR_VMAX_0_ADDR, + LINEAR_VMAX_1_ADDR, + LINEAR_REGS_NUM +}; + +enum sc500ai_dol2_regs_e { + WDR2_SHS1_0_ADDR, + WDR2_SHS1_1_ADDR, + WDR2_SHS1_2_ADDR, + WDR2_SHS2_0_ADDR, + WDR2_SHS2_1_ADDR, + WDR2_SHS2_2_ADDR, + WDR2_AGAIN1_0_ADDR, + WDR2_AGAIN1_1_ADDR, + WDR2_DGAIN1_0_ADDR, + WDR2_DGAIN1_1_ADDR, + WDR2_AGAIN2_0_ADDR, + WDR2_AGAIN2_1_ADDR, + WDR2_DGAIN2_0_ADDR, + WDR2_DGAIN2_1_ADDR, + WDR2_VMAX_0_ADDR, + WDR2_VMAX_1_ADDR, + WDR2_MAXSEXP_0_ADDR, + WDR2_MAXSEXP_1_ADDR, + WDR2_REGS_NUM +}; + +typedef enum _SC500AI_MODE_E { + SC500AI_MODE_1620P30 = 0, + SC500AI_MODE_1440P30, + SC500AI_MODE_LINEAR_NUM, + SC500AI_MODE_1620P30_WDR = SC500AI_MODE_LINEAR_NUM, + SC500AI_MODE_1440P30_WDR, + SC500AI_MODE_NUM +} SC500AI_MODE_E; + +typedef struct _SC500AI_STATE_S { + CVI_U32 u32Sexp_MAX; /* (2*{16’h3e23,16’h3e24} – 'd10)/2 */ +} SC500AI_STATE_S; + +typedef struct _SC500AI_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + CVI_U16 u16SexpMaxReg; /* {16’h3e23,16’h3e24} */ + char name[64]; +} SC500AI_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC500AI[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC500AI_BusInfo[]; +extern CVI_U16 g_au16SC500AI_GainMode[]; +extern CVI_U16 g_au16SC500AI_L2SMode[]; +extern const CVI_U8 sc500ai_i2c_addr; +extern const CVI_U32 sc500ai_addr_byte; +extern const CVI_U32 sc500ai_data_byte; +extern void sc500ai_init(VI_PIPE ViPipe); +extern void sc500ai_exit(VI_PIPE ViPipe); +extern void sc500ai_standby(VI_PIPE ViPipe); +extern void sc500ai_restart(VI_PIPE ViPipe); +extern int sc500ai_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc500ai_read_register(VI_PIPE ViPipe, int addr); +extern void sc500ai_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc500ai_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC500AI_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc500ai/sc500ai_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc500ai/sc500ai_cmos_param.h new file mode 100644 index 000000000..794712a2a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc500ai/sc500ai_cmos_param.h @@ -0,0 +1,394 @@ +#ifndef __SC500AI_CMOS_PARAM_H_ +#define __SC500AI_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc500ai_cmos_ex.h" + +static const SC500AI_MODE_S g_astSC500AI_mode[SC500AI_MODE_NUM] = { + [SC500AI_MODE_1620P30] = { + .name = "1620p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2880, + .u32Height = 1620, + }, + .stMaxSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.52, /* 1650 * 30 / 0x7FFF*/ + .u32HtsDef = 2560, /* NA */ + .u32VtsDef = 1650, + .stExp[0] = { + .u16Min = 3, + .u16Max = 3290, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 24644, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 32640, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [SC500AI_MODE_1620P30_WDR] = { + .name = "1620p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2880, + .u32Height = 1620, + }, + .stMaxSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2880, + .u32Height = 1620, + }, + .stMaxSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 3.03, /* 2250 * 30 / 0x7FFF*/ + .u32HtsDef = 640, /* NA */ + .u32VtsDef = 3300, + .u16SexpMaxReg = 0xc6, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 24644, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 32640, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 24644, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 32640, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [SC500AI_MODE_1440P30] = { + .name = "1440p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.38, /* 1650 * 30 / 0x7FFF*/ + .u32HtsDef = 3360, /* NA */ + .u32VtsDef = 1500, + .stExp[0] = { + .u16Min = 3, + .u16Max = 3290, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 24644, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 32640, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [SC500AI_MODE_1440P30_WDR] = { + .name = "1440p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.75, /* 3000 * 30 / 0x7FFF*/ + .u32HtsDef = 3000, /* NA */ + .u32VtsDef = 3000, + .u16SexpMaxReg = 0xb4, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 24644, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 32640, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 24644, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 32640, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.02792946062982082367, 3.36534714698791503906}, //B: slope, intercept + {0.02071751467883586884, 5.34583568572998046875}, //Gb: slope, intercept + {0.02110148966312408447, 5.02954530715942382813}, //Gr: slope, intercept + {0.02168512716889381409, 4.89776754379272460938}, //R: slope, intercept + }, + { //iso 200 + {0.03194080293178558350, 5.61192893981933593750}, //B: slope, intercept + {0.02428408525884151459, 7.94834280014038085938}, //Gb: slope, intercept + {0.02499442733824253082, 7.72430133819580078125}, //Gr: slope, intercept + {0.02584112435579299927, 7.20574426651000976563}, //R: slope, intercept + }, + { //iso 400 + {0.04612467437982559204, 6.88752269744873046875}, //B: slope, intercept + {0.03022909909486770630, 11.05101776123046875000}, //Gb: slope, intercept + {0.03175539523363113403, 10.60332489013671875000}, //Gr: slope, intercept + {0.03522306308150291443, 9.36425399780273437500}, //R: slope, intercept + }, + { //iso 800 + {0.06092500314116477966, 9.79670524597167968750}, //B: slope, intercept + {0.03984217345714569092, 15.30182266235351562500}, //Gb: slope, intercept + {0.04019560664892196655, 14.93132972717285156250}, //Gr: slope, intercept + {0.04470816254615783691, 13.26843166351318359375}, //R: slope, intercept + }, + { //iso 1600 + {0.08295634388923645020, 14.20334625244140625000}, //B: slope, intercept + {0.05075264349579811096, 20.99221038818359375000}, //Gb: slope, intercept + {0.05426201224327087402, 20.08068656921386718750}, //Gr: slope, intercept + {0.05945669487118721008, 19.02898788452148437500}, //R: slope, intercept + }, + { //iso 3200 + {0.09782519936561584473, 21.84967994689941406250}, //B: slope, intercept + {0.06690908223390579224, 26.53993988037109375000}, //Gb: slope, intercept + {0.06954573839902877808, 25.74129104614257812500}, //Gr: slope, intercept + {0.09061723947525024414, 22.98998260498046875000}, //R: slope, intercept + }, + { //iso 6400 + {0.14311420917510986328, 28.96467971801757812500}, //B: slope, intercept + {0.08148498833179473877, 37.93062591552734375000}, //Gb: slope, intercept + {0.08273542672395706177, 38.37096405029296875000}, //Gr: slope, intercept + {0.12093253433704376221, 33.31475067138671875000}, //R: slope, intercept + }, + { //iso 12800 + {0.17958122491836547852, 43.49506759643554687500}, //B: slope, intercept + {0.09839969873428344727, 55.43268966674804687500}, //Gb: slope, intercept + {0.10201884806156158447, 52.97607040405273437500}, //Gr: slope, intercept + {0.15302789211273193359, 47.54779434204101562500}, //R: slope, intercept + }, + { //iso 25600 + {0.25833165645599365234, 56.96470642089843750000}, //B: slope, intercept + {0.13260601460933685303, 74.69016265869140625000}, //Gb: slope, intercept + {0.14035490155220031738, 75.44366455078125000000}, //Gr: slope, intercept + {0.23465165495872497559, 60.52228164672851562500}, //R: slope, intercept + }, + { //iso 51200 + {0.37595292925834655762, 78.54853057861328125000}, //B: slope, intercept + {0.21475413441658020020, 102.12300872802734375000}, //Gb: slope, intercept + {0.20840260386466979980, 103.65763854980468750000}, //Gr: slope, intercept + {0.34428051114082336426, 87.83551025390625000000}, //R: slope, intercept + }, + { //iso 102400 + {0.51122575998306274414, 113.49224090576171875000}, //B: slope, intercept + {0.29245173931121826172, 154.26939392089843750000}, //Gb: slope, intercept + {0.31501635909080505371, 148.29017639160156250000}, //Gr: slope, intercept + {0.47034618258476257324, 124.06208038330078125000}, //R: slope, intercept + }, + { //iso 204800 + {0.67213481664657592773, 134.71751403808593750000}, //B: slope, intercept + {0.40368056297302246094, 189.80801391601562500000}, //Gb: slope, intercept + {0.43581819534301757813, 186.44682312011718750000}, //Gr: slope, intercept + {0.60127359628677368164, 160.66384887695312500000}, //R: slope, intercept + }, + { //iso 409600 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 819200 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {257, 260, 260, 260, 260, 261, 259, 258, /*8*/255, 248, 264, 300, 291, 310, 310, 311}, + {257, 260, 260, 260, 260, 261, 259, 257, /*8*/254, 247, 261, 296, 287, 309, 309, 306}, + {257, 260, 260, 260, 260, 261, 259, 257, /*8*/255, 248, 262, 298, 289, 308, 308, 308}, + {257, 260, 260, 260, 260, 261, 259, 258, /*8*/255, 247, 261, 301, 293, 310, 308, 314}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1095, 1105, 1102, 1108, 1108, 1108}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1104, 1101, 1108, 1108, 1107}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1104, 1102, 1107, 1107, 1107}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1105, 1103, 1108, 1107, 1109}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc500ai_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {1, 2, 0, 3, 4}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + .dphy = { + .enable = 1, + .hs_settle = 14, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC500AI_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc500ai/sc500ai_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc500ai/sc500ai_sensor_ctl.c new file mode 100644 index 000000000..cd783e392 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc500ai/sc500ai_sensor_ctl.c @@ -0,0 +1,846 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc500ai_cmos_ex.h" + +static void sc500ai_wdr_1620p30_2to1_init(VI_PIPE ViPipe); +static void sc500ai_linear_1620p30_init(VI_PIPE ViPipe); +static void sc500ai_wdr_1440p30_2to1_init(VI_PIPE ViPipe); +static void sc500ai_linear_1440p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc500ai_i2c_addr = 0x30; /* I2C Address of SC500AI */ +const CVI_U32 sc500ai_addr_byte = 2; +const CVI_U32 sc500ai_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc500ai_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC500AI_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc500ai_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc500ai_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc500ai_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc500ai_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc500ai_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc500ai_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc500ai_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc500ai_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc500ai_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc500ai_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc500ai_addr_byte + sc500ai_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc500ai_standby(VI_PIPE ViPipe) +{ + sc500ai_write_register(ViPipe, 0x0100, 0x00); +} + +void sc500ai_restart(VI_PIPE ViPipe) +{ + sc500ai_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc500ai_write_register(ViPipe, 0x0100, 0x01); +} + +void sc500ai_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC500AI[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc500ai_write_register(ViPipe, + g_pastSC500AI[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC500AI[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC500AI_CHIP_ID_HI_ADDR 0x3107 +#define SC500AI_CHIP_ID_LO_ADDR 0x3108 +#define SC500AI_CHIP_ID 0xce1f + +void sc500ai_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc500ai_write_register(ViPipe, 0x3221, val); +} + +static int sc500ai_init_ex(VI_PIPE ViPipe) +{ + CVI_U32 debounce = 0; + int nVal, cnt = 0; + CVI_U16 tmp = 0, tmpPrev = 0; + + while (debounce++ < 5) { + nVal = sc500ai_read_register(ViPipe, 0x3109); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "debounce read fail.\n"); + return nVal; + } + tmp = (nVal & 0xFF) << 8; + if (tmp != tmpPrev) + debounce = 0; + tmpPrev = tmp; + if (cnt++ > 20) { + CVI_TRACE_SNS(CVI_DBG_ERR, "debounce fail.\n"); + return nVal; + } + } + if (tmp == 1) { + sc500ai_write_register(ViPipe, 0x336d, 0x23); + } else { + sc500ai_write_register(ViPipe, 0x336d, 0x03); + } + + debounce = 0; + cnt = 0; + while (debounce++ < 5) { + nVal = sc500ai_read_register(ViPipe, 0x3040); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "debounce read fail.\n"); + return nVal; + } + tmp = (nVal & 0xFF) << 8; + if (tmp != tmpPrev) + debounce = 0; + tmpPrev = tmp; + if (cnt++ > 20) { + CVI_TRACE_SNS(CVI_DBG_ERR, "debounce fail.\n"); + return nVal; + } + } + if (tmp == 0) { + sc500ai_write_register(ViPipe, 0x363c, 0x42); + } else { + sc500ai_write_register(ViPipe, 0x363c, 0x40); + } + + return CVI_SUCCESS; +} + +int sc500ai_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + delay_ms(4); + if (sc500ai_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc500ai_read_register(ViPipe, SC500AI_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc500ai_read_register(ViPipe, SC500AI_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC500AI_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc500ai_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + CVI_U8 u8ImgMode; + + bInit = g_pastSC500AI[ViPipe]->bInit; + enWDRMode = g_pastSC500AI[ViPipe]->enWDRMode; + u8ImgMode = g_pastSC500AI[ViPipe]->u8ImgMode; + + sc500ai_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == SC500AI_MODE_1620P30_WDR) { + /* SC500AI_MODE_1620P30_WDR */ + sc500ai_wdr_1620p30_2to1_init(ViPipe); + } else if (u8ImgMode == SC500AI_MODE_1440P30_WDR) { + /* SC500AI_MODE_1620P30_WDR */ + sc500ai_wdr_1440p30_2to1_init(ViPipe); + } else { + } + } else { + if (u8ImgMode == SC500AI_MODE_1620P30) { + sc500ai_linear_1620p30_init(ViPipe); + } else if (u8ImgMode == SC500AI_MODE_1440P30) { + /* SC500AI_MODE_1440P30 */ + sc500ai_linear_1440p30_init(ViPipe); + } else { + } + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == SC500AI_MODE_1620P30_WDR) { + /* SC500AI_MODE_1620P30_WDR */ + sc500ai_wdr_1620p30_2to1_init(ViPipe); + } else if (u8ImgMode == SC500AI_MODE_1440P30_WDR) { + /* SC500AI_MODE_1620P30_WDR */ + sc500ai_wdr_1440p30_2to1_init(ViPipe); + } else { + } + } else { + if (u8ImgMode == SC500AI_MODE_1620P30) { + sc500ai_linear_1620p30_init(ViPipe); + } else if (u8ImgMode == SC500AI_MODE_1440P30) { + /* SC500AI_MODE_1440P30 */ + sc500ai_linear_1440p30_init(ViPipe); + } else { + } + } + } + g_pastSC500AI[ViPipe]->bInit = CVI_TRUE; +} + +void sc500ai_exit(VI_PIPE ViPipe) +{ + sc500ai_i2c_exit(ViPipe); +} + +/* 1620P30 and 1620P25 */ +static void sc500ai_linear_1620p30_init(VI_PIPE ViPipe) +{ + sc500ai_write_register(ViPipe, 0x0103, 0x01); + sc500ai_write_register(ViPipe, 0x0100, 0x00); + sc500ai_write_register(ViPipe, 0x36e9, 0x80); + sc500ai_write_register(ViPipe, 0x36f9, 0x80); + sc500ai_write_register(ViPipe, 0x301f, 0x01); + sc500ai_write_register(ViPipe, 0x3253, 0x0a); + sc500ai_write_register(ViPipe, 0x3301, 0x0a); + sc500ai_write_register(ViPipe, 0x3302, 0x18); + sc500ai_write_register(ViPipe, 0x3303, 0x10); + sc500ai_write_register(ViPipe, 0x3304, 0x60); + sc500ai_write_register(ViPipe, 0x3306, 0x60); + sc500ai_write_register(ViPipe, 0x3308, 0x10); + sc500ai_write_register(ViPipe, 0x3309, 0x70); + sc500ai_write_register(ViPipe, 0x330a, 0x00); + sc500ai_write_register(ViPipe, 0x330b, 0xf0); + sc500ai_write_register(ViPipe, 0x330d, 0x18); + sc500ai_write_register(ViPipe, 0x330e, 0x20); + sc500ai_write_register(ViPipe, 0x330f, 0x02); + sc500ai_write_register(ViPipe, 0x3310, 0x02); + sc500ai_write_register(ViPipe, 0x331c, 0x04); + sc500ai_write_register(ViPipe, 0x331e, 0x51); + sc500ai_write_register(ViPipe, 0x331f, 0x61); + sc500ai_write_register(ViPipe, 0x3320, 0x09); + sc500ai_write_register(ViPipe, 0x3333, 0x10); + sc500ai_write_register(ViPipe, 0x334c, 0x08); + sc500ai_write_register(ViPipe, 0x3356, 0x09); + sc500ai_write_register(ViPipe, 0x3364, 0x17); + sc500ai_write_register(ViPipe, 0x336d, 0x03); + sc500ai_write_register(ViPipe, 0x3390, 0x08); + sc500ai_write_register(ViPipe, 0x3391, 0x18); + sc500ai_write_register(ViPipe, 0x3392, 0x38); + sc500ai_write_register(ViPipe, 0x3393, 0x0a); + sc500ai_write_register(ViPipe, 0x3394, 0x20); + sc500ai_write_register(ViPipe, 0x3395, 0x20); + sc500ai_write_register(ViPipe, 0x3396, 0x08); + sc500ai_write_register(ViPipe, 0x3397, 0x18); + sc500ai_write_register(ViPipe, 0x3398, 0x38); + sc500ai_write_register(ViPipe, 0x3399, 0x0a); + sc500ai_write_register(ViPipe, 0x339a, 0x20); + sc500ai_write_register(ViPipe, 0x339b, 0x20); + sc500ai_write_register(ViPipe, 0x339c, 0x20); + sc500ai_write_register(ViPipe, 0x33ac, 0x10); + sc500ai_write_register(ViPipe, 0x33ae, 0x10); + sc500ai_write_register(ViPipe, 0x33af, 0x19); + sc500ai_write_register(ViPipe, 0x360f, 0x01); + sc500ai_write_register(ViPipe, 0x3622, 0x03); + sc500ai_write_register(ViPipe, 0x363a, 0x1f); + sc500ai_write_register(ViPipe, 0x363c, 0x40); + sc500ai_write_register(ViPipe, 0x3651, 0x7d); + sc500ai_write_register(ViPipe, 0x3670, 0x0a); + sc500ai_write_register(ViPipe, 0x3671, 0x07); + sc500ai_write_register(ViPipe, 0x3672, 0x17); + sc500ai_write_register(ViPipe, 0x3673, 0x1e); + sc500ai_write_register(ViPipe, 0x3674, 0x82); + sc500ai_write_register(ViPipe, 0x3675, 0x64); + sc500ai_write_register(ViPipe, 0x3676, 0x66); + sc500ai_write_register(ViPipe, 0x367a, 0x48); + sc500ai_write_register(ViPipe, 0x367b, 0x78); + sc500ai_write_register(ViPipe, 0x367c, 0x58); + sc500ai_write_register(ViPipe, 0x367d, 0x78); + sc500ai_write_register(ViPipe, 0x3690, 0x34); + sc500ai_write_register(ViPipe, 0x3691, 0x34); + sc500ai_write_register(ViPipe, 0x3692, 0x54); + sc500ai_write_register(ViPipe, 0x369c, 0x48); + sc500ai_write_register(ViPipe, 0x369d, 0x78); + sc500ai_write_register(ViPipe, 0x36ec, 0x1a); + sc500ai_write_register(ViPipe, 0x3904, 0x04); + sc500ai_write_register(ViPipe, 0x3908, 0x41); + sc500ai_write_register(ViPipe, 0x391d, 0x04); + sc500ai_write_register(ViPipe, 0x39c2, 0x30); + sc500ai_write_register(ViPipe, 0x3e01, 0xcd); + sc500ai_write_register(ViPipe, 0x3e02, 0xc0); + sc500ai_write_register(ViPipe, 0x3e16, 0x00); + sc500ai_write_register(ViPipe, 0x3e17, 0x80); + sc500ai_write_register(ViPipe, 0x4500, 0x88); + sc500ai_write_register(ViPipe, 0x4509, 0x20); + sc500ai_write_register(ViPipe, 0x481b, 0x50); // hs-trail + sc500ai_write_register(ViPipe, 0x5799, 0x00); + sc500ai_write_register(ViPipe, 0x59e0, 0x60); + sc500ai_write_register(ViPipe, 0x59e1, 0x08); + sc500ai_write_register(ViPipe, 0x59e2, 0x3f); + sc500ai_write_register(ViPipe, 0x59e3, 0x18); + sc500ai_write_register(ViPipe, 0x59e4, 0x18); + sc500ai_write_register(ViPipe, 0x59e5, 0x3f); + sc500ai_write_register(ViPipe, 0x59e7, 0x02); + sc500ai_write_register(ViPipe, 0x59e8, 0x38); + sc500ai_write_register(ViPipe, 0x59e9, 0x20); + sc500ai_write_register(ViPipe, 0x59ea, 0x0c); + sc500ai_write_register(ViPipe, 0x59ec, 0x08); + sc500ai_write_register(ViPipe, 0x59ed, 0x02); + sc500ai_write_register(ViPipe, 0x59ee, 0xa0); + sc500ai_write_register(ViPipe, 0x59ef, 0x08); + sc500ai_write_register(ViPipe, 0x59f4, 0x18); + sc500ai_write_register(ViPipe, 0x59f5, 0x10); + sc500ai_write_register(ViPipe, 0x59f6, 0x0c); + sc500ai_write_register(ViPipe, 0x59f9, 0x02); + sc500ai_write_register(ViPipe, 0x59fa, 0x18); + sc500ai_write_register(ViPipe, 0x59fb, 0x10); + sc500ai_write_register(ViPipe, 0x59fc, 0x0c); + sc500ai_write_register(ViPipe, 0x59ff, 0x02); + sc500ai_write_register(ViPipe, 0x36e9, 0x1c); + sc500ai_write_register(ViPipe, 0x36f9, 0x24); + sc500ai_init_ex(ViPipe); + + sc500ai_default_reg_init(ViPipe); + + sc500ai_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC500AI 1620P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +static void sc500ai_wdr_1620p30_2to1_init(VI_PIPE ViPipe) +{ + sc500ai_write_register(ViPipe, 0x0103, 0x01); + sc500ai_write_register(ViPipe, 0x0100, 0x00); + sc500ai_write_register(ViPipe, 0x36e9, 0x80); + sc500ai_write_register(ViPipe, 0x36f9, 0x80); + sc500ai_write_register(ViPipe, 0x301f, 0x06); + sc500ai_write_register(ViPipe, 0x3106, 0x01); + sc500ai_write_register(ViPipe, 0x320e, 0x0c); + sc500ai_write_register(ViPipe, 0x320f, 0xe4); + sc500ai_write_register(ViPipe, 0x3220, 0x53); + sc500ai_write_register(ViPipe, 0x3250, 0xff); + sc500ai_write_register(ViPipe, 0x3253, 0x0a); + sc500ai_write_register(ViPipe, 0x3301, 0x0b); + sc500ai_write_register(ViPipe, 0x3302, 0x20); + sc500ai_write_register(ViPipe, 0x3303, 0x10); + sc500ai_write_register(ViPipe, 0x3304, 0x70); + sc500ai_write_register(ViPipe, 0x3306, 0x50); + sc500ai_write_register(ViPipe, 0x3308, 0x18); + sc500ai_write_register(ViPipe, 0x3309, 0x80); + sc500ai_write_register(ViPipe, 0x330a, 0x00); + sc500ai_write_register(ViPipe, 0x330b, 0xe8); + sc500ai_write_register(ViPipe, 0x330d, 0x30); + sc500ai_write_register(ViPipe, 0x330e, 0x30); + sc500ai_write_register(ViPipe, 0x330f, 0x02); + sc500ai_write_register(ViPipe, 0x3310, 0x02); + sc500ai_write_register(ViPipe, 0x331c, 0x08); + sc500ai_write_register(ViPipe, 0x331e, 0x61); + sc500ai_write_register(ViPipe, 0x331f, 0x71); + sc500ai_write_register(ViPipe, 0x3320, 0x11); + sc500ai_write_register(ViPipe, 0x3333, 0x10); + sc500ai_write_register(ViPipe, 0x334c, 0x10); + sc500ai_write_register(ViPipe, 0x3356, 0x11); + sc500ai_write_register(ViPipe, 0x3364, 0x17); + sc500ai_write_register(ViPipe, 0x336d, 0x03); + sc500ai_write_register(ViPipe, 0x3390, 0x08); + sc500ai_write_register(ViPipe, 0x3391, 0x18); + sc500ai_write_register(ViPipe, 0x3392, 0x38); + sc500ai_write_register(ViPipe, 0x3393, 0x0a); + sc500ai_write_register(ViPipe, 0x3394, 0x0a); + sc500ai_write_register(ViPipe, 0x3395, 0x12); + sc500ai_write_register(ViPipe, 0x3396, 0x08); + sc500ai_write_register(ViPipe, 0x3397, 0x18); + sc500ai_write_register(ViPipe, 0x3398, 0x38); + sc500ai_write_register(ViPipe, 0x3399, 0x0a); + sc500ai_write_register(ViPipe, 0x339a, 0x0a); + sc500ai_write_register(ViPipe, 0x339b, 0x0a); + sc500ai_write_register(ViPipe, 0x339c, 0x12); + sc500ai_write_register(ViPipe, 0x33ac, 0x10); + sc500ai_write_register(ViPipe, 0x33ae, 0x20); + sc500ai_write_register(ViPipe, 0x33af, 0x21); + sc500ai_write_register(ViPipe, 0x360f, 0x01); + sc500ai_write_register(ViPipe, 0x3621, 0xe8); + sc500ai_write_register(ViPipe, 0x3622, 0x06); + sc500ai_write_register(ViPipe, 0x3630, 0x82); + sc500ai_write_register(ViPipe, 0x3633, 0x33); + sc500ai_write_register(ViPipe, 0x3634, 0x64); + sc500ai_write_register(ViPipe, 0x3637, 0x50); + sc500ai_write_register(ViPipe, 0x363a, 0x1f); + sc500ai_write_register(ViPipe, 0x363c, 0x40); + sc500ai_write_register(ViPipe, 0x3651, 0x7d); + sc500ai_write_register(ViPipe, 0x3670, 0x0a); + sc500ai_write_register(ViPipe, 0x3671, 0x06); + sc500ai_write_register(ViPipe, 0x3672, 0x16); + sc500ai_write_register(ViPipe, 0x3673, 0x17); + sc500ai_write_register(ViPipe, 0x3674, 0x82); + sc500ai_write_register(ViPipe, 0x3675, 0x62); + sc500ai_write_register(ViPipe, 0x3676, 0x44); + sc500ai_write_register(ViPipe, 0x367a, 0x48); + sc500ai_write_register(ViPipe, 0x367b, 0x78); + sc500ai_write_register(ViPipe, 0x367c, 0x48); + sc500ai_write_register(ViPipe, 0x367d, 0x58); + sc500ai_write_register(ViPipe, 0x3690, 0x34); + sc500ai_write_register(ViPipe, 0x3691, 0x34); + sc500ai_write_register(ViPipe, 0x3692, 0x54); + sc500ai_write_register(ViPipe, 0x369c, 0x48); + sc500ai_write_register(ViPipe, 0x369d, 0x78); + sc500ai_write_register(ViPipe, 0x36ea, 0x35); + sc500ai_write_register(ViPipe, 0x36eb, 0x04); + sc500ai_write_register(ViPipe, 0x36ec, 0x0a); + sc500ai_write_register(ViPipe, 0x36ed, 0x14); + sc500ai_write_register(ViPipe, 0x36fa, 0x35); + sc500ai_write_register(ViPipe, 0x36fb, 0x04); + sc500ai_write_register(ViPipe, 0x36fc, 0x00); + sc500ai_write_register(ViPipe, 0x36fd, 0x16); + sc500ai_write_register(ViPipe, 0x3904, 0x04); + sc500ai_write_register(ViPipe, 0x3908, 0x41); + sc500ai_write_register(ViPipe, 0x391f, 0x10); + sc500ai_write_register(ViPipe, 0x39c2, 0x30); + sc500ai_write_register(ViPipe, 0x3e00, 0x01); + sc500ai_write_register(ViPipe, 0x3e01, 0x82); + sc500ai_write_register(ViPipe, 0x3e02, 0x00); + sc500ai_write_register(ViPipe, 0x3e04, 0x18); + sc500ai_write_register(ViPipe, 0x3e05, 0x20); + sc500ai_write_register(ViPipe, 0x3e23, 0x00); + sc500ai_write_register(ViPipe, 0x3e24, 0xc6); + sc500ai_write_register(ViPipe, 0x4500, 0x88); + sc500ai_write_register(ViPipe, 0x4509, 0x20); + sc500ai_write_register(ViPipe, 0x4800, 0x04); + sc500ai_write_register(ViPipe, 0x4837, 0x15); + sc500ai_write_register(ViPipe, 0x4853, 0xfd); + sc500ai_write_register(ViPipe, 0x481b, 0x50); // hs-trail + sc500ai_write_register(ViPipe, 0x36e9, 0x44); + sc500ai_write_register(ViPipe, 0x36f9, 0x44); + sc500ai_write_register(ViPipe, 0x0100, 0x01); + sc500ai_init_ex(ViPipe); + + sc500ai_default_reg_init(ViPipe); + + sc500ai_write_register(ViPipe, 0x0100, 0x01); + + delay_ms(50); + + printf("===SC500AI sensor 1620P30fps 10bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} + +/* 1440P30 and 1440P25 */ +static void sc500ai_linear_1440p30_init(VI_PIPE ViPipe) +{ + sc500ai_write_register(ViPipe, 0x0103, 0x01); + sc500ai_write_register(ViPipe, 0x0100, 0x00); + sc500ai_write_register(ViPipe, 0x36e9, 0x80); + sc500ai_write_register(ViPipe, 0x36f9, 0x80); + sc500ai_write_register(ViPipe, 0x301f, 0x03); + sc500ai_write_register(ViPipe, 0x3200, 0x00); + sc500ai_write_register(ViPipe, 0x3201, 0xa0); + sc500ai_write_register(ViPipe, 0x3202, 0x00); + sc500ai_write_register(ViPipe, 0x3203, 0x5a); + sc500ai_write_register(ViPipe, 0x3204, 0x0a); + sc500ai_write_register(ViPipe, 0x3205, 0xa7); + sc500ai_write_register(ViPipe, 0x3206, 0x06); + sc500ai_write_register(ViPipe, 0x3207, 0x01); + sc500ai_write_register(ViPipe, 0x3208, 0x0a); + sc500ai_write_register(ViPipe, 0x3209, 0x00); + sc500ai_write_register(ViPipe, 0x320a, 0x05); + sc500ai_write_register(ViPipe, 0x320b, 0xa0); + sc500ai_write_register(ViPipe, 0x320c, 0x05); + sc500ai_write_register(ViPipe, 0x320d, 0x78); + sc500ai_write_register(ViPipe, 0x320e, 0x05); + sc500ai_write_register(ViPipe, 0x320f, 0xdc); + sc500ai_write_register(ViPipe, 0x3210, 0x00); + sc500ai_write_register(ViPipe, 0x3211, 0x04); + sc500ai_write_register(ViPipe, 0x3212, 0x00); + sc500ai_write_register(ViPipe, 0x3213, 0x04); + sc500ai_write_register(ViPipe, 0x3253, 0x0a); + sc500ai_write_register(ViPipe, 0x3301, 0x08); + sc500ai_write_register(ViPipe, 0x3302, 0x18); + sc500ai_write_register(ViPipe, 0x3303, 0x10); + sc500ai_write_register(ViPipe, 0x3304, 0x4c); + sc500ai_write_register(ViPipe, 0x3306, 0x44); + sc500ai_write_register(ViPipe, 0x3308, 0x10); + sc500ai_write_register(ViPipe, 0x3309, 0x58); + sc500ai_write_register(ViPipe, 0x330a, 0x00); + sc500ai_write_register(ViPipe, 0x330b, 0xd8); + sc500ai_write_register(ViPipe, 0x330d, 0x14); + sc500ai_write_register(ViPipe, 0x330e, 0x20); + sc500ai_write_register(ViPipe, 0x330f, 0x02); + sc500ai_write_register(ViPipe, 0x3310, 0x02); + sc500ai_write_register(ViPipe, 0x331c, 0x04); + sc500ai_write_register(ViPipe, 0x331e, 0x3d); + sc500ai_write_register(ViPipe, 0x331f, 0x49); + sc500ai_write_register(ViPipe, 0x3320, 0x09); + sc500ai_write_register(ViPipe, 0x3333, 0x10); + sc500ai_write_register(ViPipe, 0x334c, 0x08); + sc500ai_write_register(ViPipe, 0x3356, 0x09); + sc500ai_write_register(ViPipe, 0x3364, 0x17); + sc500ai_write_register(ViPipe, 0x336d, 0x03); + sc500ai_write_register(ViPipe, 0x3390, 0x08); + sc500ai_write_register(ViPipe, 0x3391, 0x18); + sc500ai_write_register(ViPipe, 0x3392, 0x38); + sc500ai_write_register(ViPipe, 0x3393, 0x08); + sc500ai_write_register(ViPipe, 0x3394, 0x20); + sc500ai_write_register(ViPipe, 0x3395, 0x20); + sc500ai_write_register(ViPipe, 0x3396, 0x08); + sc500ai_write_register(ViPipe, 0x3397, 0x18); + sc500ai_write_register(ViPipe, 0x3398, 0x38); + sc500ai_write_register(ViPipe, 0x3399, 0x08); + sc500ai_write_register(ViPipe, 0x339a, 0x20); + sc500ai_write_register(ViPipe, 0x339b, 0x20); + sc500ai_write_register(ViPipe, 0x339c, 0x20); + sc500ai_write_register(ViPipe, 0x33ac, 0x10); + sc500ai_write_register(ViPipe, 0x33ae, 0x10); + sc500ai_write_register(ViPipe, 0x33af, 0x19); + sc500ai_write_register(ViPipe, 0x360f, 0x01); + sc500ai_write_register(ViPipe, 0x3622, 0x03); + sc500ai_write_register(ViPipe, 0x363a, 0x1f); + sc500ai_write_register(ViPipe, 0x363c, 0x40); + sc500ai_write_register(ViPipe, 0x3651, 0x7d); + sc500ai_write_register(ViPipe, 0x3670, 0x0a); + sc500ai_write_register(ViPipe, 0x3671, 0x07); + sc500ai_write_register(ViPipe, 0x3672, 0x17); + sc500ai_write_register(ViPipe, 0x3673, 0x1e); + sc500ai_write_register(ViPipe, 0x3674, 0x82); + sc500ai_write_register(ViPipe, 0x3675, 0x64); + sc500ai_write_register(ViPipe, 0x3676, 0x66); + sc500ai_write_register(ViPipe, 0x367a, 0x48); + sc500ai_write_register(ViPipe, 0x367b, 0x78); + sc500ai_write_register(ViPipe, 0x367c, 0x58); + sc500ai_write_register(ViPipe, 0x367d, 0x78); + sc500ai_write_register(ViPipe, 0x3690, 0x34); + sc500ai_write_register(ViPipe, 0x3691, 0x34); + sc500ai_write_register(ViPipe, 0x3692, 0x54); + sc500ai_write_register(ViPipe, 0x369c, 0x48); + sc500ai_write_register(ViPipe, 0x369d, 0x78); + sc500ai_write_register(ViPipe, 0x36ea, 0x39); + sc500ai_write_register(ViPipe, 0x36eb, 0x0e); + sc500ai_write_register(ViPipe, 0x36ec, 0x1a); + sc500ai_write_register(ViPipe, 0x36ed, 0x34); + sc500ai_write_register(ViPipe, 0x36fa, 0x32); + sc500ai_write_register(ViPipe, 0x36fb, 0x0e); + sc500ai_write_register(ViPipe, 0x36fc, 0x10); + sc500ai_write_register(ViPipe, 0x36fd, 0x14); + sc500ai_write_register(ViPipe, 0x3904, 0x04); + sc500ai_write_register(ViPipe, 0x3908, 0x41); + sc500ai_write_register(ViPipe, 0x391d, 0x04); + sc500ai_write_register(ViPipe, 0x39c2, 0x30); + sc500ai_write_register(ViPipe, 0x3e01, 0xbb); + sc500ai_write_register(ViPipe, 0x3e02, 0x00); + sc500ai_write_register(ViPipe, 0x3e16, 0x00); + sc500ai_write_register(ViPipe, 0x3e17, 0x80); + sc500ai_write_register(ViPipe, 0x4500, 0x88); + sc500ai_write_register(ViPipe, 0x4509, 0x20); + sc500ai_write_register(ViPipe, 0x481b, 0x50); // hs-trail + sc500ai_write_register(ViPipe, 0x4837, 0x2a); + sc500ai_write_register(ViPipe, 0x5799, 0x00); + sc500ai_write_register(ViPipe, 0x59e0, 0x60); + sc500ai_write_register(ViPipe, 0x59e1, 0x08); + sc500ai_write_register(ViPipe, 0x59e2, 0x3f); + sc500ai_write_register(ViPipe, 0x59e3, 0x18); + sc500ai_write_register(ViPipe, 0x59e4, 0x18); + sc500ai_write_register(ViPipe, 0x59e5, 0x3f); + sc500ai_write_register(ViPipe, 0x59e7, 0x02); + sc500ai_write_register(ViPipe, 0x59e8, 0x38); + sc500ai_write_register(ViPipe, 0x59e9, 0x20); + sc500ai_write_register(ViPipe, 0x59ea, 0x0c); + sc500ai_write_register(ViPipe, 0x59ec, 0x08); + sc500ai_write_register(ViPipe, 0x59ed, 0x02); + sc500ai_write_register(ViPipe, 0x59ee, 0xa0); + sc500ai_write_register(ViPipe, 0x59ef, 0x08); + sc500ai_write_register(ViPipe, 0x59f4, 0x18); + sc500ai_write_register(ViPipe, 0x59f5, 0x10); + sc500ai_write_register(ViPipe, 0x59f6, 0x0c); + sc500ai_write_register(ViPipe, 0x59f9, 0x02); + sc500ai_write_register(ViPipe, 0x59fa, 0x18); + sc500ai_write_register(ViPipe, 0x59fb, 0x10); + sc500ai_write_register(ViPipe, 0x59fc, 0x0c); + sc500ai_write_register(ViPipe, 0x59ff, 0x02); + sc500ai_write_register(ViPipe, 0x36e9, 0x44); + sc500ai_write_register(ViPipe, 0x36f9, 0x44); + sc500ai_init_ex(ViPipe); + + sc500ai_default_reg_init(ViPipe); + + sc500ai_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC500AI 1440P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +static void sc500ai_wdr_1440p30_2to1_init(VI_PIPE ViPipe) +{ + sc500ai_write_register(ViPipe, 0x0103, 0x01); + sc500ai_write_register(ViPipe, 0x0100, 0x00); + sc500ai_write_register(ViPipe, 0x36e9, 0x80); + sc500ai_write_register(ViPipe, 0x36f9, 0x80); + sc500ai_write_register(ViPipe, 0x301f, 0x12); + sc500ai_write_register(ViPipe, 0x3106, 0x01); + sc500ai_write_register(ViPipe, 0x3200, 0x00); + sc500ai_write_register(ViPipe, 0x3201, 0xa0); + sc500ai_write_register(ViPipe, 0x3202, 0x00); + sc500ai_write_register(ViPipe, 0x3203, 0x5a); + sc500ai_write_register(ViPipe, 0x3204, 0x0a); + sc500ai_write_register(ViPipe, 0x3205, 0xa7); + sc500ai_write_register(ViPipe, 0x3206, 0x06); + sc500ai_write_register(ViPipe, 0x3207, 0x01); + sc500ai_write_register(ViPipe, 0x3208, 0x0a); + sc500ai_write_register(ViPipe, 0x3209, 0x00); + sc500ai_write_register(ViPipe, 0x320a, 0x05); + sc500ai_write_register(ViPipe, 0x320b, 0xa0); + sc500ai_write_register(ViPipe, 0x320c, 0x05); + sc500ai_write_register(ViPipe, 0x320d, 0xdc); + sc500ai_write_register(ViPipe, 0x320e, 0x0b); + sc500ai_write_register(ViPipe, 0x320f, 0xb8); + sc500ai_write_register(ViPipe, 0x3210, 0x00); + sc500ai_write_register(ViPipe, 0x3211, 0x04); + sc500ai_write_register(ViPipe, 0x3212, 0x00); + sc500ai_write_register(ViPipe, 0x3213, 0x04); + sc500ai_write_register(ViPipe, 0x3220, 0x53); + sc500ai_write_register(ViPipe, 0x3250, 0xff); + sc500ai_write_register(ViPipe, 0x3253, 0x0a); + sc500ai_write_register(ViPipe, 0x3301, 0x0b); + sc500ai_write_register(ViPipe, 0x3302, 0x20); + sc500ai_write_register(ViPipe, 0x3303, 0x10); + sc500ai_write_register(ViPipe, 0x3304, 0x60); + sc500ai_write_register(ViPipe, 0x3306, 0x40); + sc500ai_write_register(ViPipe, 0x3308, 0x18); + sc500ai_write_register(ViPipe, 0x3309, 0x80); + sc500ai_write_register(ViPipe, 0x330a, 0x01); + sc500ai_write_register(ViPipe, 0x330b, 0x04); + sc500ai_write_register(ViPipe, 0x330d, 0x28); + sc500ai_write_register(ViPipe, 0x330e, 0x30); + sc500ai_write_register(ViPipe, 0x330f, 0x02); + sc500ai_write_register(ViPipe, 0x3310, 0x02); + sc500ai_write_register(ViPipe, 0x331c, 0x08); + sc500ai_write_register(ViPipe, 0x331e, 0x51); + sc500ai_write_register(ViPipe, 0x331f, 0x71); + sc500ai_write_register(ViPipe, 0x3320, 0x11); + sc500ai_write_register(ViPipe, 0x3333, 0x10); + sc500ai_write_register(ViPipe, 0x334c, 0x10); + sc500ai_write_register(ViPipe, 0x3356, 0x11); + sc500ai_write_register(ViPipe, 0x3364, 0x17); + sc500ai_write_register(ViPipe, 0x336d, 0x03); + sc500ai_write_register(ViPipe, 0x3390, 0x08); + sc500ai_write_register(ViPipe, 0x3391, 0x18); + sc500ai_write_register(ViPipe, 0x3392, 0x38); + sc500ai_write_register(ViPipe, 0x3393, 0x0a); + sc500ai_write_register(ViPipe, 0x3394, 0x0a); + sc500ai_write_register(ViPipe, 0x3395, 0x12); + sc500ai_write_register(ViPipe, 0x3396, 0x08); + sc500ai_write_register(ViPipe, 0x3397, 0x18); + sc500ai_write_register(ViPipe, 0x3398, 0x38); + sc500ai_write_register(ViPipe, 0x3399, 0x0a); + sc500ai_write_register(ViPipe, 0x339a, 0x0a); + sc500ai_write_register(ViPipe, 0x339b, 0x0a); + sc500ai_write_register(ViPipe, 0x339c, 0x12); + sc500ai_write_register(ViPipe, 0x33ac, 0x10); + sc500ai_write_register(ViPipe, 0x33ae, 0x20); + sc500ai_write_register(ViPipe, 0x33af, 0x21); + sc500ai_write_register(ViPipe, 0x360f, 0x01); + sc500ai_write_register(ViPipe, 0x3621, 0xe8); + sc500ai_write_register(ViPipe, 0x3622, 0x06); + sc500ai_write_register(ViPipe, 0x3630, 0x82); + sc500ai_write_register(ViPipe, 0x3633, 0x33); + sc500ai_write_register(ViPipe, 0x3634, 0x64); + sc500ai_write_register(ViPipe, 0x3637, 0x50); + sc500ai_write_register(ViPipe, 0x363a, 0x1f); + sc500ai_write_register(ViPipe, 0x363c, 0x40); + sc500ai_write_register(ViPipe, 0x3651, 0x7d); + sc500ai_write_register(ViPipe, 0x3670, 0x0a); + sc500ai_write_register(ViPipe, 0x3671, 0x06); + sc500ai_write_register(ViPipe, 0x3672, 0x16); + sc500ai_write_register(ViPipe, 0x3673, 0x17); + sc500ai_write_register(ViPipe, 0x3674, 0x82); + sc500ai_write_register(ViPipe, 0x3675, 0x62); + sc500ai_write_register(ViPipe, 0x3676, 0x44); + sc500ai_write_register(ViPipe, 0x367a, 0x48); + sc500ai_write_register(ViPipe, 0x367b, 0x78); + sc500ai_write_register(ViPipe, 0x367c, 0x48); + sc500ai_write_register(ViPipe, 0x367d, 0x58); + sc500ai_write_register(ViPipe, 0x3690, 0x34); + sc500ai_write_register(ViPipe, 0x3691, 0x34); + sc500ai_write_register(ViPipe, 0x3692, 0x54); + sc500ai_write_register(ViPipe, 0x369c, 0x48); + sc500ai_write_register(ViPipe, 0x369d, 0x78); + sc500ai_write_register(ViPipe, 0x36ea, 0x31); + sc500ai_write_register(ViPipe, 0x36eb, 0x04); + sc500ai_write_register(ViPipe, 0x36ec, 0x0a); + sc500ai_write_register(ViPipe, 0x36ed, 0x24); + sc500ai_write_register(ViPipe, 0x36fa, 0x31); + sc500ai_write_register(ViPipe, 0x36fb, 0x04); + sc500ai_write_register(ViPipe, 0x36fc, 0x00); + sc500ai_write_register(ViPipe, 0x36fd, 0x26); + sc500ai_write_register(ViPipe, 0x3904, 0x04); + sc500ai_write_register(ViPipe, 0x3908, 0x41); + sc500ai_write_register(ViPipe, 0x391f, 0x10); + sc500ai_write_register(ViPipe, 0x39c2, 0x30); + sc500ai_write_register(ViPipe, 0x3e00, 0x01); + sc500ai_write_register(ViPipe, 0x3e01, 0x5e); + sc500ai_write_register(ViPipe, 0x3e02, 0x00); + sc500ai_write_register(ViPipe, 0x3e04, 0x15); + sc500ai_write_register(ViPipe, 0x3e05, 0xe0); + sc500ai_write_register(ViPipe, 0x3e23, 0x00); + sc500ai_write_register(ViPipe, 0x3e24, 0xb4); + sc500ai_write_register(ViPipe, 0x4500, 0x88); + sc500ai_write_register(ViPipe, 0x4509, 0x20); + sc500ai_write_register(ViPipe, 0x4800, 0x24); + sc500ai_write_register(ViPipe, 0x4837, 0x18); + sc500ai_write_register(ViPipe, 0x4853, 0xfd); + sc500ai_write_register(ViPipe, 0x481b, 0x50); // hs-trail + sc500ai_write_register(ViPipe, 0x36e9, 0x40); + sc500ai_write_register(ViPipe, 0x36f9, 0x40); + sc500ai_init_ex(ViPipe); + + sc500ai_default_reg_init(ViPipe); + + sc500ai_write_register(ViPipe, 0x0100, 0x01); + + delay_ms(50); + + printf("===SC500AI sensor 1440P30fps 10bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc501ai_2L/Makefile b/middleware/v2/component/isp/sensor/cv180x/sms_sc501ai_2L/Makefile new file mode 100644 index 000000000..1bb770b2a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc501ai_2L/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc501ai_2l.a +TARGET_SO = $(MW_LIB)/libsns_sc501ai_2l.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc501ai_2L/sc501ai_2L_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc501ai_2L/sc501ai_2L_cmos.c new file mode 100644 index 000000000..3a9471c9a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc501ai_2L/sc501ai_2L_cmos.c @@ -0,0 +1,1033 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc501ai_2L_cmos_ex.h" +#include "sc501ai_2L_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC501AI_2L_ID 500 +#define SENSOR_SC501AI_2L_WIDTH 2880 +#define SENSOR_SC501AI_2L_HEIGHT 1620 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC501AI_2L[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC501AI_2L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC501AI_2L[dev]) +#define SC501AI_2L_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC501AI_2L[dev] = pstCtx) +#define SC501AI_2L_SENSOR_RESET_CTX(dev) (g_pastSC501AI_2L[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC501AI_2L_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC501AI_2L_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC501AI_2L_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC501AI_2L_STATE_S g_astSC501AI_2L_State[VI_MAX_PIPE_NUM] = {{0} }; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC501AI_2L Lines Range*****/ +#define SC501AI_2L_FULL_LINES_MAX (0x7FFF) + +/*****SC501AI_2L Register Address*****/ +#define SC501AI_2L_SHS1_0_ADDR 0x3E00 +#define SC501AI_2L_SHS1_1_ADDR 0x3E01 +#define SC501AI_2L_SHS1_2_ADDR 0x3E02 +#define SC501AI_2L_AGAIN1_ADDR 0x3E08 +#define SC501AI_2L_DGAIN1_ADDR 0x3E06 +#define SC501AI_2L_VMAX_ADDR 0x320E +#define SC501AI_2L_TABLE_END 0xFFFF + +#define SC501AI_2L_RES_IS_1620P(w, h) ((w) <= 2880 && (h) <= 1620) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC501AI_2L_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 0.5; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astSC501AI_2L_mode[SC501AI_2L_MODE_1620P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC501AI_2L_mode[SC501AI_2L_MODE_1620P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = g_astSC501AI_2L_mode[SC501AI_2L_MODE_1620P30].stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = g_astSC501AI_2L_mode[SC501AI_2L_MODE_1620P30].stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astSC501AI_2L_mode[SC501AI_2L_MODE_1620P30].stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = g_astSC501AI_2L_mode[SC501AI_2L_MODE_1620P30].stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = 2 * (pstSnsState->u32FLStd - 5); + pstAeSnsDft->u32MinIntTime = 3; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + case WDR_MODE_2To1_LINE: + break; + } + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC501AI_2L_MODE_1620P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC501AI_2L_FULL_LINES_MAX) ? SC501AI_2L_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = 2 * (pstSnsState->u32FLStd - 5); + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + CVI_U32 u32TmpIntTime = u32IntTime[0]; + CVI_U32 maxExp = 2 * pstSnsState->au32FL[0] - 10; + + /* linear exposure reg range: + * min : 3 + * max : 2 * vts - 10 + * step : 1 + */ + u32TmpIntTime = (u32TmpIntTime > maxExp) ? maxExp : u32TmpIntTime; + if (u32TmpIntTime < 3) + u32TmpIntTime = 3; + u32IntTime[0] = u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = (u32TmpIntTime & 0xF) << 4; + + return CVI_SUCCESS; + +} + +struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +}; + +static struct gain_tbl_info_s AgainInfo[5] = { + { + .gainMax = 1536, + .idxBase = 0, + .regGain = 0x03, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 3080, + .idxBase = 33, + .regGain = 0x23, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 6161, + .idxBase = 97, + .regGain = 0x27, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 12321, + .idxBase = 161, + .regGain = 0x2F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 24644, + .idxBase = 225, + .regGain = 0x3F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, +}; + +static CVI_U32 Again_table[289] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, + 1248, 1263, 1280, 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, + 1472, 1487, 1504, 1519, 1536, 1552, 1576, 1600, 1625, 1649, 1673, 1697, 1722, 1746, + 1770, 1795, 1819, 1843, 1867, 1892, 1915, 1940, 1965, 1988, 2013, 2037, 2061, 2085, + 2110, 2135, 2158, 2183, 2207, 2231, 2255, 2280, 2304, 2328, 2353, 2376, 2401, 2425, + 2449, 2473, 2498, 2523, 2546, 2571, 2595, 2619, 2643, 2668, 2692, 2716, 2741, 2764, + 2789, 2813, 2837, 2862, 2886, 2911, 2934, 2959, 2983, 3007, 3032, 3056, 3080, 3104, + 3152, 3202, 3250, 3299, 3347, 3395, 3444, 3492, 3540, 3590, 3638, 3687, 3735, 3783, + 3832, 3880, 3929, 3978, 4026, 4075, 4123, 4171, 4220, 4269, 4317, 4366, 4414, 4463, + 4511, 4559, 4609, 4657, 4705, 4754, 4802, 4851, 4899, 4947, 4997, 5045, 5093, 5142, + 5190, 5239, 5287, 5336, 5385, 5433, 5481, 5530, 5578, 5627, 5676, 5724, 5773, 5821, + 5869, 5918, 5966, 6016, 6064, 6112, 6161, 6209, 6306, 6404, 6500, 6597, 6694, 6792, + 6888, 6985, 7083, 7180, 7276, 7373, 7471, 7568, 7664, 7761, 7859, 7956, 8052, 8150, + 8247, 8344, 8440, 8538, 8635, 8732, 8828, 8926, 9023, 9120, 9217, 9314, 9411, 9508, + 9605, 9702, 9799, 9896, 9993, 10090, 10187, 10285, 10381, 10478, 10575, 10673, 10769, + 10866, 10963, 11061, 11157, 11254, 11352, 11449, 11545, 11642, 11740, 11837, 11933, + 12030, 12128, 12225, 12321, 12419, 12613, 12807, 13001, 13195, 13389, 13583, 13777, + 13971, 14166, 14359, 14554, 14747, 14942, 15135, 15330, 15523, 15718, 15911, 16106, + 16300, 16494, 16688, 16882, 17076, 17270, 17464, 17658, 17852, 18046, 18240, 18435, + 18628, 18823, 19016, 19211, 19404, 19599, 19792, 19987, 20180, 20375, 20569, 20763, + 20957, 21151, 21345, 21539, 21733, 21927, 22121, 22316, 22509, 22704, 22897, 23092, + 23285, 23480, 23673, 23868, 24061, 24256, 24450, 24644, +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[288]) { + *pu32AgainLin = Again_table[288]; + *pu32AgainDb = 288; + return CVI_SUCCESS; + } + + for (i = 1; i < 289; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 dgain = *pu32DgainLin; + CVI_U32 dgainBase; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + + /* range check */ + if (dgain > g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max) { + *pu32DgainLin = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + *pu32DgainDb = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + return CVI_SUCCESS; + } + if (dgain < 1024) { + *pu32DgainLin = 1024; + *pu32DgainDb = 1024; + return CVI_SUCCESS; + } + /* find the base then use 1/128 as step */ + if (dgain < 2048) + dgainBase = 1024; + else if (dgain < 4096) + dgainBase = 2048; + else if (dgain < 8192) + dgainBase = 4096; + else if (dgain < 16384) + dgainBase = 8192; + else + dgainBase = 16384; + dgain = dgain * 128 / dgainBase; + *pu32DgainLin = dgainBase * dgain / 128; + *pu32DgainDb = *pu32DgainLin; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + CVI_U32 dgainReg; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + static bool bGainLogicChanged[VI_MAX_PIPE_NUM] = {true}; + CVI_U32 dgainBase; + + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + // control sensor DPC to fix high-gain noise + if (Again_table[u32Again] >= 30720 && bGainLogicChanged[ViPipe]) { + sc501ai_2l_write_register(ViPipe, 0x5799, 0x7); + bGainLogicChanged[ViPipe] = false; + } else if (Again_table[u32Again] <= 20480 && !bGainLogicChanged[ViPipe]) { + sc501ai_2l_write_register(ViPipe, 0x5799, 0x0); + bGainLogicChanged[ViPipe] = true; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + if (u32Dgain > g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max) + u32Dgain = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + if (u32Dgain < 1024) + u32Dgain = 1024; + /* find the base then use 1/128 as step */ + if (u32Dgain < 2048) { + dgainBase = 1024; + dgainReg = 0x0; + } else if (u32Dgain < 4096) { + dgainBase = 2048; + dgainReg = 0x1; + } else if (u32Dgain < 8192) { + dgainBase = 4096; + dgainReg = 0x3; + } else if (u32Dgain < 16384) { + dgainBase = 8192; + dgainReg = 0x7; + } else { + dgainBase = 16384; + dgainReg = 0xf; + } + u32Dgain = u32Dgain * 128 / dgainBase; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0_ADDR].u32Data = (dgainReg & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1_ADDR].u32Data = (u32Dgain & 0xFF); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0; + CVI_U32 u32ShortTimeMinLimit = 5; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32MaxSexp = 2 * g_astSC501AI_2L_State[ViPipe].u32Sexp_MAX - 14; + + (void) u16ManRatioEnable; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + /* short exposure reg range: + * min : 5 + * max : 2 * (max sexp - 7) + * step : 4 + * long exposure reg range: + * min : 5 + * max : 2 * (vts - max sexp - 9) + * step : 4 + */ + u32IntTimeMaxTmp = ((2 * pstSnsState->au32FL[0] - 16) * 0x40) / (au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32MaxSexp) ? u32MaxSexp : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp < u32ShortTimeMinLimit) ? u32ShortTimeMinLimit : u32IntTimeMaxTmp; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + syslog(LOG_DEBUG, "ViPipe = %d ratio = %d, (%d, %d)\n", ViPipe, au32Ratio[0], + u32IntTimeMaxTmp, u32ShortTimeMinLimit); + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC501AI_2L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC501AI_2L_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + + case WDR_MODE_2To1_LINE: + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC501AI_2L_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc501ai_2l_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc501ai_2l_addr_byte; + pstI2c_data[i].u32DataByteNum = sc501ai_2l_data_byte; + } + + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC501AI_2L_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC501AI_2L_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC501AI_2L_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC501AI_2L_AGAIN1_ADDR; + pstI2c_data[LINEAR_AGAIN_1_ADDR].u32RegAddr = SC501AI_2L_AGAIN1_ADDR + 1; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC501AI_2L_DGAIN1_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC501AI_2L_DGAIN1_ADDR + 1; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC501AI_2L_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC501AI_2L_VMAX_ADDR + 1; + + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC501AI_2L_RES_IS_1620P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC501AI_2L_MODE_1620P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC501AI_2L_MODE_S *pstMode = CVI_NULL; + + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC501AI_2L_MODE_1620P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC501AI_2L_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc501ai_2l_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc501ai_2l_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc501ai_2l_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc501ai_2l_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc501ai_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC501AI_2L_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC501AI_2L_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC501AI_2L_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC501AI_2L_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC501AI_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC501AI_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC501AI_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC501AI_2L_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC501AI_2L_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC501AI_2L_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc501ai_2l_standby, + .pfnRestart = sc501ai_2l_restart, + .pfnMirrorFlip = sc501ai_2l_mirror_flip, + .pfnWriteReg = sc501ai_2l_write_register, + .pfnReadReg = sc501ai_2l_read_register, + .pfnSetBusInfo = sc501ai_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc501ai_2l_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc501ai_2L/sc501ai_2L_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc501ai_2L/sc501ai_2L_cmos_ex.h new file mode 100644 index 000000000..57cb54b61 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc501ai_2L/sc501ai_2L_cmos_ex.h @@ -0,0 +1,85 @@ +#ifndef __SC501AI_2L_CMOS_EX_H_ +#define __SC501AI_2L_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc501ai_2l_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_2_ADDR, + LINEAR_AGAIN_0_ADDR, + LINEAR_AGAIN_1_ADDR, + LINEAR_DGAIN_0_ADDR, + LINEAR_DGAIN_1_ADDR, + LINEAR_VMAX_0_ADDR, + LINEAR_VMAX_1_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC501AI_2L_MODE_E { + SC501AI_2L_MODE_1620P30 = 0, + SC501AI_2L_MODE_LINEAR_NUM, + SC501AI_2L_MODE_NUM +} SC501AI_2L_MODE_E; + +typedef struct _SC501AI_2L_STATE_S { + CVI_U32 u32Sexp_MAX; /* (2*{16’h3e23,16’h3e24} – 'd10)/2 */ +} SC501AI_2L_STATE_S; + +typedef struct _SC501AI_2L_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + CVI_U16 u16SexpMaxReg; /* {16’h3e23,16’h3e24} */ + char name[64]; +} SC501AI_2L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC501AI_2L[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC501AI_2L_BusInfo[]; +extern CVI_U16 g_au16SC501AI_2L_GainMode[]; +extern CVI_U16 g_au16SC501AI_2L_L2SMode[]; +extern const CVI_U8 sc501ai_2l_i2c_addr; +extern const CVI_U32 sc501ai_2l_addr_byte; +extern const CVI_U32 sc501ai_2l_data_byte; +extern void sc501ai_2l_init(VI_PIPE ViPipe); +extern void sc501ai_2l_exit(VI_PIPE ViPipe); +extern void sc501ai_2l_standby(VI_PIPE ViPipe); +extern void sc501ai_2l_restart(VI_PIPE ViPipe); +extern int sc501ai_2l_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc501ai_2l_read_register(VI_PIPE ViPipe, int addr); +extern void sc501ai_2l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc501ai_2l_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC501AI_2L_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc501ai_2L/sc501ai_2L_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc501ai_2L/sc501ai_2L_cmos_param.h new file mode 100644 index 000000000..1527a6fcc --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc501ai_2L/sc501ai_2L_cmos_param.h @@ -0,0 +1,225 @@ +#ifndef __SC501AI_2L_CMOS_PARAM_H_ +#define __SC501AI_2L_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc501ai_2L_cmos_ex.h" + +static const SC501AI_2L_MODE_S g_astSC501AI_2L_mode[SC501AI_2L_MODE_NUM] = { + [SC501AI_2L_MODE_1620P30] = { + .name = "1620p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2880, + .u32Height = 1620, + }, + .stMaxSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.52, /* 1650 * 30 / 0x7FFF*/ + .u32HtsDef = 2560, /* NA */ + .u32VtsDef = 1650, + .stExp[0] = { + .u16Min = 3, + .u16Max = 3290, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 24644, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 32640, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.02792946062982082367, 3.36534714698791503906}, //B: slope, intercept + {0.02071751467883586884, 5.34583568572998046875}, //Gb: slope, intercept + {0.02110148966312408447, 5.02954530715942382813}, //Gr: slope, intercept + {0.02168512716889381409, 4.89776754379272460938}, //R: slope, intercept + }, + { //iso 200 + {0.03194080293178558350, 5.61192893981933593750}, //B: slope, intercept + {0.02428408525884151459, 7.94834280014038085938}, //Gb: slope, intercept + {0.02499442733824253082, 7.72430133819580078125}, //Gr: slope, intercept + {0.02584112435579299927, 7.20574426651000976563}, //R: slope, intercept + }, + { //iso 400 + {0.04612467437982559204, 6.88752269744873046875}, //B: slope, intercept + {0.03022909909486770630, 11.05101776123046875000}, //Gb: slope, intercept + {0.03175539523363113403, 10.60332489013671875000}, //Gr: slope, intercept + {0.03522306308150291443, 9.36425399780273437500}, //R: slope, intercept + }, + { //iso 800 + {0.06092500314116477966, 9.79670524597167968750}, //B: slope, intercept + {0.03984217345714569092, 15.30182266235351562500}, //Gb: slope, intercept + {0.04019560664892196655, 14.93132972717285156250}, //Gr: slope, intercept + {0.04470816254615783691, 13.26843166351318359375}, //R: slope, intercept + }, + { //iso 1600 + {0.08295634388923645020, 14.20334625244140625000}, //B: slope, intercept + {0.05075264349579811096, 20.99221038818359375000}, //Gb: slope, intercept + {0.05426201224327087402, 20.08068656921386718750}, //Gr: slope, intercept + {0.05945669487118721008, 19.02898788452148437500}, //R: slope, intercept + }, + { //iso 3200 + {0.09782519936561584473, 21.84967994689941406250}, //B: slope, intercept + {0.06690908223390579224, 26.53993988037109375000}, //Gb: slope, intercept + {0.06954573839902877808, 25.74129104614257812500}, //Gr: slope, intercept + {0.09061723947525024414, 22.98998260498046875000}, //R: slope, intercept + }, + { //iso 6400 + {0.14311420917510986328, 28.96467971801757812500}, //B: slope, intercept + {0.08148498833179473877, 37.93062591552734375000}, //Gb: slope, intercept + {0.08273542672395706177, 38.37096405029296875000}, //Gr: slope, intercept + {0.12093253433704376221, 33.31475067138671875000}, //R: slope, intercept + }, + { //iso 12800 + {0.17958122491836547852, 43.49506759643554687500}, //B: slope, intercept + {0.09839969873428344727, 55.43268966674804687500}, //Gb: slope, intercept + {0.10201884806156158447, 52.97607040405273437500}, //Gr: slope, intercept + {0.15302789211273193359, 47.54779434204101562500}, //R: slope, intercept + }, + { //iso 25600 + {0.25833165645599365234, 56.96470642089843750000}, //B: slope, intercept + {0.13260601460933685303, 74.69016265869140625000}, //Gb: slope, intercept + {0.14035490155220031738, 75.44366455078125000000}, //Gr: slope, intercept + {0.23465165495872497559, 60.52228164672851562500}, //R: slope, intercept + }, + { //iso 51200 + {0.37595292925834655762, 78.54853057861328125000}, //B: slope, intercept + {0.21475413441658020020, 102.12300872802734375000}, //Gb: slope, intercept + {0.20840260386466979980, 103.65763854980468750000}, //Gr: slope, intercept + {0.34428051114082336426, 87.83551025390625000000}, //R: slope, intercept + }, + { //iso 102400 + {0.51122575998306274414, 113.49224090576171875000}, //B: slope, intercept + {0.29245173931121826172, 154.26939392089843750000}, //Gb: slope, intercept + {0.31501635909080505371, 148.29017639160156250000}, //Gr: slope, intercept + {0.47034618258476257324, 124.06208038330078125000}, //R: slope, intercept + }, + { //iso 204800 + {0.67213481664657592773, 134.71751403808593750000}, //B: slope, intercept + {0.40368056297302246094, 189.80801391601562500000}, //Gb: slope, intercept + {0.43581819534301757813, 186.44682312011718750000}, //Gr: slope, intercept + {0.60127359628677368164, 160.66384887695312500000}, //R: slope, intercept + }, + { //iso 409600 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 819200 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {257, 260, 260, 260, 260, 261, 259, 258, /*8*/255, 248, 264, 300, 291, 310, 310, 311}, + {257, 260, 260, 260, 260, 261, 259, 257, /*8*/254, 247, 261, 296, 287, 309, 309, 306}, + {257, 260, 260, 260, 260, 261, 259, 257, /*8*/255, 248, 262, 298, 289, 308, 308, 308}, + {257, 260, 260, 260, 260, 261, 259, 258, /*8*/255, 247, 261, 301, 293, 310, 308, 314}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1095, 1105, 1102, 1108, 1108, 1108}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1104, 1101, 1108, 1108, 1107}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1104, 1102, 1107, 1107, 1107}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1105, 1103, 1108, 1107, 1109}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc501ai_2l_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {1, 2, 0, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + .dphy = { + .enable = 1, + .hs_settle = 14, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC501AI_2L_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc501ai_2L/sc501ai_2L_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc501ai_2L/sc501ai_2L_sensor_ctl.c new file mode 100644 index 000000000..fc7a232cf --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc501ai_2L/sc501ai_2L_sensor_ctl.c @@ -0,0 +1,425 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc501ai_2L_cmos_ex.h" + +static void sc501ai_2l_linear_1620p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc501ai_2l_i2c_addr = 0x30; /* I2C Address of SC501AI_2L */ +const CVI_U32 sc501ai_2l_addr_byte = 2; +const CVI_U32 sc501ai_2l_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc501ai_2l_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC501AI_2L_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc501ai_2l_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc501ai_2l_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc501ai_2l_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc501ai_2l_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc501ai_2l_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc501ai_2l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc501ai_2l_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc501ai_2l_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc501ai_2l_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc501ai_2l_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc501ai_2l_addr_byte + sc501ai_2l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc501ai_2l_standby(VI_PIPE ViPipe) +{ + sc501ai_2l_write_register(ViPipe, 0x0100, 0x00); +} + +void sc501ai_2l_restart(VI_PIPE ViPipe) +{ + sc501ai_2l_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc501ai_2l_write_register(ViPipe, 0x0100, 0x01); +} + +void sc501ai_2l_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC501AI_2L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc501ai_2l_write_register(ViPipe, + g_pastSC501AI_2L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC501AI_2L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC501AI_2L_CHIP_ID_HI_ADDR 0x3107 +#define SC501AI_2L_CHIP_ID_LO_ADDR 0x3108 +#define SC501AI_2L_CHIP_ID 0xce1f + +void sc501ai_2l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc501ai_2l_write_register(ViPipe, 0x3221, val); +} + +static int sc501ai_2l_init_ex(VI_PIPE ViPipe) +{ + CVI_U32 debounce = 0; + int nVal, cnt = 0; + CVI_U16 tmp = 0, tmpPrev = 0; + + while (debounce++ < 5) { + nVal = sc501ai_2l_read_register(ViPipe, 0x3109); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "debounce read fail.\n"); + return nVal; + } + tmp = (nVal & 0xFF) << 8; + if (tmp != tmpPrev) + debounce = 0; + tmpPrev = tmp; + if (cnt++ > 20) { + CVI_TRACE_SNS(CVI_DBG_ERR, "debounce fail.\n"); + return nVal; + } + } + if (tmp == 1) { + sc501ai_2l_write_register(ViPipe, 0x336d, 0x23); + } else { + sc501ai_2l_write_register(ViPipe, 0x336d, 0x03); + } + + debounce = 0; + cnt = 0; + while (debounce++ < 5) { + nVal = sc501ai_2l_read_register(ViPipe, 0x3040); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "debounce read fail.\n"); + return nVal; + } + tmp = (nVal & 0xFF) << 8; + if (tmp != tmpPrev) + debounce = 0; + tmpPrev = tmp; + if (cnt++ > 20) { + CVI_TRACE_SNS(CVI_DBG_ERR, "debounce fail.\n"); + return nVal; + } + } + if (tmp == 0) { + sc501ai_2l_write_register(ViPipe, 0x363c, 0x42); + } else { + sc501ai_2l_write_register(ViPipe, 0x363c, 0x40); + } + + return CVI_SUCCESS; +} + +int sc501ai_2l_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + delay_ms(4); + if (sc501ai_2l_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc501ai_2l_read_register(ViPipe, SC501AI_2L_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc501ai_2l_read_register(ViPipe, SC501AI_2L_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC501AI_2L_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc501ai_2l_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + + bInit = g_pastSC501AI_2L[ViPipe]->bInit; + enWDRMode = g_pastSC501AI_2L[ViPipe]->enWDRMode; + + sc501ai_2l_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_2To1_LINE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n"); + } else { + sc501ai_2l_linear_1620p30_init(ViPipe); + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_2To1_LINE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n"); + } else { + sc501ai_2l_linear_1620p30_init(ViPipe); + } + } + g_pastSC501AI_2L[ViPipe]->bInit = CVI_TRUE; +} + +void sc501ai_2l_exit(VI_PIPE ViPipe) +{ + sc501ai_2l_i2c_exit(ViPipe); +} + +/* 1620P30 and 1620P25 */ +static void sc501ai_2l_linear_1620p30_init(VI_PIPE ViPipe) +{ + sc501ai_2l_write_register(ViPipe, 0x0103, 0x01); + sc501ai_2l_write_register(ViPipe, 0x0100, 0x00); + sc501ai_2l_write_register(ViPipe, 0x36e9, 0x80); + sc501ai_2l_write_register(ViPipe, 0x36f9, 0x80); + sc501ai_2l_write_register(ViPipe, 0x3018, 0x32); + sc501ai_2l_write_register(ViPipe, 0x3019, 0x0c); + sc501ai_2l_write_register(ViPipe, 0x301f, 0x0b); + sc501ai_2l_write_register(ViPipe, 0x3253, 0x0a); + sc501ai_2l_write_register(ViPipe, 0x3301, 0x0a); + sc501ai_2l_write_register(ViPipe, 0x3302, 0x18); + sc501ai_2l_write_register(ViPipe, 0x3303, 0x10); + sc501ai_2l_write_register(ViPipe, 0x3304, 0x60); + sc501ai_2l_write_register(ViPipe, 0x3306, 0x60); + sc501ai_2l_write_register(ViPipe, 0x3308, 0x10); + sc501ai_2l_write_register(ViPipe, 0x3309, 0x70); + sc501ai_2l_write_register(ViPipe, 0x330a, 0x00); + sc501ai_2l_write_register(ViPipe, 0x330b, 0xf0); + sc501ai_2l_write_register(ViPipe, 0x330d, 0x18); + sc501ai_2l_write_register(ViPipe, 0x330e, 0x20); + sc501ai_2l_write_register(ViPipe, 0x330f, 0x02); + sc501ai_2l_write_register(ViPipe, 0x3310, 0x02); + sc501ai_2l_write_register(ViPipe, 0x331c, 0x04); + sc501ai_2l_write_register(ViPipe, 0x331e, 0x51); + sc501ai_2l_write_register(ViPipe, 0x331f, 0x61); + sc501ai_2l_write_register(ViPipe, 0x3320, 0x09); + sc501ai_2l_write_register(ViPipe, 0x3333, 0x10); + sc501ai_2l_write_register(ViPipe, 0x334c, 0x08); + sc501ai_2l_write_register(ViPipe, 0x3356, 0x09); + sc501ai_2l_write_register(ViPipe, 0x3364, 0x17); + sc501ai_2l_write_register(ViPipe, 0x336d, 0x03); + sc501ai_2l_write_register(ViPipe, 0x3390, 0x08); + sc501ai_2l_write_register(ViPipe, 0x3391, 0x18); + sc501ai_2l_write_register(ViPipe, 0x3392, 0x38); + sc501ai_2l_write_register(ViPipe, 0x3393, 0x0a); + sc501ai_2l_write_register(ViPipe, 0x3394, 0x20); + sc501ai_2l_write_register(ViPipe, 0x3395, 0x20); + sc501ai_2l_write_register(ViPipe, 0x3396, 0x08); + sc501ai_2l_write_register(ViPipe, 0x3397, 0x18); + sc501ai_2l_write_register(ViPipe, 0x3398, 0x38); + sc501ai_2l_write_register(ViPipe, 0x3399, 0x0a); + sc501ai_2l_write_register(ViPipe, 0x339a, 0x20); + sc501ai_2l_write_register(ViPipe, 0x339b, 0x20); + sc501ai_2l_write_register(ViPipe, 0x339c, 0x20); + sc501ai_2l_write_register(ViPipe, 0x33ac, 0x10); + sc501ai_2l_write_register(ViPipe, 0x33ae, 0x10); + sc501ai_2l_write_register(ViPipe, 0x33af, 0x19); + sc501ai_2l_write_register(ViPipe, 0x360f, 0x01); + sc501ai_2l_write_register(ViPipe, 0x3622, 0x03); + sc501ai_2l_write_register(ViPipe, 0x363a, 0x1f); + sc501ai_2l_write_register(ViPipe, 0x363c, 0x40); + sc501ai_2l_write_register(ViPipe, 0x3651, 0x7d); + sc501ai_2l_write_register(ViPipe, 0x3670, 0x0a); + sc501ai_2l_write_register(ViPipe, 0x3671, 0x07); + sc501ai_2l_write_register(ViPipe, 0x3672, 0x17); + sc501ai_2l_write_register(ViPipe, 0x3673, 0x1e); + sc501ai_2l_write_register(ViPipe, 0x3674, 0x82); + sc501ai_2l_write_register(ViPipe, 0x3675, 0x64); + sc501ai_2l_write_register(ViPipe, 0x3676, 0x66); + sc501ai_2l_write_register(ViPipe, 0x367a, 0x48); + sc501ai_2l_write_register(ViPipe, 0x367b, 0x78); + sc501ai_2l_write_register(ViPipe, 0x367c, 0x58); + sc501ai_2l_write_register(ViPipe, 0x367d, 0x78); + sc501ai_2l_write_register(ViPipe, 0x3690, 0x34); + sc501ai_2l_write_register(ViPipe, 0x3691, 0x34); + sc501ai_2l_write_register(ViPipe, 0x3692, 0x54); + sc501ai_2l_write_register(ViPipe, 0x369c, 0x48); + sc501ai_2l_write_register(ViPipe, 0x369d, 0x78); + sc501ai_2l_write_register(ViPipe, 0x36ec, 0x0a); + sc501ai_2l_write_register(ViPipe, 0x3904, 0x04); + sc501ai_2l_write_register(ViPipe, 0x3908, 0x41); + sc501ai_2l_write_register(ViPipe, 0x391d, 0x04); + sc501ai_2l_write_register(ViPipe, 0x39c2, 0x30); + sc501ai_2l_write_register(ViPipe, 0x3e01, 0xcd); + sc501ai_2l_write_register(ViPipe, 0x3e02, 0xc0); + sc501ai_2l_write_register(ViPipe, 0x3e16, 0x00); + sc501ai_2l_write_register(ViPipe, 0x3e17, 0x80); + sc501ai_2l_write_register(ViPipe, 0x4500, 0x88); + sc501ai_2l_write_register(ViPipe, 0x4509, 0x20); + sc501ai_2l_write_register(ViPipe, 0x4837, 0x14); + sc501ai_2l_write_register(ViPipe, 0x5799, 0x00); + sc501ai_2l_write_register(ViPipe, 0x59e0, 0x60); + sc501ai_2l_write_register(ViPipe, 0x59e1, 0x08); + sc501ai_2l_write_register(ViPipe, 0x59e2, 0x3f); + sc501ai_2l_write_register(ViPipe, 0x59e3, 0x18); + sc501ai_2l_write_register(ViPipe, 0x59e4, 0x18); + sc501ai_2l_write_register(ViPipe, 0x59e5, 0x3f); + sc501ai_2l_write_register(ViPipe, 0x59e7, 0x02); + sc501ai_2l_write_register(ViPipe, 0x59e8, 0x38); + sc501ai_2l_write_register(ViPipe, 0x59e9, 0x20); + sc501ai_2l_write_register(ViPipe, 0x59ea, 0x0c); + sc501ai_2l_write_register(ViPipe, 0x59ec, 0x08); + sc501ai_2l_write_register(ViPipe, 0x59ed, 0x02); + sc501ai_2l_write_register(ViPipe, 0x59ee, 0xa0); + sc501ai_2l_write_register(ViPipe, 0x59ef, 0x08); + sc501ai_2l_write_register(ViPipe, 0x59f4, 0x18); + sc501ai_2l_write_register(ViPipe, 0x59f5, 0x10); + sc501ai_2l_write_register(ViPipe, 0x59f6, 0x0c); + sc501ai_2l_write_register(ViPipe, 0x59f9, 0x02); + sc501ai_2l_write_register(ViPipe, 0x59fa, 0x18); + sc501ai_2l_write_register(ViPipe, 0x59fb, 0x10); + sc501ai_2l_write_register(ViPipe, 0x59fc, 0x0c); + sc501ai_2l_write_register(ViPipe, 0x59ff, 0x02); + sc501ai_2l_write_register(ViPipe, 0x36e9, 0x1c); + sc501ai_2l_write_register(ViPipe, 0x36f9, 0x24); + sc501ai_2l_init_ex(ViPipe); + sc501ai_2l_default_reg_init(ViPipe); + + sc501ai_2l_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC501AI_2L 1620P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc531ai_2L/Makefile b/middleware/v2/component/isp/sensor/cv180x/sms_sc531ai_2L/Makefile new file mode 100644 index 000000000..ae828df60 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc531ai_2L/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc531ai_2l.a +TARGET_SO = $(MW_LIB)/libsns_sc531ai_2l.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc531ai_2L/sc531ai_2L_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc531ai_2L/sc531ai_2L_cmos.c new file mode 100644 index 000000000..2e003b166 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc531ai_2L/sc531ai_2L_cmos.c @@ -0,0 +1,981 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc531ai_2L_cmos_ex.h" +#include "sc531ai_2L_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define sc531AI_2L_ID 500 +#define SENSOR_sc531AI_2L_WIDTH 2880 +#define SENSOR_sc531AI_2L_HEIGHT 1620 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastsc531AI_2L[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define sc531AI_2L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastsc531AI_2L[dev]) +#define sc531AI_2L_SENSOR_SET_CTX(dev, pstCtx) (g_pastsc531AI_2L[dev] = pstCtx) +#define sc531AI_2L_SENSOR_RESET_CTX(dev) (g_pastsc531AI_2L[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunsc531AI_2L_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16sc531AI_2L_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16sc531AI_2L_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +sc531AI_2L_STATE_S g_astsc531AI_2L_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc531ai_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****sc531AI_2L Lines Range*****/ +#define sc531AI_2L_FULL_LINES_MAX (0x7FFF) + +/*****sc531AI_2L Register Address*****/ +#define sc531AI_2L_SHS1_0_ADDR 0x3E00 +#define sc531AI_2L_SHS1_1_ADDR 0x3E01 +#define sc531AI_2L_SHS1_2_ADDR 0x3E02 +#define sc531AI_2L_AGAIN_ADDR 0x3E09 +#define sc531AI_2L_DGAIN_ADDR 0x3E06 +#define sc531AI_2L_DGAIN_FINEADDR 0x3E07 +#define sc531AI_2L_FLIP_MIRROR_ADDR 0x3221 +#define sc531AI_2L_VMAX_ADDR 0x320E +#define sc531AI_2L_TABLE_END 0xFFFF + +#define sc531AI_2L_RES_IS_1620P(w, h) ((w) <= 2880 && (h) <= 1620) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = sc531AI_2L_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 0.5; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astsc531AI_2L_mode[sc531AI_2L_MODE_1620P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astsc531AI_2L_mode[sc531AI_2L_MODE_1620P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = g_astsc531AI_2L_mode[sc531AI_2L_MODE_1620P30].stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = g_astsc531AI_2L_mode[sc531AI_2L_MODE_1620P30].stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astsc531AI_2L_mode[sc531AI_2L_MODE_1620P30].stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = g_astsc531AI_2L_mode[sc531AI_2L_MODE_1620P30].stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = 2 * (pstSnsState->u32FLStd - 5); + pstAeSnsDft->u32MinIntTime = 3; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + case WDR_MODE_2To1_LINE: + break; + } + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astsc531AI_2L_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astsc531AI_2L_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astsc531AI_2L_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case sc531AI_2L_MODE_1620P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > sc531AI_2L_FULL_LINES_MAX) ? sc531AI_2L_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = 2 * (pstSnsState->u32FLStd - 5); + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + CVI_U32 u32TmpIntTime = u32IntTime[0]; + CVI_U32 maxExp = 2 * pstSnsState->au32FL[0] - 10; + + /* linear exposure reg range: + * min : 3 + * max : 2 * vts - 10 + * step : 1 + */ + u32TmpIntTime = (u32TmpIntTime > maxExp) ? maxExp : u32TmpIntTime; + if (u32TmpIntTime < 3) + u32TmpIntTime = 3; + u32IntTime[0] = u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = (u32TmpIntTime & 0xF) << 4; + + return CVI_SUCCESS; + +} + +static CVI_U32 Again_table[] = { + 1024, 2048, 2447, 4894, 9789, 19578, 39157, 78315 +}; + +static CVI_U32 AgainReg[] = { + 0x00, 0x01, 0x40, 0x48, 0x49, 0x4B, 0x4F, 0x5F +}; + +struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +}; + +static struct gain_tbl_info_s DgainInfo[2] = { + { + .gainMax = 2016, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, +}; + +static CVI_U32 Dgain_table[64] = { + 1024, 1055, 1088, 1120, 1152, 1183, 1216, 1248, 1280, 1311, 1344, 1376, 1408, 1439, 1472, 1504, + 1536, 1567, 1600, 1632, 1664, 1695, 1728, 1760, 1792, 1823, 1856, 1888, 1920, 1951, 1984, 2016, + 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008, + 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, 3904, 3968, 4032, +}; + +static CVI_U32 Again_tableSize = sizeof(Again_table) / sizeof(CVI_U32); +static CVI_U32 Dgain_tableSize = sizeof(Dgain_table) / sizeof(CVI_U32); + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 i; + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[Again_tableSize-1]) { + *pu32AgainLin = Again_table[Again_tableSize-1]; + *pu32AgainDb = AgainReg[Again_tableSize-1]; + return CVI_SUCCESS; + } + + for (i = 1; i < Again_tableSize; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = AgainReg[i - 1]; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void)ViPipe; + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[Dgain_tableSize - 1]) { + *pu32DgainLin = Dgain_table[Dgain_tableSize - 1]; + *pu32DgainDb = Dgain_tableSize - 1; + return CVI_SUCCESS; + } + + for (CVI_U32 i = 1; i < Dgain_tableSize; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_FINE_ADDR].u32Data = (u32Dgain & 0xFF); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0; + CVI_U32 u32ShortTimeMinLimit = 5; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32MaxSexp = 2 * g_astsc531AI_2L_State[ViPipe].u32Sexp_MAX - 14; + + (void) u16ManRatioEnable; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + /* short exposure reg range: + * min : 5 + * max : 2 * (max sexp - 7) + * step : 4 + * long exposure reg range: + * min : 5 + * max : 2 * (vts - max sexp - 9) + * step : 4 + */ + u32IntTimeMaxTmp = ((2 * pstSnsState->au32FL[0] - 16) * 0x40) / (au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32MaxSexp) ? u32MaxSexp : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp < u32ShortTimeMinLimit) ? u32ShortTimeMinLimit : u32IntTimeMaxTmp; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + syslog(LOG_DEBUG, "ViPipe = %d ratio = %d, (%d, %d)\n", ViPipe, au32Ratio[0], + u32IntTimeMaxTmp, u32ShortTimeMinLimit); + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const sc531AI_2L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astsc531AI_2L_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astsc531AI_2L_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + + case WDR_MODE_2To1_LINE: + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunsc531AI_2L_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc531ai_2l_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc531ai_2l_addr_byte; + pstI2c_data[i].u32DataByteNum = sc531ai_2l_data_byte; + } + + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = sc531AI_2L_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = sc531AI_2L_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = sc531AI_2L_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = sc531AI_2L_AGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_ADDR].u32RegAddr = sc531AI_2L_DGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_FINE_ADDR].u32RegAddr = sc531AI_2L_DGAIN_FINEADDR; + pstI2c_data[LINEAR_FLIP_MIRROR].u32RegAddr = sc531AI_2L_FLIP_MIRROR_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = sc531AI_2L_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = sc531AI_2L_VMAX_ADDR + 1; + + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = CVI_FALSE; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (sc531AI_2L_RES_IS_1620P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = sc531AI_2L_MODE_1620P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sc531ai_2l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U8 value = 0; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + if (pstSnsState->bInit == CVI_TRUE && g_aeSc531ai_MirrorFip[ViPipe] != eSnsMirrorFlip) { + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + value |= 0; + break; + case ISP_SNS_MIRROR: + value |= 0x6; + break; + case ISP_SNS_FLIP: + value |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + value |= 0x66; + break; + default: + return; + } + + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u8DropFrmNum = 1; + g_aeSc531ai_MirrorFip[ViPipe] = eSnsMirrorFlip; + } + +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const sc531AI_2L_MODE_S *pstMode = CVI_NULL; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = sc531AI_2L_MODE_1620P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astsc531AI_2L_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc531ai_2l_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astsc531AI_2L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astsc531AI_2L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc531ai_2l_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc531ai_2l_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc531ai_2l_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc531ai_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunsc531AI_2L_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + sc531AI_2L_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + sc531AI_2L_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = sc531AI_2L_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, sc531AI_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, sc531AI_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, sc531AI_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16sc531AI_2L_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16sc531AI_2L_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC531AI_2L_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc531ai_2l_standby, + .pfnRestart = sc531ai_2l_restart, + .pfnMirrorFlip = sc531ai_2l_mirror_flip, + .pfnWriteReg = sc531ai_2l_write_register, + .pfnReadReg = sc531ai_2l_read_register, + .pfnSetBusInfo = sc531ai_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc531ai_2l_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc531ai_2L/sc531ai_2L_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc531ai_2L/sc531ai_2L_cmos_ex.h new file mode 100644 index 000000000..05c948c72 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc531ai_2L/sc531ai_2L_cmos_ex.h @@ -0,0 +1,84 @@ +#ifndef __SC531AI_2L_CMOS_EX_H_ +#define __SC531AI_2L_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc531ai_2l_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_2_ADDR, + LINEAR_AGAIN_ADDR, + LINEAR_DGAIN_ADDR, + LINEAR_DGAIN_FINE_ADDR, + LINEAR_FLIP_MIRROR, + LINEAR_VMAX_H_ADDR, + LINEAR_VMAX_L_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _sc531AI_2L_MODE_E { + sc531AI_2L_MODE_1620P30 = 0, + sc531AI_2L_MODE_LINEAR_NUM, + sc531AI_2L_MODE_NUM +} sc531AI_2L_MODE_E; + +typedef struct _sc531AI_2L_STATE_S { + CVI_U32 u32Sexp_MAX; +} sc531AI_2L_STATE_S; + +typedef struct _sc531AI_2L_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + CVI_U16 u16SexpMaxReg; + char name[64]; +} sc531AI_2L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastsc531AI_2L[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunsc531AI_2L_BusInfo[]; +extern CVI_U16 g_au16sc531AI_2L_GainMode[]; +extern CVI_U16 g_au16sc531AI_2L_L2SMode[]; +extern const CVI_U8 sc531ai_2l_i2c_addr; +extern const CVI_U32 sc531ai_2l_addr_byte; +extern const CVI_U32 sc531ai_2l_data_byte; +extern void sc531ai_2l_init(VI_PIPE ViPipe); +extern void sc531ai_2l_exit(VI_PIPE ViPipe); +extern void sc531ai_2l_standby(VI_PIPE ViPipe); +extern void sc531ai_2l_restart(VI_PIPE ViPipe); +extern int sc531ai_2l_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc531ai_2l_read_register(VI_PIPE ViPipe, int addr); +extern int sc531ai_2l_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __sc531AI_2L_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc531ai_2L/sc531ai_2L_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sms_sc531ai_2L/sc531ai_2L_cmos_param.h new file mode 100644 index 000000000..ec0de0eb0 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc531ai_2L/sc531ai_2L_cmos_param.h @@ -0,0 +1,225 @@ +#ifndef __SC531AI_2L_CMOS_PARAM_H_ +#define __SC531AI_2L_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc531ai_2L_cmos_ex.h" + +static const sc531AI_2L_MODE_S g_astsc531AI_2L_mode[sc531AI_2L_MODE_NUM] = { + [sc531AI_2L_MODE_1620P30] = { + .name = "1620p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2880, + .u32Height = 1620, + }, + .stMaxSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.52, /* 1650 * 30 / 0x7FFF*/ + .u32HtsDef = 2560, /* NA */ + .u32VtsDef = 1650, + .stExp[0] = { + .u16Min = 3, + .u16Max = 3290,/* 2*vts-10 */ + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 78315, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 4032, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.02792946062982082367, 3.36534714698791503906}, //B: slope, intercept + {0.02071751467883586884, 5.34583568572998046875}, //Gb: slope, intercept + {0.02110148966312408447, 5.02954530715942382813}, //Gr: slope, intercept + {0.02168512716889381409, 4.89776754379272460938}, //R: slope, intercept + }, + { //iso 200 + {0.03194080293178558350, 5.61192893981933593750}, //B: slope, intercept + {0.02428408525884151459, 7.94834280014038085938}, //Gb: slope, intercept + {0.02499442733824253082, 7.72430133819580078125}, //Gr: slope, intercept + {0.02584112435579299927, 7.20574426651000976563}, //R: slope, intercept + }, + { //iso 400 + {0.04612467437982559204, 6.88752269744873046875}, //B: slope, intercept + {0.03022909909486770630, 11.05101776123046875000}, //Gb: slope, intercept + {0.03175539523363113403, 10.60332489013671875000}, //Gr: slope, intercept + {0.03522306308150291443, 9.36425399780273437500}, //R: slope, intercept + }, + { //iso 800 + {0.06092500314116477966, 9.79670524597167968750}, //B: slope, intercept + {0.03984217345714569092, 15.30182266235351562500}, //Gb: slope, intercept + {0.04019560664892196655, 14.93132972717285156250}, //Gr: slope, intercept + {0.04470816254615783691, 13.26843166351318359375}, //R: slope, intercept + }, + { //iso 1600 + {0.08295634388923645020, 14.20334625244140625000}, //B: slope, intercept + {0.05075264349579811096, 20.99221038818359375000}, //Gb: slope, intercept + {0.05426201224327087402, 20.08068656921386718750}, //Gr: slope, intercept + {0.05945669487118721008, 19.02898788452148437500}, //R: slope, intercept + }, + { //iso 3200 + {0.09782519936561584473, 21.84967994689941406250}, //B: slope, intercept + {0.06690908223390579224, 26.53993988037109375000}, //Gb: slope, intercept + {0.06954573839902877808, 25.74129104614257812500}, //Gr: slope, intercept + {0.09061723947525024414, 22.98998260498046875000}, //R: slope, intercept + }, + { //iso 6400 + {0.14311420917510986328, 28.96467971801757812500}, //B: slope, intercept + {0.08148498833179473877, 37.93062591552734375000}, //Gb: slope, intercept + {0.08273542672395706177, 38.37096405029296875000}, //Gr: slope, intercept + {0.12093253433704376221, 33.31475067138671875000}, //R: slope, intercept + }, + { //iso 12800 + {0.17958122491836547852, 43.49506759643554687500}, //B: slope, intercept + {0.09839969873428344727, 55.43268966674804687500}, //Gb: slope, intercept + {0.10201884806156158447, 52.97607040405273437500}, //Gr: slope, intercept + {0.15302789211273193359, 47.54779434204101562500}, //R: slope, intercept + }, + { //iso 25600 + {0.25833165645599365234, 56.96470642089843750000}, //B: slope, intercept + {0.13260601460933685303, 74.69016265869140625000}, //Gb: slope, intercept + {0.14035490155220031738, 75.44366455078125000000}, //Gr: slope, intercept + {0.23465165495872497559, 60.52228164672851562500}, //R: slope, intercept + }, + { //iso 51200 + {0.37595292925834655762, 78.54853057861328125000}, //B: slope, intercept + {0.21475413441658020020, 102.12300872802734375000}, //Gb: slope, intercept + {0.20840260386466979980, 103.65763854980468750000}, //Gr: slope, intercept + {0.34428051114082336426, 87.83551025390625000000}, //R: slope, intercept + }, + { //iso 102400 + {0.51122575998306274414, 113.49224090576171875000}, //B: slope, intercept + {0.29245173931121826172, 154.26939392089843750000}, //Gb: slope, intercept + {0.31501635909080505371, 148.29017639160156250000}, //Gr: slope, intercept + {0.47034618258476257324, 124.06208038330078125000}, //R: slope, intercept + }, + { //iso 204800 + {0.67213481664657592773, 134.71751403808593750000}, //B: slope, intercept + {0.40368056297302246094, 189.80801391601562500000}, //Gb: slope, intercept + {0.43581819534301757813, 186.44682312011718750000}, //Gr: slope, intercept + {0.60127359628677368164, 160.66384887695312500000}, //R: slope, intercept + }, + { //iso 409600 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 819200 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc531ai_2l_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {1, 2, 0, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + .dphy = { + .enable = 1, + .hs_settle = 14, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __sc531AI_2L_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sms_sc531ai_2L/sc531ai_2L_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sms_sc531ai_2L/sc531ai_2L_sensor_ctl.c new file mode 100644 index 000000000..d005dc750 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sms_sc531ai_2L/sc531ai_2L_sensor_ctl.c @@ -0,0 +1,377 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc531ai_2L_cmos_ex.h" + +static void sc531ai_2l_linear_1620p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc531ai_2l_i2c_addr = 0x30; /* I2C Address of sc531AI_2L */ +const CVI_U32 sc531ai_2l_addr_byte = 2; +const CVI_U32 sc531ai_2l_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc531ai_2l_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunsc531AI_2L_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc531ai_2l_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc531ai_2l_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc531ai_2l_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc531ai_2l_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc531ai_2l_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc531ai_2l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc531ai_2l_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc531ai_2l_write_register(VI_PIPE ViPipe, int addr, int data) +{ + int idx = 0; + int ret; + char buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc531ai_2l_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc531ai_2l_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc531ai_2l_addr_byte + sc531ai_2l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc531ai_2l_standby(VI_PIPE ViPipe) +{ + sc531ai_2l_write_register(ViPipe, 0x0100, 0x00); +} + +void sc531ai_2l_restart(VI_PIPE ViPipe) +{ + sc531ai_2l_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc531ai_2l_write_register(ViPipe, 0x0100, 0x01); +} + +void sc531ai_2l_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastsc531AI_2L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc531ai_2l_write_register(ViPipe, + g_pastsc531AI_2L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastsc531AI_2L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define sc531AI_2L_CHIP_ID_HI_ADDR 0x3107 +#define sc531AI_2L_CHIP_ID_LO_ADDR 0x3108 +#define sc531AI_2L_CHIP_ID 0x9e39 + +int sc531ai_2l_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc531ai_2l_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc531ai_2l_read_register(ViPipe, sc531AI_2L_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc531ai_2l_read_register(ViPipe, sc531AI_2L_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != sc531AI_2L_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc531ai_2l_init(VI_PIPE ViPipe) +{ + sc531ai_2l_i2c_init(ViPipe); + + sc531ai_2l_linear_1620p30_init(ViPipe); + + g_pastsc531AI_2L[ViPipe]->bInit = CVI_TRUE; +} + +void sc531ai_2l_exit(VI_PIPE ViPipe) +{ + sc531ai_2l_i2c_exit(ViPipe); +} + +/* 1620P30 */ +static void sc531ai_2l_linear_1620p30_init(VI_PIPE ViPipe) +{ + sc531ai_2l_write_register(ViPipe, 0x0103, 0x01); + sc531ai_2l_write_register(ViPipe, 0x0100, 0x00); + sc531ai_2l_write_register(ViPipe, 0x36e9, 0x80); + sc531ai_2l_write_register(ViPipe, 0x37f9, 0x80); + sc531ai_2l_write_register(ViPipe, 0x3018, 0x32); + sc531ai_2l_write_register(ViPipe, 0x3019, 0x0c); + sc531ai_2l_write_register(ViPipe, 0x301f, 0x69); + sc531ai_2l_write_register(ViPipe, 0x3250, 0x40); + sc531ai_2l_write_register(ViPipe, 0x3251, 0x98); + sc531ai_2l_write_register(ViPipe, 0x3253, 0x0c); + sc531ai_2l_write_register(ViPipe, 0x325f, 0x20); + sc531ai_2l_write_register(ViPipe, 0x3301, 0x08); + sc531ai_2l_write_register(ViPipe, 0x3304, 0x50); + sc531ai_2l_write_register(ViPipe, 0x3306, 0x88); + sc531ai_2l_write_register(ViPipe, 0x3308, 0x14); + sc531ai_2l_write_register(ViPipe, 0x3309, 0x70); + sc531ai_2l_write_register(ViPipe, 0x330a, 0x00); + sc531ai_2l_write_register(ViPipe, 0x330b, 0xf8); + sc531ai_2l_write_register(ViPipe, 0x330d, 0x10); + sc531ai_2l_write_register(ViPipe, 0x330e, 0x42); + sc531ai_2l_write_register(ViPipe, 0x331e, 0x41); + sc531ai_2l_write_register(ViPipe, 0x331f, 0x61); + sc531ai_2l_write_register(ViPipe, 0x3333, 0x10); + sc531ai_2l_write_register(ViPipe, 0x335d, 0x60); + sc531ai_2l_write_register(ViPipe, 0x335e, 0x06); + sc531ai_2l_write_register(ViPipe, 0x335f, 0x08); + sc531ai_2l_write_register(ViPipe, 0x3364, 0x56); + sc531ai_2l_write_register(ViPipe, 0x3366, 0x01); + sc531ai_2l_write_register(ViPipe, 0x337c, 0x02); + sc531ai_2l_write_register(ViPipe, 0x337d, 0x0a); + sc531ai_2l_write_register(ViPipe, 0x3390, 0x01); + sc531ai_2l_write_register(ViPipe, 0x3391, 0x03); + sc531ai_2l_write_register(ViPipe, 0x3392, 0x07); + sc531ai_2l_write_register(ViPipe, 0x3393, 0x08); + sc531ai_2l_write_register(ViPipe, 0x3394, 0x08); + sc531ai_2l_write_register(ViPipe, 0x3395, 0x08); + sc531ai_2l_write_register(ViPipe, 0x3396, 0x40); + sc531ai_2l_write_register(ViPipe, 0x3397, 0x48); + sc531ai_2l_write_register(ViPipe, 0x3398, 0x4b); + sc531ai_2l_write_register(ViPipe, 0x3399, 0x08); + sc531ai_2l_write_register(ViPipe, 0x339a, 0x08); + sc531ai_2l_write_register(ViPipe, 0x339b, 0x08); + sc531ai_2l_write_register(ViPipe, 0x339c, 0x1d); + sc531ai_2l_write_register(ViPipe, 0x33a2, 0x04); + sc531ai_2l_write_register(ViPipe, 0x33ae, 0x30); + sc531ai_2l_write_register(ViPipe, 0x33af, 0x50); + sc531ai_2l_write_register(ViPipe, 0x33b1, 0x80); + sc531ai_2l_write_register(ViPipe, 0x33b2, 0x48); + sc531ai_2l_write_register(ViPipe, 0x33b3, 0x30); + sc531ai_2l_write_register(ViPipe, 0x349f, 0x02); + sc531ai_2l_write_register(ViPipe, 0x34a6, 0x48); + sc531ai_2l_write_register(ViPipe, 0x34a7, 0x4b); + sc531ai_2l_write_register(ViPipe, 0x34a8, 0x30); + sc531ai_2l_write_register(ViPipe, 0x34a9, 0x18); + sc531ai_2l_write_register(ViPipe, 0x34f8, 0x5f); + sc531ai_2l_write_register(ViPipe, 0x34f9, 0x08); + sc531ai_2l_write_register(ViPipe, 0x3632, 0x48); + sc531ai_2l_write_register(ViPipe, 0x3633, 0x32); + sc531ai_2l_write_register(ViPipe, 0x3637, 0x27); + sc531ai_2l_write_register(ViPipe, 0x3638, 0xc1); + sc531ai_2l_write_register(ViPipe, 0x363b, 0x20); + sc531ai_2l_write_register(ViPipe, 0x363d, 0x02); + sc531ai_2l_write_register(ViPipe, 0x3670, 0x09); + sc531ai_2l_write_register(ViPipe, 0x3674, 0x8b); + sc531ai_2l_write_register(ViPipe, 0x3675, 0xc6); + sc531ai_2l_write_register(ViPipe, 0x3676, 0x8b); + sc531ai_2l_write_register(ViPipe, 0x367c, 0x40); + sc531ai_2l_write_register(ViPipe, 0x367d, 0x48); + sc531ai_2l_write_register(ViPipe, 0x3690, 0x32); + sc531ai_2l_write_register(ViPipe, 0x3691, 0x43); + sc531ai_2l_write_register(ViPipe, 0x3692, 0x33); + sc531ai_2l_write_register(ViPipe, 0x3693, 0x40); + sc531ai_2l_write_register(ViPipe, 0x3694, 0x4b); + sc531ai_2l_write_register(ViPipe, 0x3698, 0x85); + sc531ai_2l_write_register(ViPipe, 0x3699, 0x8f); + sc531ai_2l_write_register(ViPipe, 0x369a, 0xa0); + sc531ai_2l_write_register(ViPipe, 0x369b, 0xc3); + sc531ai_2l_write_register(ViPipe, 0x36a2, 0x49); + sc531ai_2l_write_register(ViPipe, 0x36a3, 0x4b); + sc531ai_2l_write_register(ViPipe, 0x36a4, 0x4f); + sc531ai_2l_write_register(ViPipe, 0x36d0, 0x01); + sc531ai_2l_write_register(ViPipe, 0x36ea, 0x0b); + sc531ai_2l_write_register(ViPipe, 0x36eb, 0x04); + sc531ai_2l_write_register(ViPipe, 0x36ec, 0x03); + sc531ai_2l_write_register(ViPipe, 0x36ed, 0x14); + sc531ai_2l_write_register(ViPipe, 0x370f, 0x01); + sc531ai_2l_write_register(ViPipe, 0x3722, 0x00); + sc531ai_2l_write_register(ViPipe, 0x3728, 0x10); + sc531ai_2l_write_register(ViPipe, 0x37b0, 0x03); + sc531ai_2l_write_register(ViPipe, 0x37b1, 0x03); + sc531ai_2l_write_register(ViPipe, 0x37b2, 0x83); + sc531ai_2l_write_register(ViPipe, 0x37b3, 0x48); + sc531ai_2l_write_register(ViPipe, 0x37b4, 0x49); + sc531ai_2l_write_register(ViPipe, 0x37fa, 0x0b); + sc531ai_2l_write_register(ViPipe, 0x37fb, 0x24); + sc531ai_2l_write_register(ViPipe, 0x37fc, 0x01); + sc531ai_2l_write_register(ViPipe, 0x37fd, 0x14); + sc531ai_2l_write_register(ViPipe, 0x3901, 0x00); + sc531ai_2l_write_register(ViPipe, 0x3902, 0xc5); + sc531ai_2l_write_register(ViPipe, 0x3904, 0x08); + sc531ai_2l_write_register(ViPipe, 0x3905, 0x8c); + sc531ai_2l_write_register(ViPipe, 0x3909, 0x00); + sc531ai_2l_write_register(ViPipe, 0x391d, 0x04); + sc531ai_2l_write_register(ViPipe, 0x391f, 0x44); + sc531ai_2l_write_register(ViPipe, 0x3926, 0x21); + sc531ai_2l_write_register(ViPipe, 0x3929, 0x18); + sc531ai_2l_write_register(ViPipe, 0x3933, 0x82); + sc531ai_2l_write_register(ViPipe, 0x3934, 0x0a); + sc531ai_2l_write_register(ViPipe, 0x3937, 0x5f); + sc531ai_2l_write_register(ViPipe, 0x3939, 0x00); + sc531ai_2l_write_register(ViPipe, 0x393a, 0x00); + sc531ai_2l_write_register(ViPipe, 0x39dc, 0x02); + sc531ai_2l_write_register(ViPipe, 0x3e01, 0xcd); + sc531ai_2l_write_register(ViPipe, 0x3e02, 0xa0); + sc531ai_2l_write_register(ViPipe, 0x440e, 0x02); + sc531ai_2l_write_register(ViPipe, 0x4509, 0x20); + sc531ai_2l_write_register(ViPipe, 0x4837, 0x14); + sc531ai_2l_write_register(ViPipe, 0x5010, 0x10); + sc531ai_2l_write_register(ViPipe, 0x5780, 0x66); + sc531ai_2l_write_register(ViPipe, 0x578d, 0x40); + sc531ai_2l_write_register(ViPipe, 0x5799, 0x06); + sc531ai_2l_write_register(ViPipe, 0x57ad, 0x00); + sc531ai_2l_write_register(ViPipe, 0x5ae0, 0xfe); + sc531ai_2l_write_register(ViPipe, 0x5ae1, 0x40); + sc531ai_2l_write_register(ViPipe, 0x5ae2, 0x30); + sc531ai_2l_write_register(ViPipe, 0x5ae3, 0x2a); + sc531ai_2l_write_register(ViPipe, 0x5ae4, 0x24); + sc531ai_2l_write_register(ViPipe, 0x5ae5, 0x30); + sc531ai_2l_write_register(ViPipe, 0x5ae6, 0x2a); + sc531ai_2l_write_register(ViPipe, 0x5ae7, 0x24); + sc531ai_2l_write_register(ViPipe, 0x5ae8, 0x3c); + sc531ai_2l_write_register(ViPipe, 0x5ae9, 0x30); + sc531ai_2l_write_register(ViPipe, 0x5aea, 0x28); + sc531ai_2l_write_register(ViPipe, 0x5aeb, 0x3c); + sc531ai_2l_write_register(ViPipe, 0x5aec, 0x30); + sc531ai_2l_write_register(ViPipe, 0x5aed, 0x28); + sc531ai_2l_write_register(ViPipe, 0x5aee, 0xfe); + sc531ai_2l_write_register(ViPipe, 0x5aef, 0x40); + sc531ai_2l_write_register(ViPipe, 0x5af4, 0x30); + sc531ai_2l_write_register(ViPipe, 0x5af5, 0x2a); + sc531ai_2l_write_register(ViPipe, 0x5af6, 0x24); + sc531ai_2l_write_register(ViPipe, 0x5af7, 0x30); + sc531ai_2l_write_register(ViPipe, 0x5af8, 0x2a); + sc531ai_2l_write_register(ViPipe, 0x5af9, 0x24); + sc531ai_2l_write_register(ViPipe, 0x5afa, 0x3c); + sc531ai_2l_write_register(ViPipe, 0x5afb, 0x30); + sc531ai_2l_write_register(ViPipe, 0x5afc, 0x28); + sc531ai_2l_write_register(ViPipe, 0x5afd, 0x3c); + sc531ai_2l_write_register(ViPipe, 0x5afe, 0x30); + sc531ai_2l_write_register(ViPipe, 0x5aff, 0x28); + sc531ai_2l_write_register(ViPipe, 0x36e9, 0x44); + sc531ai_2l_write_register(ViPipe, 0x37f9, 0x44); + + sc531ai_2l_default_reg_init(ViPipe); + + sc531ai_2l_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===sc531AI_2L 1620P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_f23/Makefile b/middleware/v2/component/isp/sensor/cv180x/soi_f23/Makefile new file mode 100644 index 000000000..9a364ba1a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_f23/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_f23.a +TARGET_SO = $(MW_LIB)/libsns_f23.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_f23/f23_cmos.c b/middleware/v2/component/isp/sensor/cv180x/soi_f23/f23_cmos.c new file mode 100644 index 000000000..9f432a4b3 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_f23/f23_cmos.c @@ -0,0 +1,1124 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "f23_cmos_ex.h" +#include "f23_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define F23_ID 35 +#define SENSOR_F23_WIDTH 1920 +#define SENSOR_F23_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastF23[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define F23_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastF23[dev]) +#define F23_SENSOR_SET_CTX(dev, pstCtx) (g_pastF23[dev] = pstCtx) +#define F23_SENSOR_RESET_CTX(dev) (g_pastF23[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunF23_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16F23_GainMode[VI_MAX_PIPE_NUM] = {0}; + +F23_STATE_S g_astF23_State[VI_MAX_PIPE_NUM] = {{0} }; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****F23 Lines Range*****/ +#define F23_FULL_LINES_MAX (0xFFFF) +#define F23_FULL_LINES_MAX_2TO1_WDR (0xFFFF) + +/*****F23 Register Address*****/ +#define F23_GLAT_ADDR 0x1F +#define F23_GRP_ADDR 0xC0 +#define F23_SHS1_ADDR 0x01 +#define F23_SHS2_ADDR 0x05 +#define F23_GAIN_ADDR 0x00 +#define F23_DGAIN_ADDR 0x0D +#define F23_VMAX_ADDR 0x22 +#define F23_TABLE_END 0xff + +#define F23_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = F23_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stDgainAccu.f32Accuracy = 6; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astF23_mode[F23_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astF23_mode[F23_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 15872; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 4096; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 5; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astF23_mode[F23_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astF23_mode[F23_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstAeSnsDft->u32MinIntTime = 1; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 15872; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 4096; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 5; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astF23_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astF23_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astF23_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case F23_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > F23_FULL_LINES_MAX_2TO1_WDR) ? F23_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case F23_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > F23_FULL_LINES_MAX) ? F23_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + g_astF23_State[ViPipe].u32Sexp_MAX = u32VMAX - + g_astF23_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height * 2; + /* Sexp = 1,3,5,7... */ + if (g_astF23_State[ViPipe].u32Sexp_MAX < 2) { + g_astF23_State[ViPipe].u32Sexp_MAX = 1; + } else { + g_astF23_State[ViPipe].u32Sexp_MAX = (g_astF23_State[ViPipe].u32Sexp_MAX & (~0x1)) - 1; + syslog(LOG_DEBUG, "VMAX %d, MAX_SEXP %d\n", u32VMAX, g_astF23_State[ViPipe].u32Sexp_MAX); + } + } + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_DATA].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_DATA].u32Data = ((u32VMAX & 0xFF00) >> 8); + } else { + pstSnsRegsInfo->astI2cData[WDR2_VMAX_0_DATA].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_VMAX_1_DATA].u32Data = ((u32VMAX & 0xFF00) >> 8); + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_cif_wdr(VI_PIPE ViPipe, ISP_SNS_CIF_INFO_S *pstCifCfg) +{ + const F23_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astF23_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstCifCfg->wdr_manual.manual_en = 0; + return CVI_SUCCESS; + } + + pstCifCfg->wdr_manual.devno = f23_rx_attr.devno; + pstCifCfg->wdr_manual.manual_en = 1; + pstCifCfg->wdr_manual.l2s_distance = g_astF23_State[ViPipe].u8SexpReg; + pstCifCfg->wdr_manual.lsef_length = pstMode->astImg[0].stSnsSize.u32Height; + pstCifCfg->wdr_manual.discard_padding_lines = 0; + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + CVI_U8 u8SexpReg; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = (u32ShortIntTime > g_astF23_State[ViPipe].u32Sexp_MAX) ? + g_astF23_State[ViPipe].u32Sexp_MAX : u32ShortIntTime; + if (!pstSnsState->au32WDRIntTime[0]) + pstSnsState->au32WDRIntTime[0] = 1; + /* short exp = SexpReg * 2 + 1 */ + u8SexpReg = (pstSnsState->au32WDRIntTime[0] - 1) >> 1; + pstSnsState->au32WDRIntTime[0] = (u8SexpReg << 1) + 1; + g_astF23_State[ViPipe].u8SexpReg = u8SexpReg; + + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = u32LongIntTime; + + if ((pstSnsState->au32WDRIntTime[0] + pstSnsState->au32WDRIntTime[1] + 5) > pstSnsState->au32FL[0]) { + CVI_TRACE_SNS(CVI_DBG_ERR, "inttime over spec [%u, %u, %u]\n", + pstSnsState->au32WDRIntTime[0], + pstSnsState->au32WDRIntTime[1], + pstSnsState->au32FL[0]); + return CVI_FAILURE; + } + + pstSnsRegsInfo->astI2cData[WDR2_SHS1_0_DATA].u32Data = (pstSnsState->au32WDRIntTime[1] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_SHS1_1_DATA].u32Data = ((pstSnsState->au32WDRIntTime[1] & 0xFF00) >> 8); + + pstSnsRegsInfo->astI2cData[WDR2_SHS2_DATA].u32Data = (u8SexpReg & 0xFF); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + /* update cif*/ + cmos_get_cif_wdr(ViPipe, &pstSnsState->astSyncInfo[0].cifCfg); + } else { + if ((u32IntTime[0] + 5) > pstSnsState->au32FL[0]) { + CVI_TRACE_SNS(CVI_DBG_ERR, "inttime over spec [%u, %u]\n", + u32IntTime[0], + pstSnsState->au32FL[0]); + return CVI_FAILURE; + } + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_DATA].u32Data = (u32IntTime[0] & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_DATA].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[64] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[63]) { + *pu32AgainLin = gain_table[63]; + *pu32AgainDb = 63; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin <= 1024) { + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + } else if (*pu32DgainLin <= 2048) { + *pu32DgainLin = 2048; + *pu32DgainDb = 1; + } else { + *pu32DgainLin = 4096; + *pu32DgainDb = 3; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0] | g_astF23_mode[pstSnsState->u8ImgMode].u8DgainReg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_DATA].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_DATA].u32Data = (u32Dgain & 0xFF); + } else { + /* DOL mode */ + pstSnsRegsInfo->astI2cData[WDR2_AGAIN_DATA].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN_DATA].u32Data = (u32Dgain & 0xFF); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 1; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 5) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > g_astF23_State[ViPipe].u32Sexp_MAX) ? + g_astF23_State[ViPipe].u32Sexp_MAX : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio is too large!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const F23_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astF23_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == F23_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = F23_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astF23_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == F23_MODE_1080P30) + pstSnsState->u8ImgMode = F23_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astF23_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "2to1 line WDR 1080p mode(60fps->30fps)\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunF23_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = f23_i2c_addr; + pstI2c_data[i].u32AddrByteNum = f23_addr_byte; + pstI2c_data[i].u32DataByteNum = f23_data_byte; + } + + //DOL 2t1 Mode Regs + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + //Linear Mode Regs + pstI2c_data[WDR2_SHS1_0_ADDR].u32RegAddr = F23_GRP_ADDR; + pstI2c_data[WDR2_SHS1_0_ADDR].u32Data = F23_SHS1_ADDR; + pstI2c_data[WDR2_SHS1_0_DATA].u32RegAddr = F23_GRP_ADDR + 1; + + pstI2c_data[WDR2_SHS1_1_ADDR].u32RegAddr = F23_GRP_ADDR + 2; + pstI2c_data[WDR2_SHS1_1_ADDR].u32Data = F23_SHS1_ADDR + 1; + pstI2c_data[WDR2_SHS1_1_DATA].u32RegAddr = F23_GRP_ADDR + 3; + + pstI2c_data[WDR2_SHS2_ADDR].u32RegAddr = F23_GRP_ADDR + 4; + pstI2c_data[WDR2_SHS2_ADDR].u32Data = F23_SHS2_ADDR; + pstI2c_data[WDR2_SHS2_DATA].u32RegAddr = F23_GRP_ADDR + 5; + + pstI2c_data[WDR2_AGAIN_ADDR].u32RegAddr = F23_GRP_ADDR + 6; + pstI2c_data[WDR2_AGAIN_ADDR].u32Data = F23_GAIN_ADDR; + pstI2c_data[WDR2_AGAIN_DATA].u32RegAddr = F23_GRP_ADDR + 7; + + pstI2c_data[WDR2_DGAIN_ADDR].u32RegAddr = F23_GRP_ADDR + 8; + pstI2c_data[WDR2_DGAIN_ADDR].u32Data = F23_DGAIN_ADDR; + pstI2c_data[WDR2_DGAIN_DATA].u32RegAddr = F23_GRP_ADDR + 9; + + pstI2c_data[WDR2_VMAX_0_ADDR].u32RegAddr = F23_GRP_ADDR + 10; + pstI2c_data[WDR2_VMAX_0_ADDR].u32Data = F23_VMAX_ADDR; + pstI2c_data[WDR2_VMAX_0_DATA].u32RegAddr = F23_GRP_ADDR + 11; + + pstI2c_data[WDR2_VMAX_1_ADDR].u32RegAddr = F23_GRP_ADDR + 12; + pstI2c_data[WDR2_VMAX_1_ADDR].u32Data = F23_VMAX_ADDR + 1; + pstI2c_data[WDR2_VMAX_1_DATA].u32RegAddr = F23_GRP_ADDR + 13; + + pstI2c_data[WDR2_REL].u32RegAddr = F23_GLAT_ADDR; + pstI2c_data[WDR2_REL].u32Data = 0x80; + + break; + default: + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = F23_GRP_ADDR; + pstI2c_data[LINEAR_SHS1_0_ADDR].u32Data = F23_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_0_DATA].u32RegAddr = F23_GRP_ADDR + 1; + + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = F23_GRP_ADDR + 2; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32Data = F23_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_1_DATA].u32RegAddr = F23_GRP_ADDR + 3; + + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = F23_GRP_ADDR + 4; + pstI2c_data[LINEAR_AGAIN_ADDR].u32Data = F23_GAIN_ADDR; + pstI2c_data[LINEAR_AGAIN_DATA].u32RegAddr = F23_GRP_ADDR + 5; + + pstI2c_data[LINEAR_DGAIN_ADDR].u32RegAddr = F23_GRP_ADDR + 6; + pstI2c_data[LINEAR_DGAIN_ADDR].u32Data = F23_DGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_DATA].u32RegAddr = F23_GRP_ADDR + 7; + + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = F23_GRP_ADDR + 8; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32Data = F23_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_0_DATA].u32RegAddr = F23_GRP_ADDR + 9; + + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = F23_GRP_ADDR + 10; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32Data = F23_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_1_DATA].u32RegAddr = F23_GRP_ADDR + 11; + + pstI2c_data[LINEAR_REL].u32RegAddr = F23_GLAT_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0x80; + + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + /* recalcualte CIF WDR info */ + cmos_get_cif_wdr(ViPipe, &pstCfg0->cifCfg); + pstCfg0->cifCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[WDR2_REL].u32Data = 0x80; + pstI2c_data[WDR2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_REL].u32Data = 0x80; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (F23_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = F23_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (F23_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = F23_MODE_1080P30_WDR; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const F23_MODE_S *pstMode = CVI_NULL; + + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = F23_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astF23_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &f23_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astF23_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astF23_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstRxAttr->wdr_manu.manual_en = 1; + pstRxAttr->wdr_manu.l2s_distance = g_astF23_State[ViPipe].u8SexpReg; + pstRxAttr->wdr_manu.lsef_length = pstRxAttr->img_size.height; + pstRxAttr->wdr_manu.discard_padding_lines = 0; + pstRxAttr->wdr_manu.update = 1; + } else { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &f23_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = f23_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = f23_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 f23_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunF23_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + F23_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + F23_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + F23_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + F23_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = F23_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, F23_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, F23_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, F23_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16F23_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsF23_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = f23_standby, + .pfnRestart = f23_restart, + .pfnMirrorFlip = CVI_NULL, + .pfnWriteReg = f23_write_register, + .pfnReadReg = f23_read_register, + .pfnSetBusInfo = f23_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_f23/f23_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/soi_f23/f23_cmos_ex.h new file mode 100644 index 000000000..cd4e52a3b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_f23/f23_cmos_ex.h @@ -0,0 +1,107 @@ +#ifndef __F23_CMOS_EX_H_ +#define __F23_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum f23_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_0_DATA, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_1_DATA, + LINEAR_AGAIN_ADDR, + LINEAR_AGAIN_DATA, + LINEAR_DGAIN_ADDR, + LINEAR_DGAIN_DATA, + LINEAR_VMAX_0_ADDR, + LINEAR_VMAX_0_DATA, + LINEAR_VMAX_1_ADDR, + LINEAR_VMAX_1_DATA, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum f23_dol2_regs_e { + WDR2_SHS1_0_ADDR, + WDR2_SHS1_0_DATA, + WDR2_SHS1_1_ADDR, + WDR2_SHS1_1_DATA, + WDR2_SHS2_ADDR, + WDR2_SHS2_DATA, + WDR2_AGAIN_ADDR, + WDR2_AGAIN_DATA, + WDR2_DGAIN_ADDR, + WDR2_DGAIN_DATA, + WDR2_VMAX_0_ADDR, + WDR2_VMAX_0_DATA, + WDR2_VMAX_1_ADDR, + WDR2_VMAX_1_DATA, + WDR2_REL, + WDR2_REGS_NUM +}; + +typedef enum _F23_MODE_E { + F23_MODE_1080P30 = 0, + F23_MODE_LINEAR_NUM, + F23_MODE_1080P30_WDR = F23_MODE_LINEAR_NUM, + F23_MODE_NUM +} F23_MODE_E; + +typedef struct _F23_STATE_S { + CVI_U32 u8SexpReg; + CVI_U32 u32Sexp_MAX; +} F23_STATE_S; + +typedef struct _F23_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + char name[64]; +} F23_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastF23[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunF23_BusInfo[]; +extern CVI_U16 g_au16F23_GainMode[]; +extern const CVI_U8 f23_i2c_addr; +extern const CVI_U32 f23_addr_byte; +extern const CVI_U32 f23_data_byte; +extern void f23_init(VI_PIPE ViPipe); +extern void f23_exit(VI_PIPE ViPipe); +extern void f23_standby(VI_PIPE ViPipe); +extern void f23_restart(VI_PIPE ViPipe); +extern int f23_write_register(VI_PIPE ViPipe, int addr, int data); +extern int f23_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __F23_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_f23/f23_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/soi_f23/f23_cmos_param.h new file mode 100644 index 000000000..4672b9d31 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_f23/f23_cmos_param.h @@ -0,0 +1,203 @@ +#ifndef __F23_CMOS_PARAM_H_ +#define __F23_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "f23_cmos_ex.h" + +static const F23_MODE_S g_astF23_mode[F23_MODE_NUM] = { + [F23_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.52, /* 1125 * 30 / 0xFFFF */ + .u32HtsDef = 2560, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1120, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 4096, + .u16Def = 1024, + .u16Step = 1, + }, + .u8DgainReg = 0x50, + }, + [F23_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.03, /* 2250 * 30 / 0xFFFF */ + .u32HtsDef = 640, + .u32VtsDef = 2250, + .stExp[0] = { + .u16Min = 1, + .u16Max = 131, + .u16Def = 13, + .u16Step = 2, + }, + .stExp[1] = { + .u16Min = 132, + .u16Max = 2096, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 4096, + .u16Def = 1024, + .u16Step = 1, + }, + .u8DgainReg = 0x50, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {68, 68, 68, 68, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1096, 1096, 1096, 1096 +#endif + }, + .stAuto = { + {68, 66, 67, 65, 135, 271, 255, 255, /*8*/255, 255, 255, 255, 256, 255, 256, 256}, + {68, 66, 67, 65, 135, 255, 255, 255, /*8*/255, 255, 255, 255, 256, 255, 256, 256}, + {68, 66, 67, 65, 128, 271, 271, 271, /*8*/255, 255, 256, 256, 256, 256, 256, 256}, + {68, 66, 67, 65, 128, 255, 271, 271, /*8*/255, 255, 256, 255, 256, 256, 256, 256}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1040, 1040, 1040, 1040, 1058, 1096, 1091, 1091, + /*8*/1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091}, + {1040, 1040, 1040, 1040, 1058, 1091, 1091, 1091, + /*8*/1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091}, + {1040, 1040, 1040, 1040, 1057, 1096, 1096, 1096, + /*8*/1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091}, + {1040, 1040, 1040, 1040, 1057, 1091, 1096, 1096, + /*8*/1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091}, +#endif + }, + }, +}; + +struct combo_dev_attr_s f23_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, +#ifdef FPGA_PORTING + .lane_id = {0, 4, -1, -1, -1}, +#else + .lane_id = {1, 0, 2, -1, -1}, +#endif +// .wdr_mode = CVI_MIPI_WDR_MODE_MANUAL, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __F23_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_f23/f23_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/soi_f23/f23_sensor_ctl.c new file mode 100644 index 000000000..8ae66aa0a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_f23/f23_sensor_ctl.c @@ -0,0 +1,427 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "f23_cmos_ex.h" + +static void f23_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void f23_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 f23_i2c_addr = 0x40; /* I2C Address of F23 */ +const CVI_U32 f23_addr_byte = 1; +const CVI_U32 f23_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int f23_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunF23_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, f23_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int f23_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int f23_read_register(VI_PIPE ViPipe, int addr) +{ + /* TODO:*/ + (void) ViPipe; + (void) addr; + + return CVI_SUCCESS; +} + + +int f23_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (f23_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (f23_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, f23_addr_byte + f23_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void f23_standby(VI_PIPE ViPipe) +{ + f23_write_register(ViPipe, 0x12, 0x40); +} + +void f23_restart(VI_PIPE ViPipe) +{ + f23_write_register(ViPipe, 0x12, 0x40); + delay_ms(20); + f23_write_register(ViPipe, 0x12, 0x00); +} + +void f23_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastF23[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + f23_write_register(ViPipe, + g_pastF23[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastF23[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void f23_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + CVI_U8 u8ImgMode; + + bInit = g_pastF23[ViPipe]->bInit; + enWDRMode = g_pastF23[ViPipe]->enWDRMode; + u8ImgMode = g_pastF23[ViPipe]->u8ImgMode; + + f23_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == F23_MODE_1080P30_WDR) { + /* F23_MODE_1080P30_WDR */ + f23_wdr_1080p30_2to1_init(ViPipe); + } else { + } + } else { + f23_linear_1080p30_init(ViPipe); + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == F23_MODE_1080P30_WDR) { + /* F23_MODE_1080P30_WDR */ + f23_wdr_1080p30_2to1_init(ViPipe); + } else { + } + } else { + f23_linear_1080p30_init(ViPipe); + } + } + g_pastF23[ViPipe]->bInit = CVI_TRUE; +} + +void f23_exit(VI_PIPE ViPipe) +{ + f23_i2c_exit(ViPipe); +} + +#ifdef FPGA_PORTING +static void f23_linear_1080p30_init(VI_PIPE ViPipe) +{ + f23_write_register(ViPipe, 0x12, 0x80); + delay_ms(15); + f23_write_register(ViPipe, 0x0E, 0x11); + f23_write_register(ViPipe, 0x0F, 0x14); + f23_write_register(ViPipe, 0x10, 0x40); + f23_write_register(ViPipe, 0x11, 0x80); + f23_write_register(ViPipe, 0x48, 0x05); + f23_write_register(ViPipe, 0x96, 0xAA); + f23_write_register(ViPipe, 0x94, 0xC0); + f23_write_register(ViPipe, 0x97, 0x8D); + f23_write_register(ViPipe, 0x96, 0x00); + f23_write_register(ViPipe, 0x12, 0x40); + f23_write_register(ViPipe, 0x48, 0x8A); + f23_write_register(ViPipe, 0x48, 0x0A); + f23_write_register(ViPipe, 0x0E, 0x11); + f23_write_register(ViPipe, 0x0F, 0x14); + +// f23_write_register(ViPipe, 0x10, 0x20); + f23_write_register(ViPipe, 0x10, 0x12); // VCO for FPGA + f23_write_register(ViPipe, 0x11, 0x80); + f23_write_register(ViPipe, 0x0D, 0xA0); + f23_write_register(ViPipe, 0x5F, 0x42); + f23_write_register(ViPipe, 0x60, 0x2B); + f23_write_register(ViPipe, 0x58, 0x12); + f23_write_register(ViPipe, 0x57, 0x60); + f23_write_register(ViPipe, 0x9D, 0x00); +// f23_write_register(ViPipe, 0x20, 0x00); +// f23_write_register(ViPipe, 0x21, 0x05); + f23_write_register(ViPipe, 0x20, 0x00); + f23_write_register(ViPipe, 0x21, 0x1e); // for FPGA, FrameW + f23_write_register(ViPipe, 0x22, 0x65); + f23_write_register(ViPipe, 0x23, 0x04); // FrameH + f23_write_register(ViPipe, 0x24, 0xC0); + f23_write_register(ViPipe, 0x25, 0x38); + f23_write_register(ViPipe, 0x26, 0x43); + f23_write_register(ViPipe, 0x27, 0xC3); + f23_write_register(ViPipe, 0x28, 0x19); + f23_write_register(ViPipe, 0x29, 0x04); + f23_write_register(ViPipe, 0x2C, 0x00); + f23_write_register(ViPipe, 0x2D, 0x00); + f23_write_register(ViPipe, 0x2E, 0x18); + f23_write_register(ViPipe, 0x2F, 0x44); + f23_write_register(ViPipe, 0x41, 0xC9); + f23_write_register(ViPipe, 0x42, 0x13); + f23_write_register(ViPipe, 0x46, 0x00); + f23_write_register(ViPipe, 0x76, 0x60); + f23_write_register(ViPipe, 0x77, 0x09); + f23_write_register(ViPipe, 0x1D, 0x00); + f23_write_register(ViPipe, 0x1E, 0x04); + f23_write_register(ViPipe, 0x6C, 0x50); // 1-lane +// f23_write_register(ViPipe, 0x6C, 0x40); // 2-lane + + f23_write_register(ViPipe, 0x68, 0x00); + f23_write_register(ViPipe, 0x6E, 0x2C); + f23_write_register(ViPipe, 0x70, 0x6C); + f23_write_register(ViPipe, 0x71, 0x6D); + f23_write_register(ViPipe, 0x72, 0x6A); + f23_write_register(ViPipe, 0x73, 0x36); + f23_write_register(ViPipe, 0x74, 0x02); + f23_write_register(ViPipe, 0x78, 0x9E); + f23_write_register(ViPipe, 0x89, 0x01); + f23_write_register(ViPipe, 0x6B, 0x20); + f23_write_register(ViPipe, 0x86, 0x40); + f23_write_register(ViPipe, 0x2A, 0xB1); + f23_write_register(ViPipe, 0x2B, 0x24); + f23_write_register(ViPipe, 0x31, 0x08); + f23_write_register(ViPipe, 0x32, 0x4F); + f23_write_register(ViPipe, 0x33, 0x20); + f23_write_register(ViPipe, 0x34, 0x5E); + f23_write_register(ViPipe, 0x35, 0x5E); + f23_write_register(ViPipe, 0x3A, 0xAF); + f23_write_register(ViPipe, 0x56, 0x32); + f23_write_register(ViPipe, 0x59, 0xBF); + f23_write_register(ViPipe, 0x5A, 0x04); + f23_write_register(ViPipe, 0x85, 0x5A); + f23_write_register(ViPipe, 0x8A, 0x04); + f23_write_register(ViPipe, 0x8F, 0x90); + f23_write_register(ViPipe, 0x91, 0x13); + f23_write_register(ViPipe, 0x5B, 0xA0); + f23_write_register(ViPipe, 0x5C, 0xF0); + f23_write_register(ViPipe, 0x5D, 0xFC); + f23_write_register(ViPipe, 0x5E, 0x1F); + f23_write_register(ViPipe, 0x62, 0x04); + f23_write_register(ViPipe, 0x63, 0x0F); + f23_write_register(ViPipe, 0x64, 0xC0); + f23_write_register(ViPipe, 0x66, 0x44); + f23_write_register(ViPipe, 0x67, 0x73); + f23_write_register(ViPipe, 0x69, 0x7C); + f23_write_register(ViPipe, 0x6A, 0x28); + f23_write_register(ViPipe, 0x7A, 0xC0); + f23_write_register(ViPipe, 0x4A, 0x05); + f23_write_register(ViPipe, 0x7E, 0xCD); + f23_write_register(ViPipe, 0x49, 0x10); + f23_write_register(ViPipe, 0x50, 0x02); + f23_write_register(ViPipe, 0x7B, 0x4A); + f23_write_register(ViPipe, 0x7C, 0x0C); + f23_write_register(ViPipe, 0x7F, 0x57); + f23_write_register(ViPipe, 0x90, 0x00); + f23_write_register(ViPipe, 0x8E, 0x00); + f23_write_register(ViPipe, 0x8C, 0xFF); + f23_write_register(ViPipe, 0x8D, 0xC7); + f23_write_register(ViPipe, 0x8B, 0x01); + f23_write_register(ViPipe, 0x0C, 0x40); // bit0: test pattern + f23_write_register(ViPipe, 0x65, 0x02); + f23_write_register(ViPipe, 0x80, 0x1A); + f23_write_register(ViPipe, 0x81, 0xC0); + f23_write_register(ViPipe, 0x19, 0x20); + f23_write_register(ViPipe, 0x99, 0x0F); + f23_write_register(ViPipe, 0x9B, 0x0F); + + //f23_default_reg_init(ViPipe); + + f23_write_register(ViPipe, 0x12, 0x00); + f23_write_register(ViPipe, 0x48, 0x8A); + f23_write_register(ViPipe, 0x48, 0x0A); + + printf("ViPipe:%d,===F23 1080P 30fps 10bit LINE FPGA Init OK!===\n", ViPipe); +} +#else +/* 1080P30 and 1080P25 */ +static void f23_linear_1080p30_init(VI_PIPE ViPipe) +{ + f23_write_register(ViPipe, 0x12, 0x80); + delay_ms(15); + f23_write_register(ViPipe, 0x0E, 0x11); + f23_write_register(ViPipe, 0x0F, 0x14); + f23_write_register(ViPipe, 0x10, 0x40); + f23_write_register(ViPipe, 0x11, 0x80); + f23_write_register(ViPipe, 0x48, 0x05); + f23_write_register(ViPipe, 0x96, 0xAA); + f23_write_register(ViPipe, 0x94, 0xC0); + f23_write_register(ViPipe, 0x97, 0x8D); + f23_write_register(ViPipe, 0x96, 0x00); + f23_write_register(ViPipe, 0x12, 0x40); + f23_write_register(ViPipe, 0x48, 0x8A); + f23_write_register(ViPipe, 0x48, 0x0A); + f23_write_register(ViPipe, 0x0E, 0x11); + f23_write_register(ViPipe, 0x0F, 0x14); + + f23_write_register(ViPipe, 0x10, 0x20); +// f23_write_register(ViPipe, 0x10, 0x12); // VCO for FPGA + f23_write_register(ViPipe, 0x11, 0x80); + f23_write_register(ViPipe, 0x0D, 0xA0); // for FPGA driving upto max + f23_write_register(ViPipe, 0x5F, 0x42); + f23_write_register(ViPipe, 0x60, 0x2B); + f23_write_register(ViPipe, 0x58, 0x12); + f23_write_register(ViPipe, 0x57, 0x60); + f23_write_register(ViPipe, 0x9D, 0x00); + f23_write_register(ViPipe, 0x20, 0x00); + f23_write_register(ViPipe, 0x21, 0x05); + // f23_write_register(ViPipe, 0x20, 0x00); + // f23_write_register(ViPipe, 0x21, 0x1e); // for FPGA, FrameW + f23_write_register(ViPipe, 0x22, 0x65); + f23_write_register(ViPipe, 0x23, 0x04); // FrameH + f23_write_register(ViPipe, 0x24, 0xC0); + f23_write_register(ViPipe, 0x25, 0x38); + f23_write_register(ViPipe, 0x26, 0x43); + f23_write_register(ViPipe, 0x27, 0xC3); + f23_write_register(ViPipe, 0x28, 0x19); + f23_write_register(ViPipe, 0x29, 0x04); + f23_write_register(ViPipe, 0x2C, 0x00); + f23_write_register(ViPipe, 0x2D, 0x00); + f23_write_register(ViPipe, 0x2E, 0x18); + f23_write_register(ViPipe, 0x2F, 0x44); + f23_write_register(ViPipe, 0x41, 0xC9); + f23_write_register(ViPipe, 0x42, 0x13); + f23_write_register(ViPipe, 0x46, 0x00); + f23_write_register(ViPipe, 0x76, 0x60); + f23_write_register(ViPipe, 0x77, 0x09); + f23_write_register(ViPipe, 0x1D, 0x00); + f23_write_register(ViPipe, 0x1E, 0x04); +// f23_write_register(ViPipe, 0x6C, 0x50); // 1-lane + f23_write_register(ViPipe, 0x6C, 0x40); // 2-lane + + f23_write_register(ViPipe, 0x68, 0x00); + f23_write_register(ViPipe, 0x6E, 0x2C); + f23_write_register(ViPipe, 0x70, 0x6C); + f23_write_register(ViPipe, 0x71, 0x6D); + f23_write_register(ViPipe, 0x72, 0x6A); + f23_write_register(ViPipe, 0x73, 0x36); + f23_write_register(ViPipe, 0x74, 0x02); + f23_write_register(ViPipe, 0x78, 0x9E); + f23_write_register(ViPipe, 0x89, 0x01); + f23_write_register(ViPipe, 0x6B, 0x20); + f23_write_register(ViPipe, 0x86, 0x40); + f23_write_register(ViPipe, 0x2A, 0xB1); + f23_write_register(ViPipe, 0x2B, 0x24); + f23_write_register(ViPipe, 0x31, 0x08); + f23_write_register(ViPipe, 0x32, 0x4F); + f23_write_register(ViPipe, 0x33, 0x20); + f23_write_register(ViPipe, 0x34, 0x5E); + f23_write_register(ViPipe, 0x35, 0x5E); + f23_write_register(ViPipe, 0x3A, 0xAF); + f23_write_register(ViPipe, 0x56, 0x32); + f23_write_register(ViPipe, 0x59, 0xBF); + f23_write_register(ViPipe, 0x5A, 0x04); + f23_write_register(ViPipe, 0x85, 0x5A); + f23_write_register(ViPipe, 0x8A, 0x04); + f23_write_register(ViPipe, 0x8F, 0x90); + f23_write_register(ViPipe, 0x91, 0x13); + f23_write_register(ViPipe, 0x5B, 0xA0); + f23_write_register(ViPipe, 0x5C, 0xF0); + f23_write_register(ViPipe, 0x5D, 0xFC); + f23_write_register(ViPipe, 0x5E, 0x1F); + f23_write_register(ViPipe, 0x62, 0x04); + f23_write_register(ViPipe, 0x63, 0x0F); + f23_write_register(ViPipe, 0x64, 0xC0); + f23_write_register(ViPipe, 0x66, 0x44); + f23_write_register(ViPipe, 0x67, 0x73); + f23_write_register(ViPipe, 0x69, 0x7C); + f23_write_register(ViPipe, 0x6A, 0x28); + f23_write_register(ViPipe, 0x7A, 0xC0); + f23_write_register(ViPipe, 0x4A, 0x05); + f23_write_register(ViPipe, 0x7E, 0xCD); + f23_write_register(ViPipe, 0x49, 0x10); + f23_write_register(ViPipe, 0x50, 0x02); + f23_write_register(ViPipe, 0x7B, 0x4A); + f23_write_register(ViPipe, 0x7C, 0x0C); + f23_write_register(ViPipe, 0x7F, 0x57); + f23_write_register(ViPipe, 0x90, 0x00); + f23_write_register(ViPipe, 0x8E, 0x00); + f23_write_register(ViPipe, 0x8C, 0xFF); + f23_write_register(ViPipe, 0x8D, 0xC7); + f23_write_register(ViPipe, 0x8B, 0x01); + f23_write_register(ViPipe, 0x0C, 0x40); // bit0: test pattern + f23_write_register(ViPipe, 0x65, 0x02); + f23_write_register(ViPipe, 0x80, 0x1A); + f23_write_register(ViPipe, 0x81, 0xC0); + f23_write_register(ViPipe, 0x19, 0x20); + f23_write_register(ViPipe, 0x99, 0x0F); + f23_write_register(ViPipe, 0x9B, 0x0F); + + //f23_default_reg_init(ViPipe); + + f23_write_register(ViPipe, 0x12, 0x00); + f23_write_register(ViPipe, 0x48, 0x8A); + f23_write_register(ViPipe, 0x48, 0x0A); + + printf("ViPipe:%d,===F23 1080P 30fps 10bit LINE FPGA Init OK!===\n", ViPipe); +} +#endif + +static void f23_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + (void) ViPipe; + + printf("===F23 sensor 1080P30fps HDR not support yet!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_f35/Makefile b/middleware/v2/component/isp/sensor/cv180x/soi_f35/Makefile new file mode 100644 index 000000000..43d630ab4 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_f35/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_f35.a +TARGET_SO = $(MW_LIB)/libsns_f35.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_f35/f35_cmos.c b/middleware/v2/component/isp/sensor/cv180x/soi_f35/f35_cmos.c new file mode 100644 index 000000000..492682bc2 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_f35/f35_cmos.c @@ -0,0 +1,1025 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "f35_cmos_ex.h" +#include "f35_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define F35_ID 35 +#define SENSOR_F35_WIDTH 1920 +#define SENSOR_F35_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastF35[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define F35_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastF35[dev]) +#define F35_SENSOR_SET_CTX(dev, pstCtx) (g_pastF35[dev] = pstCtx) +#define F35_SENSOR_RESET_CTX(dev) (g_pastF35[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunF35_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16F35_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16F35_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +F35_STATE_S g_astF35_State[VI_MAX_PIPE_NUM] = {{0} }; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****F35 Lines Range*****/ +#define F35_FULL_LINES_MAX (0xFFFF) +#define F35_FULL_LINES_MAX_2TO1_WDR (0xFFFF) + +/*****F35 Register Address*****/ +#define F35_SHS1_ADDR 0x01 +#define F35_SHS2_ADDR 0x05 +#define F35_GAIN_ADDR 0x00 +#define F35_DGAIN_ADDR 0x0D +#define F35_VMAX_ADDR 0x22 +#define F35_L2S_ADDR 0xAA +#define F35_TABLE_END 0xff + +#define F35_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = F35_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 2; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stDgainAccu.f32Accuracy = 6; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + pstAeSnsDft->enBlcType = AE_BLC_TYPE_LADDER; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astF35_mode[F35_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astF35_mode[F35_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 15872; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 4096; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + pstAeSnsDft->u32AEResponseFrame = 4; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astF35_mode[F35_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astF35_mode[F35_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstAeSnsDft->u32MinIntTime = 1; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 15872; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 4096; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astF35_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astF35_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astF35_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case F35_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > F35_FULL_LINES_MAX_2TO1_WDR) ? F35_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case F35_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > F35_FULL_LINES_MAX) ? F35_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + /* maximum sexp = 2 * reg_AA + 1 - 8. */ + CVI_U32 SexpLimit = g_astF35_mode[pstSnsState->u8ImgMode].u32L2S_MAX - 4; + + g_astF35_State[ViPipe].u32Sexp_MAX = SexpLimit * 2 + 1; + syslog(LOG_DEBUG, "VMAX %d, MAX_SEXP %d\n", u32VMAX, g_astF35_State[ViPipe].u32Sexp_MAX); + } + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_DATA].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_DATA].u32Data = ((u32VMAX & 0xFF00) >> 8); + } else { + pstSnsRegsInfo->astI2cData[WDR2_VMAX_0_DATA].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_VMAX_1_DATA].u32Data = ((u32VMAX & 0xFF00) >> 8); + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + CVI_U8 u8SexpReg; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = (u32ShortIntTime > g_astF35_State[ViPipe].u32Sexp_MAX) ? + g_astF35_State[ViPipe].u32Sexp_MAX : u32ShortIntTime; + if (!pstSnsState->au32WDRIntTime[0]) + pstSnsState->au32WDRIntTime[0] = 1; + /* short exp = SexpReg * 2 + 1 */ + u8SexpReg = (pstSnsState->au32WDRIntTime[0] - 1) >> 1; + pstSnsState->au32WDRIntTime[0] = (u8SexpReg << 1) + 1; + g_astF35_State[ViPipe].u8SexpReg = u8SexpReg; + + /* long exposure must be odd number. */ + if (!(u32LongIntTime & 0x1)) + u32LongIntTime = (u32LongIntTime > 1) ? u32LongIntTime - 1 : 1; + pstSnsState->au32WDRIntTime[1] = u32LongIntTime; + + if ((pstSnsState->au32WDRIntTime[0] + pstSnsState->au32WDRIntTime[1]) > pstSnsState->au32FL[0]) { + CVI_TRACE_SNS(CVI_DBG_ERR, "inttime over spec [%u, %u, %u]\n", + pstSnsState->au32WDRIntTime[0], + pstSnsState->au32WDRIntTime[1], + pstSnsState->au32FL[0]); + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[0] - pstSnsState->au32WDRIntTime[0]; + } + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + pstSnsRegsInfo->astI2cData[WDR2_SHS1_0_DATA].u32Data = (pstSnsState->au32WDRIntTime[1] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_SHS1_1_DATA].u32Data = ((pstSnsState->au32WDRIntTime[1] & 0xFF00) >> 8); + + pstSnsRegsInfo->astI2cData[WDR2_SHS2_DATA].u32Data = (u8SexpReg & 0xFF); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if ((u32IntTime[0] + 5) > pstSnsState->au32FL[0]) { + CVI_TRACE_SNS(CVI_DBG_ERR, "inttime over spec [%u, %u]\n", + u32IntTime[0], + pstSnsState->au32FL[0]); + return CVI_FAILURE; + } + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_DATA].u32Data = (u32IntTime[0] & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_DATA].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[64] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[63]) { + *pu32AgainLin = gain_table[63]; + *pu32AgainDb = 63; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin < 2048) { + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + } else if (*pu32DgainLin < 4096) { + *pu32DgainLin = 2048; + *pu32DgainDb = 1; + } else { + *pu32DgainLin = 4096; + *pu32DgainDb = 3; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0] | g_astF35_mode[pstSnsState->u8ImgMode].u8DgainReg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_DATA].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_DATA].u32Data = (u32Dgain & 0xFF); + } else { + /* DOL mode */ + pstSnsRegsInfo->astI2cData[WDR2_AGAIN_DATA].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN_DATA].u32Data = (u32Dgain & 0xFF); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0; + CVI_U32 u32ShortTimeMinLimit = 1; + + (void) u16ManRatioEnable; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32IntTimeMaxTmp = (pstSnsState->au32FL[0] * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > g_astF35_State[ViPipe].u32Sexp_MAX) ? + g_astF35_State[ViPipe].u32Sexp_MAX : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const F35_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astF35_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == F35_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = F35_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astF35_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == F35_MODE_1080P30) + pstSnsState->u8ImgMode = F35_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astF35_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "2to1 line WDR 1080p mode(60fps->30fps)\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunF35_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = f35_i2c_addr; + pstI2c_data[i].u32AddrByteNum = f35_addr_byte; + pstI2c_data[i].u32DataByteNum = f35_data_byte; + } + + //DOL 2t1 Mode Regs + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + //Linear Mode Regs + pstI2c_data[WDR2_SHS1_0_DATA].u32RegAddr = F35_SHS1_ADDR; + + pstI2c_data[WDR2_SHS1_1_DATA].u32RegAddr = F35_SHS1_ADDR + 1; + + pstI2c_data[WDR2_SHS2_DATA].u32RegAddr = F35_SHS2_ADDR; + + pstI2c_data[WDR2_AGAIN_DATA].u32RegAddr = F35_GAIN_ADDR; + + pstI2c_data[WDR2_DGAIN_DATA].u32RegAddr = F35_DGAIN_ADDR; + pstI2c_data[WDR2_DGAIN_DATA].u8DelayFrmNum = 2; + + pstI2c_data[WDR2_VMAX_0_DATA].u32RegAddr = F35_VMAX_ADDR; + pstI2c_data[WDR2_VMAX_0_DATA].u8DelayFrmNum = 2; + + pstI2c_data[WDR2_VMAX_1_DATA].u32RegAddr = F35_VMAX_ADDR + 1; + pstI2c_data[WDR2_VMAX_1_DATA].u8DelayFrmNum = 2; + + break; + default: + pstI2c_data[LINEAR_SHS1_0_DATA].u32RegAddr = F35_SHS1_ADDR; + + pstI2c_data[LINEAR_SHS1_1_DATA].u32RegAddr = F35_SHS1_ADDR + 1; + + pstI2c_data[LINEAR_AGAIN_DATA].u32RegAddr = F35_GAIN_ADDR; + + pstI2c_data[LINEAR_DGAIN_DATA].u32RegAddr = F35_DGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_DATA].u8DelayFrmNum = 2; + + pstI2c_data[LINEAR_VMAX_0_DATA].u32RegAddr = F35_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_0_DATA].u8DelayFrmNum = 2; + + pstI2c_data[LINEAR_VMAX_1_DATA].u32RegAddr = F35_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_1_DATA].u8DelayFrmNum = 2; + + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (F35_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = F35_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (F35_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = F35_MODE_1080P30_WDR; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const F35_MODE_S *pstMode = CVI_NULL; + + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = F35_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astF35_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &f35_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astF35_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astF35_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &f35_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = f35_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = f35_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 f35_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunF35_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + F35_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + F35_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + F35_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + F35_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = F35_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, F35_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, F35_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, F35_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16F35_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16F35_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsF35_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = f35_standby, + .pfnRestart = f35_restart, + .pfnMirrorFlip = CVI_NULL, + .pfnWriteReg = f35_write_register, + .pfnReadReg = f35_read_register, + .pfnSetBusInfo = f35_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_f35/f35_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/soi_f35/f35_cmos_ex.h new file mode 100644 index 000000000..d57c93471 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_f35/f35_cmos_ex.h @@ -0,0 +1,94 @@ +#ifndef __F35_CMOS_EX_H_ +#define __F35_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum f35_linear_regs_e { + LINEAR_SHS1_0_DATA, + LINEAR_SHS1_1_DATA, + LINEAR_AGAIN_DATA, + LINEAR_DGAIN_DATA, + LINEAR_VMAX_0_DATA, + LINEAR_VMAX_1_DATA, + LINEAR_REGS_NUM +}; + +enum f35_dol2_regs_e { + WDR2_SHS1_0_DATA, + WDR2_SHS1_1_DATA, + WDR2_SHS2_DATA, + WDR2_AGAIN_DATA, + WDR2_DGAIN_DATA, + WDR2_VMAX_0_DATA, + WDR2_VMAX_1_DATA, + WDR2_REGS_NUM +}; + +typedef enum _F35_MODE_E { + F35_MODE_1080P30 = 0, + F35_MODE_LINEAR_NUM, + F35_MODE_1080P30_WDR = F35_MODE_LINEAR_NUM, + F35_MODE_NUM +} F35_MODE_E; + +typedef struct _F35_STATE_S { + CVI_U32 u8SexpReg; + CVI_U32 u32Sexp_MAX; +} F35_STATE_S; + +typedef struct _F35_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + CVI_U32 u32L2S_MAX; + char name[64]; +} F35_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastF35[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunF35_BusInfo[]; +extern CVI_U16 g_au16F35_GainMode[]; +extern CVI_U16 g_au16F35_L2SMode[]; +extern const CVI_U8 f35_i2c_addr; +extern const CVI_U32 f35_addr_byte; +extern const CVI_U32 f35_data_byte; +extern void f35_init(VI_PIPE ViPipe); +extern void f35_exit(VI_PIPE ViPipe); +extern void f35_standby(VI_PIPE ViPipe); +extern void f35_restart(VI_PIPE ViPipe); +extern int f35_write_register(VI_PIPE ViPipe, int addr, int data); +extern int f35_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __F35_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_f35/f35_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/soi_f35/f35_cmos_param.h new file mode 100644 index 000000000..d555b50c6 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_f35/f35_cmos_param.h @@ -0,0 +1,299 @@ +#ifndef __F35_CMOS_PARAM_H_ +#define __F35_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "f35_cmos_ex.h" + +static const F35_MODE_S g_astF35_mode[F35_MODE_NUM] = { + [F35_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.52, /* 1125 * 30 / 0xFFFF */ + .u32HtsDef = 2560, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1120, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 4096, + .u16Def = 1024, + .u16Step = 1, + }, + .u8DgainReg = 0xF0, + }, + [F35_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.03, /* 2250 * 30 / 0xFFFF */ + .u32HtsDef = 600, + .u32VtsDef = 2250, + .stExp[0] = { + .u16Min = 1, + .u16Max = 131, + .u16Def = 13, + .u16Step = 2, + }, + .stExp[1] = { + .u16Min = 132, + .u16Max = 2096, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 4096, + .u16Def = 1024, + .u16Step = 1, + }, + .u8DgainReg = 0xF0, + .u32L2S_MAX = 0xFC, + }, +}; + +ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.04988861083984375000, 4.38765525817871093750}, //B: slope, intercept + {0.04792890325188636780, 3.92597246170043945313}, //Gb: slope, intercept + {0.04811932146549224854, 3.89808440208435058594}, //Gr: slope, intercept + {0.05060157552361488342, 4.38360261917114257813}, //R: slope, intercept + }, + { //iso 200 + {0.05668020620942115784, 8.36383914947509765625}, //B: slope, intercept + {0.05190096050500869751, 9.12379550933837890625}, //Gb: slope, intercept + {0.05187550559639930725, 9.15234565734863281250}, //Gr: slope, intercept + {0.05625439062714576721, 8.55138778686523437500}, //R: slope, intercept + }, + { //iso 400 + {0.06673676520586013794, 14.12210369110107421875}, //B: slope, intercept + {0.05751207098364830017, 16.82577514648437500000}, //Gb: slope, intercept + {0.05804729461669921875, 16.61601066589355468750}, //Gr: slope, intercept + {0.06506298482418060303, 14.56138515472412109375}, //R: slope, intercept + }, + { //iso 800 + {0.08542215079069137573, 21.73256301879882812500}, //B: slope, intercept + {0.06953971832990646362, 27.63131332397460937500}, //Gb: slope, intercept + {0.06944745033979415894, 27.69048118591308593750}, //Gr: slope, intercept + {0.08224378526210784912, 22.75174522399902343750}, //R: slope, intercept + }, + { //iso 1600 + {0.10555629432201385498, 33.52949905395507812500}, //B: slope, intercept + {0.08282581716775894165, 43.78954315185546875000}, //Gb: slope, intercept + {0.08244660496711730957, 43.95007705688476562500}, //Gr: slope, intercept + {0.09990881383419036865, 35.52837753295898437500}, //R: slope, intercept + }, + { //iso 3200 + {0.13504384458065032959, 52.07051086425781250000}, //B: slope, intercept + {0.10585222393274307251, 68.38363647460937500000}, //Gb: slope, intercept + {0.10607221722602844238, 68.20414733886718750000}, //Gr: slope, intercept + {0.12796562910079956055, 55.04695510864257812500}, //R: slope, intercept + }, + { //iso 6400 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 12800 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 25600 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 51200 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 102400 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 204800 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 409600 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 819200 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 1638400 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 3276800 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {68, 68, 68, 68, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1096, 1096, 1096, 1096 +#endif + }, + .stAuto = { + {68, 66, 67, 65, 69, 135, 271, 255, 255, /*8*/255, 255, 255, 255, 256, 255, 256}, + {68, 66, 67, 65, 69, 135, 255, 255, 255, /*8*/255, 255, 255, 255, 256, 255, 256}, + {68, 66, 67, 65, 69, 128, 271, 271, 271, /*8*/255, 255, 256, 256, 256, 256, 256}, + {68, 66, 67, 65, 69, 128, 255, 271, 271, /*8*/255, 255, 256, 255, 256, 256, 256}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1040, 1040, 1040, 1040, 1042, 1059, 1097, 1091, + /*8*/1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091}, + {1040, 1040, 1040, 1040, 1042, 1059, 1092, 1091, + /*8*/1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091}, + {1040, 1040, 1040, 1040, 1042, 1057, 1097, 1096, + /*8*/1091, 1091, 1091, 1091, 1097, 1091, 1091, 1091}, + {1040, 1040, 1040, 1040, 1042, 1057, 1092, 1096, + /*8*/1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091}, +#endif + }, + }, +}; + +struct combo_dev_attr_s f35_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {3, 4, 0, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __F35_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_f35/f35_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/soi_f35/f35_sensor_ctl.c new file mode 100644 index 000000000..4d8eb2162 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_f35/f35_sensor_ctl.c @@ -0,0 +1,396 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "f35_cmos_ex.h" + +static void f35_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void f35_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 f35_i2c_addr = 0x40; /* I2C Address of F35 */ +const CVI_U32 f35_addr_byte = 1; +const CVI_U32 f35_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int f35_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunF35_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, f35_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int f35_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int f35_read_register(VI_PIPE ViPipe, int addr) +{ + /* TODO:*/ + (void) ViPipe; + (void) addr; + + return CVI_SUCCESS; +} + + +int f35_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (f35_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (f35_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, f35_addr_byte + f35_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void f35_standby(VI_PIPE ViPipe) +{ + f35_write_register(ViPipe, 0x12, 0x40); +} + +void f35_restart(VI_PIPE ViPipe) +{ + f35_write_register(ViPipe, 0x12, 0x40); + delay_ms(20); + f35_write_register(ViPipe, 0x12, 0x00); +} + +void f35_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastF35[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + f35_write_register(ViPipe, + g_pastF35[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastF35[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void f35_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + CVI_U8 u8ImgMode; + + bInit = g_pastF35[ViPipe]->bInit; + enWDRMode = g_pastF35[ViPipe]->enWDRMode; + u8ImgMode = g_pastF35[ViPipe]->u8ImgMode; + + f35_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == F35_MODE_1080P30_WDR) { + /* F35_MODE_1080P30_WDR */ + f35_wdr_1080p30_2to1_init(ViPipe); + } else { + } + } else { + f35_linear_1080p30_init(ViPipe); + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == F35_MODE_1080P30_WDR) { + /* F35_MODE_1080P30_WDR */ + f35_wdr_1080p30_2to1_init(ViPipe); + } else { + } + } else { + f35_linear_1080p30_init(ViPipe); + } + } + g_pastF35[ViPipe]->bInit = CVI_TRUE; +} + +void f35_exit(VI_PIPE ViPipe) +{ + f35_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void f35_linear_1080p30_init(VI_PIPE ViPipe) +{ + f35_write_register(ViPipe, 0x12, 0x40); + f35_write_register(ViPipe, 0x48, 0x8A); + f35_write_register(ViPipe, 0x48, 0x0A); + f35_write_register(ViPipe, 0x0E, 0x11); + f35_write_register(ViPipe, 0x0F, 0x14); + f35_write_register(ViPipe, 0x10, 0x20); + f35_write_register(ViPipe, 0x11, 0x80); + f35_write_register(ViPipe, 0x0D, 0xF0); + f35_write_register(ViPipe, 0x5F, 0x42); + f35_write_register(ViPipe, 0x60, 0x2B); + f35_write_register(ViPipe, 0x58, 0x18); + f35_write_register(ViPipe, 0x57, 0x60); + f35_write_register(ViPipe, 0x64, 0xE0); + f35_write_register(ViPipe, 0x20, 0x00); + f35_write_register(ViPipe, 0x21, 0x05); + f35_write_register(ViPipe, 0x22, 0x65); + f35_write_register(ViPipe, 0x23, 0x04); + f35_write_register(ViPipe, 0x24, 0xC0); + f35_write_register(ViPipe, 0x25, 0x38); + f35_write_register(ViPipe, 0x26, 0x43); + f35_write_register(ViPipe, 0x27, 0x0C); + f35_write_register(ViPipe, 0x28, 0x15); + f35_write_register(ViPipe, 0x29, 0x02); + f35_write_register(ViPipe, 0x2A, 0x00); + f35_write_register(ViPipe, 0x2B, 0x12); + f35_write_register(ViPipe, 0x2C, 0x00); + f35_write_register(ViPipe, 0x2D, 0x00); + f35_write_register(ViPipe, 0x2E, 0x14); + f35_write_register(ViPipe, 0x2F, 0x44); + f35_write_register(ViPipe, 0x41, 0xC4); + f35_write_register(ViPipe, 0x42, 0x13); + f35_write_register(ViPipe, 0x46, 0x01); + f35_write_register(ViPipe, 0x76, 0x60); + f35_write_register(ViPipe, 0x77, 0x09); + f35_write_register(ViPipe, 0x80, 0x06); + f35_write_register(ViPipe, 0x1D, 0x00); + f35_write_register(ViPipe, 0x1E, 0x04); + f35_write_register(ViPipe, 0x6C, 0x40); + f35_write_register(ViPipe, 0x68, 0x00); + f35_write_register(ViPipe, 0x70, 0x6D); + f35_write_register(ViPipe, 0x71, 0xCD); + f35_write_register(ViPipe, 0x72, 0x6A); + f35_write_register(ViPipe, 0x73, 0x36); + f35_write_register(ViPipe, 0x74, 0x02); + f35_write_register(ViPipe, 0x78, 0x1E); + f35_write_register(ViPipe, 0x89, 0x81); + f35_write_register(ViPipe, 0x6E, 0x2C); + f35_write_register(ViPipe, 0x32, 0x4F); + f35_write_register(ViPipe, 0x33, 0x58); + f35_write_register(ViPipe, 0x34, 0x5F); + f35_write_register(ViPipe, 0x35, 0x5F); + f35_write_register(ViPipe, 0x3A, 0xAF); + f35_write_register(ViPipe, 0x3B, 0x00); + f35_write_register(ViPipe, 0x3C, 0x70); + f35_write_register(ViPipe, 0x3D, 0x8F); + f35_write_register(ViPipe, 0x3E, 0xFF); + f35_write_register(ViPipe, 0x3F, 0x85); + f35_write_register(ViPipe, 0x40, 0xFF); + f35_write_register(ViPipe, 0x56, 0x32); + f35_write_register(ViPipe, 0x59, 0x67); + f35_write_register(ViPipe, 0x85, 0x3C); + f35_write_register(ViPipe, 0x8A, 0x04); + f35_write_register(ViPipe, 0x91, 0x10); + f35_write_register(ViPipe, 0x9C, 0xE1); + f35_write_register(ViPipe, 0x5A, 0x09); + f35_write_register(ViPipe, 0x5C, 0x4C); + f35_write_register(ViPipe, 0x5D, 0xF4); + f35_write_register(ViPipe, 0x5E, 0x1E); + f35_write_register(ViPipe, 0x62, 0x04); + f35_write_register(ViPipe, 0x63, 0x0F); + f35_write_register(ViPipe, 0x66, 0x04); + f35_write_register(ViPipe, 0x67, 0x30); + f35_write_register(ViPipe, 0x6A, 0x12); + f35_write_register(ViPipe, 0x7A, 0xA0); + f35_write_register(ViPipe, 0x9D, 0x10); + f35_write_register(ViPipe, 0x4A, 0x05); + f35_write_register(ViPipe, 0x7E, 0xCD); + f35_write_register(ViPipe, 0x50, 0x02); + f35_write_register(ViPipe, 0x49, 0x10); + f35_write_register(ViPipe, 0x47, 0x02); + f35_write_register(ViPipe, 0x7B, 0x4A); + f35_write_register(ViPipe, 0x7C, 0x0C); + f35_write_register(ViPipe, 0x7F, 0x57); + f35_write_register(ViPipe, 0x8F, 0x81); + f35_write_register(ViPipe, 0x90, 0x00); + f35_write_register(ViPipe, 0x8C, 0xFF); + f35_write_register(ViPipe, 0x8D, 0xC7); + f35_write_register(ViPipe, 0x8E, 0x00); + f35_write_register(ViPipe, 0x8B, 0x01); + f35_write_register(ViPipe, 0x0C, 0x00); + f35_write_register(ViPipe, 0x69, 0x74); + f35_write_register(ViPipe, 0x65, 0x02); + f35_write_register(ViPipe, 0x81, 0x74); + f35_write_register(ViPipe, 0x19, 0x20); + + f35_default_reg_init(ViPipe); + + f35_write_register(ViPipe, 0x12, 0x00); + + printf("ViPipe:%d,===F35 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +static void f35_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + f35_write_register(ViPipe, 0x12, 0x48); + f35_write_register(ViPipe, 0x48, 0x96); + f35_write_register(ViPipe, 0x48, 0x16); + f35_write_register(ViPipe, 0x0E, 0x11); + f35_write_register(ViPipe, 0x0F, 0x14); + f35_write_register(ViPipe, 0x10, 0x3C); + f35_write_register(ViPipe, 0x11, 0x80); + f35_write_register(ViPipe, 0x0D, 0xF0); + f35_write_register(ViPipe, 0x5F, 0x42); + f35_write_register(ViPipe, 0x60, 0x2B); + f35_write_register(ViPipe, 0x58, 0x18); + f35_write_register(ViPipe, 0x57, 0x60); + f35_write_register(ViPipe, 0x64, 0xE0); + f35_write_register(ViPipe, 0x20, 0x58); + f35_write_register(ViPipe, 0x21, 0x02); + f35_write_register(ViPipe, 0x22, 0xCA); + f35_write_register(ViPipe, 0x23, 0x08); + f35_write_register(ViPipe, 0x24, 0xE0); + f35_write_register(ViPipe, 0x25, 0x38); + f35_write_register(ViPipe, 0x26, 0x41); + f35_write_register(ViPipe, 0x27, 0x07); + f35_write_register(ViPipe, 0x28, 0x25); + f35_write_register(ViPipe, 0x29, 0x02); + f35_write_register(ViPipe, 0x2A, 0x00); + f35_write_register(ViPipe, 0x2B, 0x12); + f35_write_register(ViPipe, 0x2C, 0x02); + f35_write_register(ViPipe, 0x2D, 0x00); + f35_write_register(ViPipe, 0x2E, 0x14); + f35_write_register(ViPipe, 0x2F, 0x44); + f35_write_register(ViPipe, 0x41, 0xC8); + f35_write_register(ViPipe, 0x42, 0x13); + f35_write_register(ViPipe, 0x46, 0x05); + f35_write_register(ViPipe, 0x76, 0x60); + f35_write_register(ViPipe, 0x77, 0x09); + f35_write_register(ViPipe, 0x80, 0x06); + f35_write_register(ViPipe, 0x1D, 0x00); + f35_write_register(ViPipe, 0x1E, 0x04); + f35_write_register(ViPipe, 0x6C, 0x40); + f35_write_register(ViPipe, 0x68, 0x00); + f35_write_register(ViPipe, 0x70, 0xDD); + f35_write_register(ViPipe, 0x71, 0xCB); + f35_write_register(ViPipe, 0x72, 0xD5); + f35_write_register(ViPipe, 0x73, 0x59); + f35_write_register(ViPipe, 0x74, 0x02); + f35_write_register(ViPipe, 0x78, 0x94); + f35_write_register(ViPipe, 0x89, 0x81); + f35_write_register(ViPipe, 0x6E, 0x2C); + f35_write_register(ViPipe, 0x84, 0x20); + f35_write_register(ViPipe, 0x6B, 0x20); + f35_write_register(ViPipe, 0x86, 0x40); + f35_write_register(ViPipe, 0x32, 0x4F); + f35_write_register(ViPipe, 0x33, 0x58); + f35_write_register(ViPipe, 0x34, 0x5F); + f35_write_register(ViPipe, 0x35, 0x5F); + f35_write_register(ViPipe, 0x3A, 0xAF); + f35_write_register(ViPipe, 0x3B, 0x00); + f35_write_register(ViPipe, 0x3C, 0x70); + f35_write_register(ViPipe, 0x3D, 0x8F); + f35_write_register(ViPipe, 0x3E, 0xFF); + f35_write_register(ViPipe, 0x3F, 0x85); + f35_write_register(ViPipe, 0x40, 0xFF); + f35_write_register(ViPipe, 0x56, 0x32); + f35_write_register(ViPipe, 0x59, 0x67); + f35_write_register(ViPipe, 0x85, 0x3C); + f35_write_register(ViPipe, 0x8A, 0x04); + f35_write_register(ViPipe, 0x91, 0x10); + f35_write_register(ViPipe, 0x9C, 0xE1); + f35_write_register(ViPipe, 0x5A, 0x09); + f35_write_register(ViPipe, 0x5C, 0x4C); + f35_write_register(ViPipe, 0x5D, 0xF4); + f35_write_register(ViPipe, 0x5E, 0x1E); + f35_write_register(ViPipe, 0x62, 0x04); + f35_write_register(ViPipe, 0x63, 0x0F); + f35_write_register(ViPipe, 0x66, 0x04); + f35_write_register(ViPipe, 0x67, 0x30); + f35_write_register(ViPipe, 0x6A, 0x12); + f35_write_register(ViPipe, 0x7A, 0xA0); + f35_write_register(ViPipe, 0x9D, 0x10); + f35_write_register(ViPipe, 0x4A, 0x05); + f35_write_register(ViPipe, 0x7E, 0xCD); + f35_write_register(ViPipe, 0x50, 0x02); + f35_write_register(ViPipe, 0x49, 0x10); + f35_write_register(ViPipe, 0x47, 0x02); + f35_write_register(ViPipe, 0x7B, 0x4A); + f35_write_register(ViPipe, 0x7C, 0x0C); + f35_write_register(ViPipe, 0x7F, 0x57); + f35_write_register(ViPipe, 0x8F, 0x81); + f35_write_register(ViPipe, 0x90, 0x00); + f35_write_register(ViPipe, 0x8C, 0xFF); + f35_write_register(ViPipe, 0x8D, 0xC7); + f35_write_register(ViPipe, 0x8E, 0x00); + f35_write_register(ViPipe, 0x8B, 0x01); + f35_write_register(ViPipe, 0x0C, 0x00); + f35_write_register(ViPipe, 0x69, 0x74); + f35_write_register(ViPipe, 0x65, 0x02); + f35_write_register(ViPipe, 0x81, 0x74); + f35_write_register(ViPipe, 0x19, 0x20); + f35_write_register(ViPipe, 0xA9, 0x14); + f35_write_register(ViPipe, 0xAA, 0xFF); // set l2s to max value + + f35_default_reg_init(ViPipe); + + if (g_au16F35_GainMode[ViPipe] == SNS_GAIN_MODE_ONLY_LEF) { + f35_write_register(ViPipe, 0x46, 0x01); + } else { + f35_write_register(ViPipe, 0x46, 0x05); + } + + f35_write_register(ViPipe, 0x12, 0x08); + + usleep(33*1000); + printf("===F35 sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_f37p/Makefile b/middleware/v2/component/isp/sensor/cv180x/soi_f37p/Makefile new file mode 100644 index 000000000..20147a162 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_f37p/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_f37p.a +TARGET_SO = $(MW_LIB)/libsns_f37p.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_f37p/f37p_cmos.c b/middleware/v2/component/isp/sensor/cv180x/soi_f37p/f37p_cmos.c new file mode 100644 index 000000000..de8095048 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_f37p/f37p_cmos.c @@ -0,0 +1,821 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "f37p_cmos_ex.h" +#include "f37p_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define F37P_ID 0x0841 +#define F37P_I2C_ADDR_1 0x40 +#define F37P_I2C_ADDR_2 0x42 +#define F37P_I2C_ADDR_3 0x44 +#define F37P_I2C_ADDR_4 0x46 +#define F37P_I2C_ADDR_IS_VALID(addr) ((addr) == F37P_I2C_ADDR_1 || (addr) == F37P_I2C_ADDR_2 \ + || (addr) == F37P_I2C_ADDR_3 || (addr) == F37P_I2C_ADDR_4) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastF37P[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define F37P_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastF37P[dev]) +#define F37P_SENSOR_SET_CTX(dev, pstCtx) (g_pastF37P[dev] = pstCtx) +#define F37P_SENSOR_RESET_CTX(dev) (g_pastF37P[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunF37P_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16F37P_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16F37P_L2SMode[VI_MAX_PIPE_NUM] = {0}; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeF37P_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****F37P Lines Range*****/ +#define F37P_FULL_LINES_MAX (0xFFFF) + +/*****F37P Register Address*****/ +#define F37P_EXP_ADDR 0x01 +#define F37P_GAIN_ADDR 0x00 +#define F37P_VMAX_ADDR 0x22 +#define F37P_BLC_CTAL_ADDR 0x4a +#define F37P_TABLE_END 0xff + +#define F37P_RES_IS_1080P(w, h) ((w) == 1920 && (h) == 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const F37P_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astF37P_mode[pstSnsState->u8ImgMode]; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = F37P_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 2; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + pstAeSnsDft->enBlcType = AE_BLC_TYPE_LADDER; + + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + pstAeSnsDft->u32AEResponseFrame = 4; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astF37P_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astF37P_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astF37P_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case F37P_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > F37P_FULL_LINES_MAX) ? F37P_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_DATA].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_DATA].u32Data = (u32VMAX & 0xFF); + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if ((u32IntTime[0] + 5) > pstSnsState->au32FL[0]) { + CVI_TRACE_SNS(CVI_DBG_ERR, "inttime over spec [%u, %u]\n", + u32IntTime[0], + pstSnsState->au32FL[0]); + return CVI_FAILURE; + } + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_DATA].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_DATA].u32Data = (u32IntTime[0] & 0xFF); + + return CVI_SUCCESS; +} + +static const CVI_U32 gain_table[] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; +static const CVI_U32 gain_table_size = ARRAY_SIZE(gain_table); + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[gain_table_size - 1]) { + *pu32AgainLin = gain_table[gain_table_size - 1]; + *pu32AgainDb = gain_table_size - 1; + return CVI_SUCCESS; + } + + for (i = 1; i < gain_table_size; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_DATA].u32Data = (u32Again & 0xFF); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const F37P_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astF37P_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = F37P_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astF37P_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + static CVI_U32 delay_frame; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunF37P_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = f37p_i2c_addr; + pstI2c_data[i].u32AddrByteNum = f37p_addr_byte; + pstI2c_data[i].u32DataByteNum = f37p_data_byte; + } + + switch (pstSnsState->enWDRMode) { + default: + pstI2c_data[LINEAR_BLC_CTRL_CLOSE].u32RegAddr = F37P_BLC_CTAL_ADDR; + pstI2c_data[LINEAR_BLC_CTRL_CLOSE].u32Data = 0x1; + pstI2c_data[LINEAR_EXP_L_DATA].u32RegAddr = F37P_EXP_ADDR; + pstI2c_data[LINEAR_EXP_H_DATA].u32RegAddr = F37P_EXP_ADDR + 1; + pstI2c_data[LINEAR_AGAIN_DATA].u32RegAddr = F37P_GAIN_ADDR; + pstI2c_data[LINEAR_VMAX_L_DATA].u32RegAddr = F37P_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_H_DATA].u32RegAddr = F37P_VMAX_ADDR + 1; + pstI2c_data[LINEAR_BLC_CTRL_OPEN].u32RegAddr = F37P_BLC_CTAL_ADDR; + pstI2c_data[LINEAR_BLC_CTRL_OPEN].u32Data = 0x0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + delay_frame = 0; + pstI2c_data[LINEAR_BLC_CTRL_CLOSE].bUpdate = CVI_TRUE; + } else { + if (++delay_frame == 2) { + pstCfg0->snsCfg.astI2cData[LINEAR_BLC_CTRL_OPEN].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeF37P_MirrorFip[ViPipe] != eSnsMirrorFlip) { + f37p_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeF37P_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (F37P_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = F37P_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const F37P_MODE_S *pstMode = CVI_NULL; + + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = F37P_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astF37P_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &f37p_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astF37P_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astF37P_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &f37p_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = f37p_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = f37p_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (F37P_I2C_ADDR_IS_VALID(s32I2cAddr)) + f37p_i2c_addr = s32I2cAddr; +} + +static CVI_S32 f37p_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunF37P_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + F37P_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + F37P_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + F37P_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + F37P_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = F37P_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, F37P_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, F37P_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, F37P_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16F37P_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16F37P_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsF37P_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = f37p_standby, + .pfnRestart = f37p_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = f37p_write_register, + .pfnReadReg = f37p_read_register, + .pfnSetBusInfo = f37p_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = f37p_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_f37p/f37p_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/soi_f37p/f37p_cmos_ex.h new file mode 100644 index 000000000..de0465e0f --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_f37p/f37p_cmos_ex.h @@ -0,0 +1,77 @@ +#ifndef __F37P_CMOS_EX_H_ +#define __F37P_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +enum f37p_linear_regs_e { + LINEAR_BLC_CTRL_CLOSE, + LINEAR_EXP_H_DATA, + LINEAR_EXP_L_DATA, + LINEAR_AGAIN_DATA, + LINEAR_VMAX_H_DATA, + LINEAR_VMAX_L_DATA, + LINEAR_BLC_CTRL_OPEN, + LINEAR_REGS_NUM +}; + +typedef enum _F37P_MODE_E { + F37P_MODE_1080P30 = 0, + F37P_MODE_LINEAR_NUM, + F37P_MODE_NUM +} F37P_MODE_E; + +typedef struct _F37P_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + CVI_U32 u32L2S_MAX; + char name[64]; +} F37P_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastF37P[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunF37P_BusInfo[]; +extern CVI_U8 f37p_i2c_addr; +extern const CVI_U32 f37p_addr_byte; +extern const CVI_U32 f37p_data_byte; +extern void f37p_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void f37p_init(VI_PIPE ViPipe); +extern void f37p_exit(VI_PIPE ViPipe); +extern void f37p_standby(VI_PIPE ViPipe); +extern void f37p_restart(VI_PIPE ViPipe); +extern int f37p_write_register(VI_PIPE ViPipe, int addr, int data); +extern int f37p_read_register(VI_PIPE ViPipe, int addr); +extern int f37p_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __F37P_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_f37p/f37p_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/soi_f37p/f37p_cmos_param.h new file mode 100644 index 000000000..3648a52be --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_f37p/f37p_cmos_param.h @@ -0,0 +1,125 @@ +#ifndef __F37P_CMOS_PARAM_H_ +#define __F37P_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "f37p_cmos_ex.h" + +static const F37P_MODE_S g_astF37P_mode[F37P_MODE_NUM] = { + [F37P_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.52, /* 1125 * 30 / 0xFFFF */ + .u32HtsDef = 2560, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1120, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {64, 64, 64, 64, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1040, 1040, 1040, 1040 +#endif + }, + .stAuto = { + {64, 64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, +#endif + }, + }, +}; + +struct combo_dev_attr_s f37p_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 1, 3, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 8, + } + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __F37P_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_f37p/f37p_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/soi_f37p/f37p_sensor_ctl.c new file mode 100644 index 000000000..fce19875b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_f37p/f37p_sensor_ctl.c @@ -0,0 +1,362 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "f37p_cmos_ex.h" + +static void f37p_linear_1080p30_init(VI_PIPE ViPipe); + +CVI_U8 f37p_i2c_addr = 0x40; /* I2C Address of F37P */ +const CVI_U32 f37p_addr_byte = 1; +const CVI_U32 f37p_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int f37p_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunF37P_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, f37p_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int f37p_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int f37p_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, f37p_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + ret = read(g_fd[ViPipe], buf, f37p_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (f37p_data_byte == 1) { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; + +} + +int f37p_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (f37p_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (f37p_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, f37p_addr_byte + f37p_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void f37p_standby(VI_PIPE ViPipe) +{ + f37p_write_register(ViPipe, 0x12, 0x40); +} + +void f37p_restart(VI_PIPE ViPipe) +{ + f37p_write_register(ViPipe, 0x12, 0x40); + delay_ms(20); + f37p_write_register(ViPipe, 0x12, 0x00); +} + +void f37p_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastF37P[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + f37p_write_register(ViPipe, + g_pastF37P[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastF37P[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void f37p_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = f37p_read_register(ViPipe, 0x12) & ~0x30; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x20; + break; + case ISP_SNS_FLIP: + val |= 0x10; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x30; + break; + default: + return; + } + + f37p_write_register(ViPipe, 0x12, val); +} + +#define F37P_CHIP_ID_HI_ADDR 0x0A +#define F37P_CHIP_ID_LO_ADDR 0x0B +#define F37P_CHIP_ID 0x0841 + +int f37p_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + if (f37p_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + delay_ms(4); + + nVal = f37p_read_register(ViPipe, F37P_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = f37p_read_register(ViPipe, F37P_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != F37P_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void f37p_init(VI_PIPE ViPipe) +{ + + f37p_i2c_init(ViPipe); + + f37p_linear_1080p30_init(ViPipe); + + g_pastF37P[ViPipe]->bInit = CVI_TRUE; +} + +void f37p_exit(VI_PIPE ViPipe) +{ + f37p_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void f37p_linear_1080p30_init(VI_PIPE ViPipe) +{ + f37p_write_register(ViPipe, 0x12, 0x40); + f37p_write_register(ViPipe, 0x48, 0x8A); + f37p_write_register(ViPipe, 0x48, 0x0A); + f37p_write_register(ViPipe, 0x0E, 0x19); + f37p_write_register(ViPipe, 0x0F, 0x04); + f37p_write_register(ViPipe, 0x10, 0x20); + f37p_write_register(ViPipe, 0x11, 0x80); + f37p_write_register(ViPipe, 0x46, 0x09); + f37p_write_register(ViPipe, 0x47, 0x66); + f37p_write_register(ViPipe, 0x0D, 0xF2); + f37p_write_register(ViPipe, 0x57, 0x6A); + f37p_write_register(ViPipe, 0x58, 0x22); + f37p_write_register(ViPipe, 0x5F, 0x41); + f37p_write_register(ViPipe, 0x60, 0x24); + f37p_write_register(ViPipe, 0xA5, 0xC0); + f37p_write_register(ViPipe, 0x20, 0x00); + f37p_write_register(ViPipe, 0x21, 0x05); + f37p_write_register(ViPipe, 0x22, 0x65); + f37p_write_register(ViPipe, 0x23, 0x04); + f37p_write_register(ViPipe, 0x24, 0xC0); + f37p_write_register(ViPipe, 0x25, 0x38); + f37p_write_register(ViPipe, 0x26, 0x43); + f37p_write_register(ViPipe, 0x27, 0xC6); + f37p_write_register(ViPipe, 0x28, 0x15); + f37p_write_register(ViPipe, 0x29, 0x04); + f37p_write_register(ViPipe, 0x2A, 0xBB); + f37p_write_register(ViPipe, 0x2B, 0x14); + f37p_write_register(ViPipe, 0x2C, 0x02); + f37p_write_register(ViPipe, 0x2D, 0x00); + f37p_write_register(ViPipe, 0x2E, 0x14); + f37p_write_register(ViPipe, 0x2F, 0x04); + f37p_write_register(ViPipe, 0x41, 0xC5); + f37p_write_register(ViPipe, 0x42, 0x33); + f37p_write_register(ViPipe, 0x47, 0x46); + f37p_write_register(ViPipe, 0x76, 0x60); + f37p_write_register(ViPipe, 0x77, 0x09); + f37p_write_register(ViPipe, 0x80, 0x01); + f37p_write_register(ViPipe, 0xAF, 0x22); + f37p_write_register(ViPipe, 0xAB, 0x00); + f37p_write_register(ViPipe, 0x1D, 0x00); + f37p_write_register(ViPipe, 0x1E, 0x04); + f37p_write_register(ViPipe, 0x6C, 0x40); + f37p_write_register(ViPipe, 0x9E, 0xF8); + f37p_write_register(ViPipe, 0x6E, 0x2C); + f37p_write_register(ViPipe, 0x70, 0x6C); + f37p_write_register(ViPipe, 0x71, 0x6D); + f37p_write_register(ViPipe, 0x72, 0x6A); + f37p_write_register(ViPipe, 0x73, 0x56); + f37p_write_register(ViPipe, 0x74, 0x02); + f37p_write_register(ViPipe, 0x78, 0x9D); + f37p_write_register(ViPipe, 0x89, 0x01); + f37p_write_register(ViPipe, 0x6B, 0x20); + f37p_write_register(ViPipe, 0x86, 0x40); + f37p_write_register(ViPipe, 0x31, 0x10); + f37p_write_register(ViPipe, 0x32, 0x18); + f37p_write_register(ViPipe, 0x33, 0xE8); + f37p_write_register(ViPipe, 0x34, 0x5E); + f37p_write_register(ViPipe, 0x35, 0x5E); + f37p_write_register(ViPipe, 0x3A, 0xAF); + f37p_write_register(ViPipe, 0x3B, 0x00); + f37p_write_register(ViPipe, 0x3C, 0xFF); + f37p_write_register(ViPipe, 0x3D, 0xFF); + f37p_write_register(ViPipe, 0x3E, 0xFF); + f37p_write_register(ViPipe, 0x3F, 0xBB); + f37p_write_register(ViPipe, 0x40, 0xFF); + f37p_write_register(ViPipe, 0x56, 0x92); + f37p_write_register(ViPipe, 0x59, 0xAF); + f37p_write_register(ViPipe, 0x5A, 0x47); + f37p_write_register(ViPipe, 0x61, 0x18); + f37p_write_register(ViPipe, 0x6F, 0x04); + f37p_write_register(ViPipe, 0x85, 0x5F); + f37p_write_register(ViPipe, 0x8A, 0x44); + f37p_write_register(ViPipe, 0x91, 0x13); + f37p_write_register(ViPipe, 0x94, 0xA0); + f37p_write_register(ViPipe, 0x9B, 0x83); + f37p_write_register(ViPipe, 0x9C, 0xE1); + f37p_write_register(ViPipe, 0xA4, 0x80); + f37p_write_register(ViPipe, 0xA6, 0x22); + f37p_write_register(ViPipe, 0xA9, 0x1C); + f37p_write_register(ViPipe, 0x5B, 0xE7); + f37p_write_register(ViPipe, 0x5C, 0x28); + f37p_write_register(ViPipe, 0x5D, 0x67); + f37p_write_register(ViPipe, 0x5E, 0x11); + f37p_write_register(ViPipe, 0x62, 0x21); + f37p_write_register(ViPipe, 0x63, 0x0F); + f37p_write_register(ViPipe, 0x64, 0xD0); + f37p_write_register(ViPipe, 0x65, 0x02); + f37p_write_register(ViPipe, 0x67, 0x49); + f37p_write_register(ViPipe, 0x66, 0x00); + f37p_write_register(ViPipe, 0x68, 0x00); + f37p_write_register(ViPipe, 0x69, 0x72); + f37p_write_register(ViPipe, 0x6A, 0x12); + f37p_write_register(ViPipe, 0x7A, 0x00); + f37p_write_register(ViPipe, 0x82, 0x20); + f37p_write_register(ViPipe, 0x8D, 0x47); + f37p_write_register(ViPipe, 0x8F, 0x90); + f37p_write_register(ViPipe, 0x45, 0x01); + f37p_write_register(ViPipe, 0x97, 0x20); + f37p_write_register(ViPipe, 0x13, 0x81); + f37p_write_register(ViPipe, 0x96, 0x84); + f37p_write_register(ViPipe, 0x4A, 0x01); + f37p_write_register(ViPipe, 0xB1, 0x00); + f37p_write_register(ViPipe, 0xA1, 0x0F); + f37p_write_register(ViPipe, 0xBE, 0x00); + f37p_write_register(ViPipe, 0x7E, 0x48); + f37p_write_register(ViPipe, 0xB5, 0xC0); + f37p_write_register(ViPipe, 0x50, 0x02); + f37p_write_register(ViPipe, 0x49, 0x10); + f37p_write_register(ViPipe, 0x7F, 0x57); + f37p_write_register(ViPipe, 0x90, 0x00); + f37p_write_register(ViPipe, 0x7B, 0x4A); + f37p_write_register(ViPipe, 0x7C, 0x0C); + f37p_write_register(ViPipe, 0x8C, 0xFF); + f37p_write_register(ViPipe, 0x8E, 0x00); + f37p_write_register(ViPipe, 0x8B, 0x01); + f37p_write_register(ViPipe, 0x0C, 0x00); + f37p_write_register(ViPipe, 0xBC, 0x11); + f37p_write_register(ViPipe, 0x19, 0x20); + f37p_write_register(ViPipe, 0x1B, 0x4F); + + f37p_default_reg_init(ViPipe); + + f37p_write_register(ViPipe, 0x12, 0x00); + + delay_ms(80); + + printf("ViPipe:%d,===F37P 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_k06/Makefile b/middleware/v2/component/isp/sensor/cv180x/soi_k06/Makefile new file mode 100644 index 000000000..f1045598e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_k06/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_k06.a +TARGET_SO = $(MW_LIB)/libsns_k06.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_k06/k06_cmos.c b/middleware/v2/component/isp/sensor/cv180x/soi_k06/k06_cmos.c new file mode 100644 index 000000000..5c720b650 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_k06/k06_cmos.c @@ -0,0 +1,819 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "k06_cmos_ex.h" +#include "k06_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define K06_ID 06 +#define K06_I2C_ADDR_1 0x40 +#define K06_I2C_ADDR_2 0x44 +#define K06_I2C_ADDR_IS_VALID(addr) ((addr) == K06_I2C_ADDR_1 || (addr) == K06_I2C_ADDR_2) +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastK06[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define K06_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastK06[dev]) +#define K06_SENSOR_SET_CTX(dev, pstCtx) (g_pastK06[dev] = pstCtx) +#define K06_SENSOR_RESET_CTX(dev) (g_pastK06[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunK06_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16K06_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16K06_L2SMode[VI_MAX_PIPE_NUM] = {0}; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeK06_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****K06 Lines Range*****/ +#define K06_FULL_LINES_MAX (0xFFFF) + +/*****K06 Register Address*****/ +#define K06_SHS1_ADDR 0x01 +#define K06_GAIN_ADDR 0x00 +#define K06_VMAX_ADDR 0x22 +#define K06_TABLE_END 0xff + +#define K06_RES_IS_1440P(w, h) ((w) == 2560 && (h) == 1440) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const K06_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astK06_mode[pstSnsState->u8ImgMode]; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = K06_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 25); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 2; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 25 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + pstAeSnsDft->enBlcType = AE_BLC_TYPE_LADDER; + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? + g_au32InitExposure[ViPipe] : g_astK06_mode[K06_MODE_1440P25].stExp[0].u16Def; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astK06_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astK06_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astK06_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case K06_MODE_1440P25: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > K06_FULL_LINES_MAX) ? K06_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_DATA].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_DATA].u32Data = ((u32VMAX & 0xFF00) >> 8); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if ((u32IntTime[0] + 5) > pstSnsState->au32FL[0]) { + CVI_TRACE_SNS(CVI_DBG_ERR, "inttime over spec [%u, %u]\n", + u32IntTime[0], + pstSnsState->au32FL[0]); + return CVI_FAILURE; + } + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_DATA].u32Data = (u32IntTime[0] & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_DATA].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[64] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[63]) { + *pu32AgainLin = gain_table[63]; + *pu32AgainDb = 63; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_DATA].u32Data = (u32Again & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const K06_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astK06_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = K06_MODE_1440P25; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astK06_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunK06_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = k06_i2c_addr; + pstI2c_data[i].u32AddrByteNum = k06_addr_byte; + pstI2c_data[i].u32DataByteNum = k06_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + pstI2c_data[LINEAR_SHS1_0_DATA].u32RegAddr = K06_SHS1_ADDR; + + pstI2c_data[LINEAR_SHS1_1_DATA].u32RegAddr = K06_SHS1_ADDR + 1; + + pstI2c_data[LINEAR_AGAIN_DATA].u32RegAddr = K06_GAIN_ADDR; + + pstI2c_data[LINEAR_VMAX_0_DATA].u32RegAddr = K06_VMAX_ADDR; + + pstI2c_data[LINEAR_VMAX_1_DATA].u32RegAddr = K06_VMAX_ADDR + 1; + + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (K06_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = K06_MODE_1440P25; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeK06_MirrorFip[ViPipe] != eSnsMirrorFlip) { + k06_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeK06_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const K06_MODE_S *pstMode = CVI_NULL; + + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = K06_MODE_1440P25; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astK06_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &k06_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astK06_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astK06_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &k06_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = k06_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = k06_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (K06_I2C_ADDR_IS_VALID(s32I2cAddr)) + k06_i2c_addr = s32I2cAddr; +} + +static CVI_S32 k06_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunK06_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + K06_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + K06_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + K06_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + K06_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = K06_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, K06_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, K06_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, K06_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16K06_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16K06_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsK06_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = k06_standby, + .pfnRestart = k06_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = k06_write_register, + .pfnReadReg = k06_read_register, + .pfnSetBusInfo = k06_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = k06_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_k06/k06_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/soi_k06/k06_cmos_ex.h new file mode 100644 index 000000000..e23696056 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_k06/k06_cmos_ex.h @@ -0,0 +1,82 @@ +#ifndef __K06_CMOS_EX_H_ +#define __K06_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum k06_linear_regs_e { + LINEAR_SHS1_0_DATA, + LINEAR_SHS1_1_DATA, + LINEAR_AGAIN_DATA, + LINEAR_VMAX_0_DATA, + LINEAR_VMAX_1_DATA, + LINEAR_REGS_NUM +}; + + +typedef enum _K06_MODE_E { + K06_MODE_1440P25 = 0, + K06_MODE_LINEAR_NUM, + K06_MODE_NUM +} K06_MODE_E; + +typedef struct _K06_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + CVI_U32 u32L2S_MAX; + char name[64]; +} K06_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastK06[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunK06_BusInfo[]; +extern CVI_U16 g_au16K06_GainMode[]; +extern CVI_U16 g_au16K06_L2SMode[]; +extern CVI_U8 k06_i2c_addr; +extern const CVI_U32 k06_addr_byte; +extern const CVI_U32 k06_data_byte; +extern void k06_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void k06_init(VI_PIPE ViPipe); +extern void k06_exit(VI_PIPE ViPipe); +extern void k06_standby(VI_PIPE ViPipe); +extern void k06_restart(VI_PIPE ViPipe); +extern int k06_write_register(VI_PIPE ViPipe, int addr, int data); +extern int k06_read_register(VI_PIPE ViPipe, int addr); +extern int k06_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __K06_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_k06/k06_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/soi_k06/k06_cmos_param.h new file mode 100644 index 000000000..9a1ae21d1 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_k06/k06_cmos_param.h @@ -0,0 +1,122 @@ +#ifndef __K06_CMOS_PARAM_H_ +#define __K06_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "k06_cmos_ex.h" + +static const K06_MODE_S g_astK06_mode[K06_MODE_NUM] = { + [K06_MODE_1440P25] = { + .name = "1440p25", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 25, + .f32MinFps = 0.57, /* 1500 * 25 / 0xFFFF */ + .u32HtsDef = 4608, + .u32VtsDef = 1500, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1500, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {64, 64, 64, 64, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1040, 1040, 1040, 1040 +#endif + }, + .stAuto = { + {64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, +#endif + }, + }, +}; + +struct combo_dev_attr_s k06_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 1, 3, -1, -1}, + .pn_swap = {0, 0, 0, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 1, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __K06_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_k06/k06_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/soi_k06/k06_sensor_ctl.c new file mode 100644 index 000000000..d97d23e85 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_k06/k06_sensor_ctl.c @@ -0,0 +1,349 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "k06_cmos_ex.h" + +#define K06_CHIP_ID_HI_ADDR 0x0A +#define K06_CHIP_ID_LO_ADDR 0x0B +#define K06_CHIP_ID 0x0852 + +static void k06_linear_1440p25_init(VI_PIPE ViPipe); + +CVI_U8 k06_i2c_addr = 0x40; /* I2C Address of K06 */ +const CVI_U32 k06_addr_byte = 1; +const CVI_U32 k06_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int k06_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunK06_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, k06_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int k06_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int k06_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, k06_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + ret = read(g_fd[ViPipe], buf, k06_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (k06_data_byte == 1) { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int k06_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (k06_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (k06_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, k06_addr_byte + k06_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void k06_standby(VI_PIPE ViPipe) +{ + k06_write_register(ViPipe, 0x12, 0x40); +} + +void k06_restart(VI_PIPE ViPipe) +{ + k06_write_register(ViPipe, 0x12, 0x40); + delay_ms(20); + k06_write_register(ViPipe, 0x12, 0x00); +} + +void k06_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastK06[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + k06_write_register(ViPipe, + g_pastK06[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastK06[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void k06_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = k06_read_register(ViPipe, 0x12) & (~0x30); + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + val |= 0x30; + break; + case ISP_SNS_MIRROR: + val |= (0x1 << 4); + break; + case ISP_SNS_FLIP: + val |= (0x2 << 4); + break; + case ISP_SNS_MIRROR_FLIP: + val &= ~(0x1 << 4); + break; + default: + return; + } + + k06_write_register(ViPipe, 0x12, val); +} + +int k06_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (k06_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = k06_read_register(ViPipe, K06_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = k06_read_register(ViPipe, K06_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != K06_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void k06_init(VI_PIPE ViPipe) +{ + k06_i2c_init(ViPipe); + + k06_linear_1440p25_init(ViPipe); + g_pastK06[ViPipe]->bInit = CVI_TRUE; +} + +void k06_exit(VI_PIPE ViPipe) +{ + k06_i2c_exit(ViPipe); +} + +static void k06_linear_1440p25_init(VI_PIPE ViPipe) +{ + k06_write_register(ViPipe, 0x12, 0x70); + k06_write_register(ViPipe, 0x48, 0x86); + k06_write_register(ViPipe, 0x48, 0x06); + k06_write_register(ViPipe, 0x0E, 0x11); + k06_write_register(ViPipe, 0x0F, 0x04); + k06_write_register(ViPipe, 0x10, 0x48); + k06_write_register(ViPipe, 0x11, 0x80); + k06_write_register(ViPipe, 0x46, 0x08); + k06_write_register(ViPipe, 0x0D, 0xA0); + k06_write_register(ViPipe, 0x57, 0x67); + k06_write_register(ViPipe, 0x58, 0x1F); + k06_write_register(ViPipe, 0x5F, 0x41); + k06_write_register(ViPipe, 0x60, 0x20); + k06_write_register(ViPipe, 0x20, 0x80); + k06_write_register(ViPipe, 0x21, 0x04); + k06_write_register(ViPipe, 0x22, 0xDC); + k06_write_register(ViPipe, 0x23, 0x05); + k06_write_register(ViPipe, 0x24, 0x80); + k06_write_register(ViPipe, 0x25, 0xA0); + k06_write_register(ViPipe, 0x26, 0x52); + k06_write_register(ViPipe, 0x27, 0x27); + k06_write_register(ViPipe, 0x28, 0x15); + k06_write_register(ViPipe, 0x29, 0x04); + k06_write_register(ViPipe, 0x2A, 0x20); + k06_write_register(ViPipe, 0x2B, 0x14); + k06_write_register(ViPipe, 0x2C, 0x00); + k06_write_register(ViPipe, 0x2D, 0x00); + k06_write_register(ViPipe, 0x2E, 0x6E); + k06_write_register(ViPipe, 0x2F, 0x04); + k06_write_register(ViPipe, 0x41, 0x06); + k06_write_register(ViPipe, 0x42, 0x05); + k06_write_register(ViPipe, 0x47, 0x46); + k06_write_register(ViPipe, 0x76, 0x80); + k06_write_register(ViPipe, 0x77, 0x0C); + k06_write_register(ViPipe, 0x80, 0x01); + k06_write_register(ViPipe, 0xAF, 0x12); + k06_write_register(ViPipe, 0xAA, 0x04); + k06_write_register(ViPipe, 0x1D, 0x00); + k06_write_register(ViPipe, 0x1E, 0x04); + k06_write_register(ViPipe, 0x6C, 0x40); + k06_write_register(ViPipe, 0x9E, 0xF8); + k06_write_register(ViPipe, 0x0C, 0x30); + k06_write_register(ViPipe, 0x6F, 0x80); + k06_write_register(ViPipe, 0x6E, 0x2C); + k06_write_register(ViPipe, 0x70, 0xF9); + k06_write_register(ViPipe, 0x71, 0xDD); + k06_write_register(ViPipe, 0x72, 0xD5); + k06_write_register(ViPipe, 0x73, 0x5A); + k06_write_register(ViPipe, 0x74, 0x02); + k06_write_register(ViPipe, 0x78, 0x1D); + k06_write_register(ViPipe, 0x89, 0x01); + k06_write_register(ViPipe, 0x6B, 0x20); + k06_write_register(ViPipe, 0x86, 0x40); + k06_write_register(ViPipe, 0x30, 0x8D); + k06_write_register(ViPipe, 0x31, 0x08); + k06_write_register(ViPipe, 0x32, 0x20); + k06_write_register(ViPipe, 0x33, 0x5C); + k06_write_register(ViPipe, 0x34, 0x30); + k06_write_register(ViPipe, 0x35, 0x30); + k06_write_register(ViPipe, 0x3A, 0xB6); + k06_write_register(ViPipe, 0x56, 0x92); + k06_write_register(ViPipe, 0x59, 0x48); + k06_write_register(ViPipe, 0x5A, 0x01); + k06_write_register(ViPipe, 0x61, 0x00); + k06_write_register(ViPipe, 0x64, 0xC0); + k06_write_register(ViPipe, 0x7F, 0x46); + k06_write_register(ViPipe, 0x85, 0x44); + k06_write_register(ViPipe, 0x8A, 0x00); + k06_write_register(ViPipe, 0x91, 0x58); + k06_write_register(ViPipe, 0x94, 0xE0); + k06_write_register(ViPipe, 0x9B, 0x8F); + k06_write_register(ViPipe, 0xA6, 0x02); + k06_write_register(ViPipe, 0xA7, 0xA0); + k06_write_register(ViPipe, 0xA9, 0x48); + k06_write_register(ViPipe, 0x45, 0x09); + k06_write_register(ViPipe, 0x5B, 0xA5); + k06_write_register(ViPipe, 0x5C, 0x8C); + k06_write_register(ViPipe, 0x5D, 0x97); + k06_write_register(ViPipe, 0x5E, 0x48); + k06_write_register(ViPipe, 0x65, 0x32); + k06_write_register(ViPipe, 0x66, 0x80); + k06_write_register(ViPipe, 0x67, 0x44); + k06_write_register(ViPipe, 0x68, 0x00); + k06_write_register(ViPipe, 0x69, 0x74); + k06_write_register(ViPipe, 0x6A, 0x2B); + k06_write_register(ViPipe, 0x7A, 0x82); + k06_write_register(ViPipe, 0x8D, 0x6F); + k06_write_register(ViPipe, 0x8F, 0x90); + k06_write_register(ViPipe, 0xA4, 0xC7); + k06_write_register(ViPipe, 0xA5, 0xAF); + k06_write_register(ViPipe, 0xB7, 0x21); + k06_write_register(ViPipe, 0x97, 0x20); + k06_write_register(ViPipe, 0x13, 0x81); + k06_write_register(ViPipe, 0x96, 0x84); + k06_write_register(ViPipe, 0x4A, 0x01); + k06_write_register(ViPipe, 0x7E, 0x4C); + k06_write_register(ViPipe, 0x50, 0x02); + k06_write_register(ViPipe, 0x93, 0xC0); + k06_write_register(ViPipe, 0xB5, 0x4C); + k06_write_register(ViPipe, 0xB1, 0x00); + k06_write_register(ViPipe, 0xA1, 0x0F); + k06_write_register(ViPipe, 0xA3, 0x40); + k06_write_register(ViPipe, 0x49, 0x10); + k06_write_register(ViPipe, 0x8C, 0xFF); + k06_write_register(ViPipe, 0x8E, 0x00); + k06_write_register(ViPipe, 0x8B, 0x01); + k06_write_register(ViPipe, 0xBC, 0x11); + k06_write_register(ViPipe, 0x82, 0x00); + k06_write_register(ViPipe, 0x9F, 0x50); + k06_write_register(ViPipe, 0x19, 0x20); + k06_write_register(ViPipe, 0x1B, 0x4F); + + k06_default_reg_init(ViPipe); +// k06_write_register(ViPipe, 0x12, 0x00); + k06_write_register(ViPipe, 0x12, 0x30); + k06_write_register(ViPipe, 0x48, 0x86); + k06_write_register(ViPipe, 0x48, 0x06); + printf("ViPipe:%d,===K06 1440P 25fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_q03/Makefile b/middleware/v2/component/isp/sensor/cv180x/soi_q03/Makefile new file mode 100644 index 000000000..16b0c3f0c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_q03/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_q03.a +TARGET_SO = $(MW_LIB)/libsns_q03.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_q03/q03_cmos.c b/middleware/v2/component/isp/sensor/cv180x/soi_q03/q03_cmos.c new file mode 100644 index 000000000..d661e2724 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_q03/q03_cmos.c @@ -0,0 +1,848 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "q03_cmos_ex.h" +#include "q03_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define Q03_ID 03 +#define Q03_I2C_ADDR_1 0x40 +#define Q03_I2C_ADDR_2 0x42 +#define Q03_I2C_ADDR_3 0x44 +#define Q03_I2C_ADDR_4 0x46 +#define Q03_I2C_ADDR_IS_VALID(addr) ((addr) == Q03_I2C_ADDR_1 || (addr) == Q03_I2C_ADDR_2 \ + || (addr) == Q03_I2C_ADDR_3 || (addr) == Q03_I2C_ADDR_4) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastQ03[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define Q03_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastQ03[dev]) +#define Q03_SENSOR_SET_CTX(dev, pstCtx) (g_pastQ03[dev] = pstCtx) +#define Q03_SENSOR_RESET_CTX(dev) (g_pastQ03[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunQ03_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Q03_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Q03_L2SMode[VI_MAX_PIPE_NUM] = {0}; +//Q03_STATE_S g_astQ03_State[VI_MAX_PIPE_NUM] = {{0}}; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeQ03_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Q03 Lines Range*****/ +#define Q03_FULL_LINES_MAX (0xFFFF) + +/*****F35 Register Address*****/ +#define Q03_SHS1_ADDR 0x01 +#define Q03_GAIN_ADDR 0x00 +#define Q03_VMAX_ADDR 0x22 +#define Q03_TABLE_END 0xff + +#define Q03_RES_IS_1296P(w, h) ((w) <= 2304 && (h) <= 1296) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const Q03_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astQ03_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = Q03_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 2; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + pstAeSnsDft->enBlcType = AE_BLC_TYPE_LADDER; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + pstAeSnsDft->u32AEResponseFrame = 4; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astQ03_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astQ03_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astQ03_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case Q03_MODE_1296P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > Q03_FULL_LINES_MAX) ? Q03_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_DATA].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_DATA].u32Data = ((u32VMAX & 0xFF00) >> 8); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((u32IntTime[0] + 5) > pstSnsState->au32FL[0]) { + CVI_TRACE_SNS(CVI_DBG_ERR, "inttime over spec [%u, %u]\n", + u32IntTime[0], + pstSnsState->au32FL[0]); + return CVI_FAILURE; + } + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_DATA].u32Data = (u32IntTime[0] & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_DATA].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[64] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[63]) { + *pu32AgainLin = gain_table[63]; + *pu32AgainDb = 63; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_DATA].u32Data = (u32Again & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const Q03_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astQ03_mode[pstSnsState->u8ImgMode]; + + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = Q03_MODE_1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astQ03_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunQ03_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = q03_i2c_addr; + pstI2c_data[i].u32AddrByteNum = q03_addr_byte; + pstI2c_data[i].u32DataByteNum = q03_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_DATA].u32RegAddr = Q03_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1_DATA].u32RegAddr = Q03_SHS1_ADDR + 1; + pstI2c_data[LINEAR_AGAIN_DATA].u32RegAddr = Q03_GAIN_ADDR; + pstI2c_data[LINEAR_VMAX_0_DATA].u32RegAddr = Q03_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_0_DATA].u8DelayFrmNum = 2; + pstI2c_data[LINEAR_VMAX_1_DATA].u32RegAddr = Q03_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_1_DATA].u8DelayFrmNum = 2; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (Q03_RES_IS_1296P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = Q03_MODE_1296P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeQ03_MirrorFip[ViPipe] != eSnsMirrorFlip) { + q03_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeQ03_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const Q03_MODE_S *pstMode = CVI_NULL; + + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = Q03_MODE_1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astQ03_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &q03_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astQ03_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astQ03_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &q03_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = q03_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = q03_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (Q03_I2C_ADDR_IS_VALID(s32I2cAddr)) + q03_i2c_addr = s32I2cAddr; +} + +static CVI_S32 q03_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunQ03_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + Q03_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + Q03_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + Q03_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + Q03_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = Q03_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, Q03_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, Q03_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, Q03_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Q03_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Q03_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsQ03_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = q03_standby, + .pfnRestart = q03_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = q03_write_register, + .pfnReadReg = q03_read_register, + .pfnSetBusInfo = q03_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = q03_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_q03/q03_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/soi_q03/q03_cmos_ex.h new file mode 100644 index 000000000..05a431c19 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_q03/q03_cmos_ex.h @@ -0,0 +1,82 @@ +#ifndef __Q03_CMOS_EX_H_ +#define __Q03_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum q03_linear_regs_e { + LINEAR_SHS1_0_DATA, + LINEAR_SHS1_1_DATA, + LINEAR_AGAIN_DATA, + LINEAR_VMAX_0_DATA, + LINEAR_VMAX_1_DATA, + LINEAR_REGS_NUM +}; + +typedef enum _Q03_MODE_E { + Q03_MODE_1296P30 = 0, + Q03_MODE_LINEAR_NUM, + Q03_MODE_1296P30_WDR = Q03_MODE_LINEAR_NUM, + Q03_MODE_NUM +} Q03_MODE_E; + +typedef struct _Q03_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + CVI_U32 u32L2S_MAX; + char name[64]; +} Q03_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastQ03[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunQ03_BusInfo[]; +extern CVI_U16 g_au16Q03_GainMode[]; +extern CVI_U16 g_au16Q03_L2SMode[]; +extern CVI_U8 q03_i2c_addr; +extern const CVI_U32 q03_addr_byte; +extern const CVI_U32 q03_data_byte; +extern void q03_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void q03_init(VI_PIPE ViPipe); +extern void q03_exit(VI_PIPE ViPipe); +extern void q03_standby(VI_PIPE ViPipe); +extern void q03_restart(VI_PIPE ViPipe); +extern int q03_write_register(VI_PIPE ViPipe, int addr, int data); +extern int q03_read_register(VI_PIPE ViPipe, int addr); +extern int q03_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __Q03_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_q03/q03_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/soi_q03/q03_cmos_param.h new file mode 100644 index 000000000..f64924528 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_q03/q03_cmos_param.h @@ -0,0 +1,122 @@ +#ifndef __Q03_CMOS_PARAM_H_ +#define __Q03_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "q03_cmos_ex.h" + +static const Q03_MODE_S g_astQ03_mode[Q03_MODE_NUM] = { + [Q03_MODE_1296P30] = { + .name = "1296p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2312, + .u32Height = 1296, + }, + .stWndRect = { + .s32X = 4, + .s32Y = 0, + .u32Width = 2304, + .u32Height = 1296, + }, + .stMaxSize = { + .u32Width = 2312, + .u32Height = 1296, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.61, /* 1350 * 30 / 0xFFFF */ + .u32HtsDef = 3600, + .u32VtsDef = 1350, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1350, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {64, 64, 64, 64, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1040, 1040, 1040, 1040 +#endif + }, + .stAuto = { + {64, 64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, +#endif + }, + }, +}; + +struct combo_dev_attr_s q03_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {0, 1, 2, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __Q03_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/soi_q03/q03_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/soi_q03/q03_sensor_ctl.c new file mode 100644 index 000000000..5f340ff82 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/soi_q03/q03_sensor_ctl.c @@ -0,0 +1,348 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "q03_cmos_ex.h" + +#define Q03_CHIP_ID_HI_ADDR 0x0A +#define Q03_CHIP_ID_LO_ADDR 0x0B +#define Q03_CHIP_ID 0x0507 + +static void q03_linear_1296p30_init(VI_PIPE ViPipe); + +CVI_U8 q03_i2c_addr = 0x46; /* I2C Address of Q03 */ +const CVI_U32 q03_addr_byte = 1; +const CVI_U32 q03_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int q03_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunQ03_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, q03_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int q03_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int q03_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, q03_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + ret = read(g_fd[ViPipe], buf, q03_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (q03_data_byte == 1) { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int q03_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (q03_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + + if (q03_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, q03_addr_byte + q03_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void q03_standby(VI_PIPE ViPipe) +{ + q03_write_register(ViPipe, 0x12, 0x40); +} + +void q03_restart(VI_PIPE ViPipe) +{ + q03_write_register(ViPipe, 0x12, 0x40); + delay_ms(20); + q03_write_register(ViPipe, 0x12, 0x00); +} + +void q03_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastQ03[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + q03_write_register(ViPipe, + g_pastQ03[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastQ03[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void q03_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = q03_read_register(ViPipe, 0x12) & ~0x30; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x20; + break; + case ISP_SNS_FLIP: + val |= 0x10; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x30; + break; + default: + return; + } + + q03_write_register(ViPipe, 0x12, val); +} + +int q03_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + delay_ms(4); + if (q03_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = q03_read_register(ViPipe, Q03_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = q03_read_register(ViPipe, Q03_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != Q03_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void q03_init(VI_PIPE ViPipe) +{ + q03_i2c_init(ViPipe); + + q03_linear_1296p30_init(ViPipe); + + g_pastQ03[ViPipe]->bInit = CVI_TRUE; +} + +void q03_exit(VI_PIPE ViPipe) +{ + q03_i2c_exit(ViPipe); +} + +static void q03_linear_1296p30_init(VI_PIPE ViPipe) +{ + q03_write_register(ViPipe, 0x12, 0x40); + q03_write_register(ViPipe, 0x48, 0x96); + q03_write_register(ViPipe, 0x48, 0x16); + q03_write_register(ViPipe, 0x0E, 0x11); + q03_write_register(ViPipe, 0x0F, 0x14); + q03_write_register(ViPipe, 0x10, 0x36); + q03_write_register(ViPipe, 0x11, 0x80); + q03_write_register(ViPipe, 0x0D, 0xB0); + q03_write_register(ViPipe, 0x5F, 0x42); + q03_write_register(ViPipe, 0x60, 0x2B); + q03_write_register(ViPipe, 0x58, 0x1A); + q03_write_register(ViPipe, 0x57, 0x60); + q03_write_register(ViPipe, 0x20, 0x84); + q03_write_register(ViPipe, 0x21, 0x03); + q03_write_register(ViPipe, 0x22, 0x46); + q03_write_register(ViPipe, 0x23, 0x05); + q03_write_register(ViPipe, 0x24, 0x42); + q03_write_register(ViPipe, 0x25, 0x10); + q03_write_register(ViPipe, 0x26, 0x52); + q03_write_register(ViPipe, 0x27, 0x53); + q03_write_register(ViPipe, 0x28, 0x15); + q03_write_register(ViPipe, 0x29, 0x03); + q03_write_register(ViPipe, 0x2A, 0x4E); + q03_write_register(ViPipe, 0x2B, 0x13); + q03_write_register(ViPipe, 0x2C, 0x00); + q03_write_register(ViPipe, 0x2D, 0x00); + q03_write_register(ViPipe, 0x2E, 0x4A); + q03_write_register(ViPipe, 0x2F, 0x64); + q03_write_register(ViPipe, 0x41, 0x8A); + q03_write_register(ViPipe, 0x42, 0x14); + q03_write_register(ViPipe, 0x47, 0x42); + q03_write_register(ViPipe, 0x76, 0x4A); + q03_write_register(ViPipe, 0x77, 0x0B); + q03_write_register(ViPipe, 0x80, 0x00); + q03_write_register(ViPipe, 0xAF, 0x22); + q03_write_register(ViPipe, 0xAB, 0x00); + q03_write_register(ViPipe, 0x46, 0x00); + q03_write_register(ViPipe, 0x1D, 0x00); + q03_write_register(ViPipe, 0x1E, 0x04); + q03_write_register(ViPipe, 0x6C, 0x40); + q03_write_register(ViPipe, 0x6E, 0x2C); + q03_write_register(ViPipe, 0x70, 0xD9); + q03_write_register(ViPipe, 0x71, 0xD0); + q03_write_register(ViPipe, 0x72, 0xD5); + q03_write_register(ViPipe, 0x73, 0x59); + q03_write_register(ViPipe, 0x74, 0x02); + q03_write_register(ViPipe, 0x78, 0x96); + q03_write_register(ViPipe, 0x89, 0x01); + q03_write_register(ViPipe, 0x6B, 0x20); + q03_write_register(ViPipe, 0x86, 0x40); + q03_write_register(ViPipe, 0x31, 0x0A); + q03_write_register(ViPipe, 0x32, 0x21); + q03_write_register(ViPipe, 0x33, 0x5C); + q03_write_register(ViPipe, 0x34, 0x44); + q03_write_register(ViPipe, 0x35, 0x40); + q03_write_register(ViPipe, 0x3A, 0xA0); + q03_write_register(ViPipe, 0x3B, 0x38); + q03_write_register(ViPipe, 0x3C, 0x50); + q03_write_register(ViPipe, 0x3D, 0x5B); + q03_write_register(ViPipe, 0x3E, 0xFF); + q03_write_register(ViPipe, 0x3F, 0x54); + q03_write_register(ViPipe, 0x40, 0xFF); + q03_write_register(ViPipe, 0x56, 0xB2); + q03_write_register(ViPipe, 0x59, 0x50); + q03_write_register(ViPipe, 0x5A, 0x04); + q03_write_register(ViPipe, 0x85, 0x34); + q03_write_register(ViPipe, 0x8A, 0x04); + q03_write_register(ViPipe, 0x91, 0x08); + q03_write_register(ViPipe, 0xA9, 0x08); + q03_write_register(ViPipe, 0x9C, 0xE1); + q03_write_register(ViPipe, 0x5B, 0xA0); + q03_write_register(ViPipe, 0x5C, 0x80); + q03_write_register(ViPipe, 0x5D, 0xEF); + q03_write_register(ViPipe, 0x5E, 0x14); + q03_write_register(ViPipe, 0x64, 0xE0); + q03_write_register(ViPipe, 0x66, 0x04); + q03_write_register(ViPipe, 0x67, 0x77); + q03_write_register(ViPipe, 0x68, 0x00); + q03_write_register(ViPipe, 0x69, 0x41); + q03_write_register(ViPipe, 0x7A, 0xA0); + q03_write_register(ViPipe, 0x8F, 0x91); + q03_write_register(ViPipe, 0x9D, 0x70); + q03_write_register(ViPipe, 0xAE, 0x30); + q03_write_register(ViPipe, 0x13, 0x81); + q03_write_register(ViPipe, 0x96, 0x04); + q03_write_register(ViPipe, 0x4A, 0x01); + q03_write_register(ViPipe, 0x7E, 0xC9); + q03_write_register(ViPipe, 0x50, 0x02); + q03_write_register(ViPipe, 0x49, 0x10); + q03_write_register(ViPipe, 0x7B, 0x4A); + q03_write_register(ViPipe, 0x7C, 0x0F); + q03_write_register(ViPipe, 0x7F, 0x57); + q03_write_register(ViPipe, 0x62, 0x21); + q03_write_register(ViPipe, 0x90, 0x00); + q03_write_register(ViPipe, 0x8C, 0xFF); + q03_write_register(ViPipe, 0x8D, 0xC7); + q03_write_register(ViPipe, 0x8E, 0x00); + q03_write_register(ViPipe, 0x8B, 0x01); + q03_write_register(ViPipe, 0x0C, 0x00); + q03_write_register(ViPipe, 0xBB, 0x11); + q03_write_register(ViPipe, 0x6A, 0x12); + q03_write_register(ViPipe, 0x65, 0x32); + q03_write_register(ViPipe, 0x82, 0x01); + q03_write_register(ViPipe, 0xA3, 0x20); + q03_write_register(ViPipe, 0xA0, 0x01); + q03_write_register(ViPipe, 0x81, 0x74); + q03_write_register(ViPipe, 0xA2, 0xFF); + q03_write_register(ViPipe, 0x19, 0x20); + + q03_default_reg_init(ViPipe); + + q03_write_register(ViPipe, 0x12, 0x00); + q03_write_register(ViPipe, 0x48, 0x96); + q03_write_register(ViPipe, 0x48, 0x16); + + printf("ViPipe:%d,===Q03 1296P 30fps 10bit LINE FPGA Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx307/Makefile b/middleware/v2/component/isp/sensor/cv180x/sony_imx307/Makefile new file mode 100644 index 000000000..e89c0e113 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx307/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx307.a +TARGET_SO = $(MW_LIB)/libsns_imx307.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx307/imx307_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx307/imx307_cmos.c new file mode 100644 index 000000000..19bf4d83d --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx307/imx307_cmos.c @@ -0,0 +1,1186 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_ae.h" +#include "cvi_isp.h" + +#include "imx307_cmos_ex.h" +#include "imx307_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX307_ID 307 +#define SENSOR_IMX307_WIDTH 1920 +#define SENSOR_IMX307_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx307[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX307_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx307[dev]) +#define IMX307_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx307[dev] = pstCtx) +#define IMX307_SENSOR_RESET_CTX(dev) (g_pastImx307[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunImx307_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx307_GainMode[VI_MAX_PIPE_NUM] = {0}; + +IMX307_STATE_S g_astImx307_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx307_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx307 Lines Range*****/ +#define IMX307_FULL_LINES_MAX (0x3FFFF) +#define IMX307_FULL_LINES_MAX_2TO1_WDR (0x3FFFF) // considering the YOUT_SIZE and bad frame +#define IMX307_VMAX_1080P30_LINEAR 1125 + +/*****Imx307 Register Address*****/ +#define IMX307_HOLD_ADDR 0x3001 +#define IMX307_SHS1_ADDR 0x3020 +#define IMX307_SHS2_ADDR 0x3024 +#define IMX307_GAIN_ADDR 0x3014 +#define IMX307_GAIN1_ADDR 0x30F2 +#define IMX307_HCG_ADDR 0x3009 +#define IMX307_VMAX_ADDR 0x3018 +#define IMX307_YOUT_ADDR 0x3418 +#define IMX307_RHS1_ADDR 0x3030 +#define IMX307_TABLE_END 0xffff + +#define IMX307_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX307_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->enWDRGainMode = SNS_GAIN_MODE_WDR_2F; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astImx307_mode[IMX307_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx307_mode[IMX307_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 45740; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astImx307_mode[IMX307_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx307_mode[IMX307_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 45740; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = IMX307_VMAX_1080P30_LINEAR; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astImx307_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx307_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx307_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case IMX307_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX307_FULL_LINES_MAX_2TO1_WDR) ? IMX307_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case IMX307_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX307_FULL_LINES_MAX) ? IMX307_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } else { + pstSnsRegsInfo->astI2cData[DOL2_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx307_State[ViPipe].u32RHS1_MAX = (u32VMAX - g_astImx307_State[ViPipe].u32BRL) * 2 - 21; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHS1 = 0; + CVI_U32 u32SHS2 = 0; + CVI_U32 u32YOUTSIZE; + CVI_U32 u16BRL = 0; + + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u16BRL = g_astImx307_mode[pstSnsState->u8ImgMode].u16BRL; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[0] < u32LongIntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], u32LongIntTime - 1); + return CVI_FAILURE; + } + u32SHS2 = pstSnsState->au32FL[0] - u32LongIntTime - 1; + + u32SHS1 = (u32ShortIntTime % 2) + 2; + u32RHS1 = u32ShortIntTime + u32SHS1 + 1; + g_astImx307_State[ViPipe].u32RHS1 = u32RHS1; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - (u32SHS1 + 1); + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[0] - (u32SHS2 + 1); + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + u32YOUTSIZE = (u16BRL + (u32RHS1 - 1) / 2) * 2; + u32YOUTSIZE = (u32YOUTSIZE >= 0x1FFF) ? 0x1FFF : u32YOUTSIZE; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHS1 = %d\n", u32ShortIntTime, u32SHS1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d u32YOUTSIZE = %d\n", ViPipe, u32RHS1, u32YOUTSIZE); + + pstSnsRegsInfo->astI2cData[DOL2_SHS1_0].u32Data = (u32SHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_1].u32Data = ((u32SHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_2].u32Data = ((u32SHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHS2_0].u32Data = (u32SHS2 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_1].u32Data = ((u32SHS2 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_2].u32Data = ((u32SHS2 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_0].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_1].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_2].u32Data = ((u32RHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_0].u32Data = (u32YOUTSIZE & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_1].u32Data = ((u32YOUTSIZE & 0x1F00) >> 8); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if (pstSnsState->au32FL[0] < *u32IntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], *u32IntTime - 1); + return CVI_FAILURE; + } + u32Value = pstSnsState->au32FL[0] - *u32IntTime - 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2].u32Data = ((u32Value & 0x30000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 327567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32HCG = g_astImx307_State[ViPipe].u8Hcg; + CVI_U32 u16Mode = g_au16Imx307_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 20) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 20; + } + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = (u32HCG & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + CVI_U8 bEnableHCG = 0; + + if (pu32Again[0] >= 20 && pu32Again[1] >= 20) { + /* hcg bit[4]*/ + u32HCG |= 0x10; + bEnableHCG = 1; + } + + u32Again = pu32Again[1] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + + u32Again = pu32Again[0] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN1].u32Data = (u32Tmp & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 20) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 20; + } + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 2 : 2; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 10; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx307_State[ViPipe].u32RHS1_MAX - 3)) ? + (g_astImx307_State[ViPipe].u32RHS1_MAX - 3) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} +#if 0 +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} +#endif +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX307_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx307_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX307_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = IMX307_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx307_mode[pstSnsState->u8ImgMode].u32VtsDef; + g_astImx307_State[ViPipe].u8Hcg = 0x2; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX307_MODE_1080P30) + pstSnsState->u8ImgMode = IMX307_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + g_astImx307_State[ViPipe].u8Hcg = 0x1; + if (pstSnsState->u8ImgMode == IMX307_MODE_1080P30_WDR) { + pstSnsState->u32FLStd = g_astImx307_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx307_State[ViPipe].u32BRL = g_astImx307_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1080p\n"); + } + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx307_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 2; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx307_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx307_addr_byte; + pstI2c_data[i].u32DataByteNum = imx307_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_HOLD].u32RegAddr = IMX307_HOLD_ADDR; + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_SHS1_0].u32RegAddr = IMX307_SHS1_ADDR; + pstI2c_data[DOL2_SHS1_1].u32RegAddr = IMX307_SHS1_ADDR + 1; + pstI2c_data[DOL2_SHS1_2].u32RegAddr = IMX307_SHS1_ADDR + 2; + + pstI2c_data[DOL2_GAIN].u32RegAddr = IMX307_GAIN_ADDR; + pstI2c_data[DOL2_HCG].u32RegAddr = IMX307_HCG_ADDR; + pstI2c_data[DOL2_HCG].u8DelayFrmNum = 1; + pstI2c_data[DOL2_GAIN1].u32RegAddr = IMX307_GAIN1_ADDR; + pstI2c_data[DOL2_RHS1_0].u32RegAddr = IMX307_RHS1_ADDR; + pstI2c_data[DOL2_RHS1_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_1].u32RegAddr = IMX307_RHS1_ADDR + 1; + pstI2c_data[DOL2_RHS1_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_2].u32RegAddr = IMX307_RHS1_ADDR + 2; + pstI2c_data[DOL2_RHS1_2].u8DelayFrmNum = 1; + pstI2c_data[DOL2_SHS2_0].u32RegAddr = IMX307_SHS2_ADDR; + pstI2c_data[DOL2_SHS2_1].u32RegAddr = IMX307_SHS2_ADDR + 1; + pstI2c_data[DOL2_SHS2_2].u32RegAddr = IMX307_SHS2_ADDR + 2; + pstI2c_data[DOL2_VMAX_0].u32RegAddr = IMX307_VMAX_ADDR; + pstI2c_data[DOL2_VMAX_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_1].u32RegAddr = IMX307_VMAX_ADDR + 1; + pstI2c_data[DOL2_VMAX_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_2].u32RegAddr = IMX307_VMAX_ADDR + 2; + pstI2c_data[DOL2_VMAX_2].u8DelayFrmNum = 1; + + pstI2c_data[DOL2_YOUT_SIZE_0].u32RegAddr = IMX307_YOUT_ADDR; + pstI2c_data[DOL2_YOUT_SIZE_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u32RegAddr = IMX307_YOUT_ADDR + 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_REL].u32RegAddr = IMX307_HOLD_ADDR; + pstI2c_data[DOL2_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 1; + break; + default: + pstI2c_data[LINEAR_HOLD].u32RegAddr = IMX307_HOLD_ADDR; + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_SHS1_0].u32RegAddr = IMX307_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1].u32RegAddr = IMX307_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2].u32RegAddr = IMX307_SHS1_ADDR + 2; + pstI2c_data[LINEAR_GAIN].u32RegAddr = IMX307_GAIN_ADDR; + pstI2c_data[LINEAR_HCG].u32RegAddr = IMX307_HCG_ADDR; + pstI2c_data[LINEAR_HCG].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VMAX_0].u32RegAddr = IMX307_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1].u32RegAddr = IMX307_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_2].u32RegAddr = IMX307_VMAX_ADDR + 2; + pstI2c_data[LINEAR_REL].u32RegAddr = IMX307_HOLD_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[DOL2_REL].u32Data = 0; + pstI2c_data[DOL2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX307_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX307_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX307_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX307_MODE_1080P30_WDR; + g_astImx307_State[ViPipe].u32BRL = 1109; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx307_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx307_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx307_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = IMX307_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = IMX307_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[0] = IMX307_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[1] = IMX307_VMAX_1080P30_LINEAR; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx307_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx307_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx307_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx307_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx307_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx307_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx307_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx307_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX307_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX307_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX307_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX307_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + //AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX307_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } +#if 0 + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stSnsExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } +#endif + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX307_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX307_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } +#if 0 + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX307_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } +#endif + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx307_GainMode[ViPipe] = SNS_GAIN_MODE_WDR_2F; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return imx307_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsImx307_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx307_standby, + .pfnRestart = imx307_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx307_write_register, + .pfnReadReg = imx307_read_register, + .pfnSetBusInfo = imx307_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx307/imx307_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx307/imx307_cmos_ex.h new file mode 100644 index 000000000..f1405f88c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx307/imx307_cmos_ex.h @@ -0,0 +1,124 @@ +#ifndef __IMX307_CMOS_EX_H_ +#define __IMX307_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +/* [TODO] ======== Temporarily definitions start ========*/ +typedef struct _AWB_SENSOR_DEFAULT_S { + CVI_U16 u16InitRgain; /*Init WB gain*/ + CVI_U16 u16InitGgain; + CVI_U16 u16InitBgain; + CVI_U8 u8AWBRunInterval; /*RW;AWB Run Interval*/ +} AWB_SENSOR_DEFAULT_S; + +/* [TODO] ======== Temporarily definitions end ========*/ +enum imx307_linear_regs_e { + LINEAR_HOLD = 0, + LINEAR_SHS1_0, + LINEAR_SHS1_1, + LINEAR_SHS1_2, + LINEAR_GAIN, + LINEAR_HCG, + LINEAR_VMAX_0, + LINEAR_VMAX_1, + LINEAR_VMAX_2, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum imx307_dol2_regs_e { + DOL2_HOLD = 0, + DOL2_SHS1_0, + DOL2_SHS1_1, + DOL2_SHS1_2, + DOL2_GAIN, + DOL2_HCG, + DOL2_GAIN1, + DOL2_RHS1_0, + DOL2_RHS1_1, + DOL2_RHS1_2, + DOL2_SHS2_0, + DOL2_SHS2_1, + DOL2_SHS2_2, + DOL2_VMAX_0, + DOL2_VMAX_1, + DOL2_VMAX_2, + DOL2_YOUT_SIZE_0, + DOL2_YOUT_SIZE_1, + DOL2_REL, + DOL2_REGS_NUM +}; + +typedef enum _IMX307_MODE_E { + IMX307_MODE_1080P30 = 0, + IMX307_MODE_LINEAR_NUM, + IMX307_MODE_1080P30_WDR = IMX307_MODE_LINEAR_NUM, + IMX307_MODE_NUM +} IMX307_MODE_E; + +typedef struct _IMX307_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX307_STATE_S; + +typedef struct _IMX307_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX307_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx307[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx307_BusInfo[]; +extern CVI_U16 g_au16Imx307_GainMode[]; +extern const CVI_U8 imx307_i2c_addr; +extern const CVI_U32 imx307_addr_byte; +extern const CVI_U32 imx307_data_byte; +extern void imx307_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void imx307_init(VI_PIPE ViPipe); +extern void imx307_exit(VI_PIPE ViPipe); +extern void imx307_standby(VI_PIPE ViPipe); +extern void imx307_restart(VI_PIPE ViPipe); +extern int imx307_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx307_read_register(VI_PIPE ViPipe, int addr); +extern int imx307_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX307_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx307/imx307_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx307/imx307_cmos_param.h new file mode 100644 index 000000000..967cebe99 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx307/imx307_cmos_param.h @@ -0,0 +1,308 @@ +#ifndef __IMX307_CMOS_PARAM_H_ +#define __IMX307_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx307_cmos_ex.h" + +static const IMX307_MODE_S g_astImx307_mode[IMX307_MODE_NUM] = { + [IMX307_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x1130, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX307_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 8, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 2236, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 7, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.03396590426564216614, 2.31280159950256347656}, //B: slope, intercept + {0.02877708896994590759, 1.99502599239349365234}, //Gb: slope, intercept + {0.02853375114500522614, 1.53825533390045166016}, //Gr: slope, intercept + {0.02940983884036540985, 2.40369534492492675781}, //R: slope, intercept + }, + { //iso 200 + {0.03635194525122642517, 5.70069074630737304688}, //B: slope, intercept + {0.02990435808897018433, 6.70210981369018554688}, //Gb: slope, intercept + {0.03183263540267944336, 4.92136955261230468750}, //Gr: slope, intercept + {0.03145531564950942993, 5.97894525527954101563}, //R: slope, intercept + }, + { //iso 400 + {0.04329251870512962341, 7.09708356857299804688}, //B: slope, intercept + {0.03147880360484123230, 11.36076831817626953125}, //Gb: slope, intercept + {0.03299136087298393250, 8.49763488769531250000}, //Gr: slope, intercept + {0.03585162013769149780, 8.31188583374023437500}, //R: slope, intercept + }, + { //iso 800 + {0.05740678682923316956, 10.93907737731933593750}, //B: slope, intercept + {0.03538244962692260742, 21.53132820129394531250}, //Gb: slope, intercept + {0.04014955088496208191, 14.56391811370849609375}, //Gr: slope, intercept + {0.03907874971628189087, 15.16305541992187500000}, //R: slope, intercept + }, + { //iso 1600 + {0.05417122691869735718, 23.33716773986816406250}, //B: slope, intercept + {0.02816017158329486847, 55.33533859252929687500}, //Gb: slope, intercept + {0.03809726238250732422, 30.80285072326660156250}, //Gr: slope, intercept + {0.04028835147619247437, 31.24934768676757812500}, //R: slope, intercept + }, + { //iso 3200 + {0.07438381761312484741, 33.81318664550781250000}, //B: slope, intercept + {0.02690842747688293457, 95.65101623535156250000}, //Gb: slope, intercept + {0.05132644250988960266, 46.27661132812500000000}, //Gr: slope, intercept + {0.05343631654977798462, 44.67097473144531250000}, //R: slope, intercept + }, + { //iso 6400 + {0.10831451416015625000, 49.42535018920898437500}, //B: slope, intercept + {0.04577258601784706116, 122.51580810546875000000}, //Gb: slope, intercept + {0.06677398085594177246, 69.54801177978515625000}, //Gr: slope, intercept + {0.07670628279447555542, 63.47140884399414062500}, //R: slope, intercept + }, + { //iso 12800 + {0.15062870085239410400, 68.36373138427734375000}, //B: slope, intercept + {0.07762257009744644165, 146.30807495117187500000}, //Gb: slope, intercept + {0.09608269482851028442, 96.59751892089843750000}, //Gr: slope, intercept + {0.10346080362796783447, 96.64923095703125000000}, //R: slope, intercept + }, + { //iso 25600 + {0.21278673410415649414, 107.37140655517578125000}, //B: slope, intercept + {0.12505164742469787598, 179.24717712402343750000}, //Gb: slope, intercept + {0.14927712082862854004, 140.71289062500000000000}, //Gr: slope, intercept + {0.15530782938003540039, 139.79985046386718750000}, //R: slope, intercept + }, + { //iso 51200 + {0.32940942049026489258, 149.26779174804687500000}, //B: slope, intercept + {0.18958723545074462891, 247.18806457519531250000}, //Gb: slope, intercept + {0.19027391076087951660, 230.56108093261718750000}, //Gr: slope, intercept + {0.23455394804477691650, 192.10685729980468750000}, //R: slope, intercept + }, + { //iso 102400 + {0.48793542385101318359, 210.41285705566406250000}, //B: slope, intercept + {0.24973315000534057617, 372.87121582031250000000}, //Gb: slope, intercept + {0.23015110194683074951, 402.12283325195312500000}, //Gr: slope, intercept + {0.35159105062484741211, 294.27154541015625000000}, //R: slope, intercept + }, + { //iso 204800 + {0.60629695653915405273, 340.77212524414062500000}, //B: slope, intercept + {0.39248645305633544922, 481.49472045898437500000}, //Gb: slope, intercept + {0.33751612901687622070, 544.22698974609375000000}, //Gr: slope, intercept + {0.43583938479423522949, 458.90490722656250000000}, //R: slope, intercept + }, + { //iso 409600 + {0.71151763200759887695, 544.37280273437500000000}, //B: slope, intercept + {0.47628879547119140625, 697.04498291015625000000}, //Gb: slope, intercept + {0.38568580150604248047, 794.64263916015625000000}, //Gr: slope, intercept + {0.54425776004791259766, 658.77343750000000000000}, //R: slope, intercept + }, + { //iso 819200 + {0.61085152626037597656, 821.67352294921875000000}, //B: slope, intercept + {0.38012877106666564941, 1050.61950683593750000000}, //Gb: slope, intercept + {0.38677954673767089844, 1049.79968261718750000000}, //Gr: slope, intercept + {0.54386067390441894531, 875.86968994140625000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.88969016075134277344, 635.22283935546875000000}, //B: slope, intercept + {0.71133875846862792969, 754.16796875000000000000}, //Gb: slope, intercept + {0.66038286685943603516, 765.11163330078125000000}, //Gr: slope, intercept + {0.61520493030548095703, 817.94128417968750000000}, //R: slope, intercept + }, + { //iso 3276800 + {1.43259191513061523438, 263.03683471679687500000}, //B: slope, intercept + {0.87281060218811035156, 624.04595947265625000000}, //Gb: slope, intercept + {0.81407910585403442383, 666.59527587890625000000}, //Gr: slope, intercept + {0.87593811750411987305, 608.70275878906250000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {239, 239, 239, 239, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1087, 1087, 1087, 1087 +#endif + }, + .stAuto = { + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/243, 252, 290, 395, 681, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1228, 1365, 1365, 1365}, +#endif + }, + }, +}; + +struct combo_dev_attr_s imx307_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {2, 3, 1, 4, 0}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_DOL, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX307_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx307/imx307_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx307/imx307_sensor_ctl.c new file mode 100644 index 000000000..c76af0526 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx307/imx307_sensor_ctl.c @@ -0,0 +1,416 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx307_cmos_ex.h" + +static void imx307_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void imx307_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 imx307_i2c_addr = 0x1A; +const CVI_U32 imx307_addr_byte = 2; +const CVI_U32 imx307_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx307_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx307_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx307_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int imx307_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx307_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (imx307_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, imx307_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, imx307_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (imx307_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int imx307_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx307_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx307_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx307_addr_byte + imx307_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx307_standby(VI_PIPE ViPipe) +{ + imx307_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx307_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ +} + +void imx307_restart(VI_PIPE ViPipe) +{ + imx307_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx307_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx307_write_register(ViPipe, 0x304b, 0x0a); +} + +void imx307_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx307[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx307_write_register(ViPipe, + g_pastImx307[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx307[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define IMX307_CHIP_ID_ADDR 0x31dc +#define IMX307_CHIP_ID 0x4 +#define IMX307_CHIP_ID_MASK 0x6 + +void imx307_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = imx307_read_register(ViPipe, 0x3007) & ~0x3; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + imx307_write_register(ViPipe, 0x3007, val); +} + +int imx307_probe(VI_PIPE ViPipe) +{ + int nVal; + + usleep(100); + if (imx307_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = imx307_read_register(ViPipe, IMX307_CHIP_ID_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((nVal & IMX307_CHIP_ID_MASK) != IMX307_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void imx307_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastImx307[ViPipe]->enWDRMode; + u8ImgMode = g_pastImx307[ViPipe]->u8ImgMode; + + imx307_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == IMX307_MODE_1080P30_WDR) { + imx307_wdr_1080p30_2to1_init(ViPipe); + } + } else { + imx307_linear_1080p30_init(ViPipe); + } + g_pastImx307[ViPipe]->bInit = CVI_TRUE; +} + +void imx307_exit(VI_PIPE ViPipe) +{ + imx307_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void imx307_linear_1080p30_init(VI_PIPE ViPipe) +{ + imx307_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx307_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx307_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx307_write_register(ViPipe, 0x3005, 0x01); /* ADBIT 10bit*/ + imx307_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx307_write_register(ViPipe, 0x3009, 0x02); /**/ + imx307_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx307_write_register(ViPipe, 0x3010, 0x21); + imx307_write_register(ViPipe, 0x3011, 0x0A); + imx307_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx307_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx307_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx307_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx307_write_register(ViPipe, 0x301C, 0x30); /* HMAX[7:0], TBD*/ + imx307_write_register(ViPipe, 0x301D, 0x11); /* HMAX[15:8]*/ + imx307_write_register(ViPipe, 0x3020, 0x8C); /* SHS[7:0], TBD*/ + imx307_write_register(ViPipe, 0x3021, 0x01); /* SHS[15:8]*/ + imx307_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx307_write_register(ViPipe, 0x3046, 0x01); + imx307_write_register(ViPipe, 0x304B, 0x0A); + imx307_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx307_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx307_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx307_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx307_write_register(ViPipe, 0x309E, 0x4A); + imx307_write_register(ViPipe, 0x309F, 0x4A); + imx307_write_register(ViPipe, 0x311C, 0x0E); + imx307_write_register(ViPipe, 0x3128, 0x04); + imx307_write_register(ViPipe, 0x3129, 0x00); + imx307_write_register(ViPipe, 0x313B, 0x41); + imx307_write_register(ViPipe, 0x315E, 0x1A); + imx307_write_register(ViPipe, 0x3164, 0x1A); + imx307_write_register(ViPipe, 0x317C, 0x00); + imx307_write_register(ViPipe, 0x31EC, 0x0E); + imx307_write_register(ViPipe, 0x3405, 0x20); /* Repetition*/ + imx307_write_register(ViPipe, 0x3407, 0x03); /* physical_lane_nl*/ + imx307_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx307_write_register(ViPipe, 0x3418, 0x49); /* y_out_size*/ + imx307_write_register(ViPipe, 0x3419, 0x04); /* y_out_size*/ + imx307_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx307_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx307_write_register(ViPipe, 0x3443, 0x03); /* csi_lane_mode*/ + imx307_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx307_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx307_write_register(ViPipe, 0x3446, 0x47); /* tclkpost*/ + imx307_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx307_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx307_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx307_write_register(ViPipe, 0x344A, 0x17); /* thsprepare*/ + imx307_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx307_write_register(ViPipe, 0x344C, 0x0F); /* tclktrail*/ + imx307_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx307_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx307_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx307_write_register(ViPipe, 0x3450, 0x47); /* tclkzero*/ + imx307_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx307_write_register(ViPipe, 0x3452, 0x0F); /* tclkprepare*/ + imx307_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx307_write_register(ViPipe, 0x3454, 0x0F); /* tlpx*/ + imx307_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx307_write_register(ViPipe, 0x3472, 0x9C); /* x_out_size*/ + imx307_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx307_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx307_default_reg_init(ViPipe); + + imx307_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx307_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx307_write_register(ViPipe, 0x304b, 0x0a); + + printf("ViPipe:%d,===IMX307 1080P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void imx307_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + imx307_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx307_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx307_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx307_write_register(ViPipe, 0x3005, 0x01); /* ADBIT*/ + imx307_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx307_write_register(ViPipe, 0x3009, 0x01); /**/ + imx307_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx307_write_register(ViPipe, 0x300C, 0x11); /* WDMODE [0] 0:Normal, 1:DOL, WDSEL [5:4] 1:DOL 2 frames*/ + imx307_write_register(ViPipe, 0x3011, 0x0A); + imx307_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx307_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx307_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx307_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx307_write_register(ViPipe, 0x301C, 0x98); /* HMAX[7:0], TBD*/ + imx307_write_register(ViPipe, 0x301D, 0x08); /* HMAX[15:8]*/ + imx307_write_register(ViPipe, 0x3020, 0x02); /* SHS[7:0], TBD*/ + imx307_write_register(ViPipe, 0x3021, 0x00); /* SHS[15:8]*/ + imx307_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx307_write_register(ViPipe, 0x3024, 0xC9); /* SHS2[7:0], TBD*/ + imx307_write_register(ViPipe, 0x3025, 0x07); /* SHS2[15:8]*/ + imx307_write_register(ViPipe, 0x3026, 0x00); /* SHS2[19:16]*/ + imx307_write_register(ViPipe, 0x3030, 0x0B); /* RHS1[7:0], TBD*/ + imx307_write_register(ViPipe, 0x3031, 0x00); /* RHS1[15:8]*/ + imx307_write_register(ViPipe, 0x3032, 0x00); /* RHS1[19:16]*/ + imx307_write_register(ViPipe, 0x3045, 0x05); /* DOLSCDEN [0] 1: pattern1 0: pattern2*/ + imx307_write_register(ViPipe, 0x3046, 0x01); + imx307_write_register(ViPipe, 0x304B, 0x0A); + imx307_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx307_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx307_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx307_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx307_write_register(ViPipe, 0x309E, 0x4A); + imx307_write_register(ViPipe, 0x309F, 0x4A); + imx307_write_register(ViPipe, 0x3106, 0x11); /*DOLHBFIXEN[7] 0: pattern1 1: pattern2*/ + imx307_write_register(ViPipe, 0x311C, 0x0E); + imx307_write_register(ViPipe, 0x3128, 0x04); + imx307_write_register(ViPipe, 0x3129, 0x00); + imx307_write_register(ViPipe, 0x313B, 0x41); + imx307_write_register(ViPipe, 0x315E, 0x1A); + imx307_write_register(ViPipe, 0x3164, 0x1A); + imx307_write_register(ViPipe, 0x317C, 0x00); + imx307_write_register(ViPipe, 0x31EC, 0x0E); + imx307_write_register(ViPipe, 0x3405, 0x10); /* Repetition*/ + imx307_write_register(ViPipe, 0x3407, 0x03); /* physical_lane_nl*/ + imx307_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx307_write_register(ViPipe, 0x3415, 0x00); /* NULL0_SIZE_V, set to 00h when DOL*/ + imx307_write_register(ViPipe, 0x3418, 0xB4); /* y_out_size*/ + imx307_write_register(ViPipe, 0x3419, 0x08); /* y_out_size*/ + imx307_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx307_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx307_write_register(ViPipe, 0x3443, 0x03); /* csi_lane_mode*/ + imx307_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx307_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx307_write_register(ViPipe, 0x3446, 0x57); /* tclkpost*/ + imx307_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx307_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx307_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx307_write_register(ViPipe, 0x344A, 0x1F); /* thsprepare*/ + imx307_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx307_write_register(ViPipe, 0x344C, 0x1F); /* tclktrail*/ + imx307_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx307_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx307_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx307_write_register(ViPipe, 0x3450, 0x77); /* tclkzero*/ + imx307_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx307_write_register(ViPipe, 0x3452, 0x1F); /* tclkprepare*/ + imx307_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx307_write_register(ViPipe, 0x3454, 0x17); /* tlpx*/ + imx307_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx307_write_register(ViPipe, 0x3472, 0xA0); /* x_out_size*/ + imx307_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx307_write_register(ViPipe, 0x347B, 0x23); /**/ + imx307_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx307_default_reg_init(ViPipe); + + if (g_au16Imx307_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + imx307_write_register(ViPipe, 0x30F0, 0xF0); + imx307_write_register(ViPipe, 0x3010, 0x21); + } else { + imx307_write_register(ViPipe, 0x30F0, 0x64); + imx307_write_register(ViPipe, 0x3010, 0x61); + } + + imx307_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx307_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx307_write_register(ViPipe, 0x304b, 0x0a); + + printf("===Imx307 sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx307_2L/Makefile b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_2L/Makefile new file mode 100644 index 000000000..304509b36 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_2L/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx307_2l.a +TARGET_SO = $(MW_LIB)/libsns_imx307_2l.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx307_2L/imx307_2l_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_2L/imx307_2l_cmos.c new file mode 100644 index 000000000..4ea605bc1 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_2L/imx307_2l_cmos.c @@ -0,0 +1,1181 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_ae.h" +#include "cvi_isp.h" + +#include "imx307_2l_cmos_ex.h" +#include "imx307_2l_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX307_2L_ID 307 +#define SENSOR_IMX307_2L_WIDTH 1920 +#define SENSOR_IMX307_2L_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx307_2l[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX307_2L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx307_2l[dev]) +#define IMX307_2L_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx307_2l[dev] = pstCtx) +#define IMX307_2L_SENSOR_RESET_CTX(dev) (g_pastImx307_2l[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunImx307_2l_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx307_2l_GainMode[VI_MAX_PIPE_NUM] = {0}; + +IMX307_2L_STATE_S g_astImx307_2l_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx307_2l_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx307 Lines Range*****/ +#define IMX307_2L_FULL_LINES_MAX (0x3FFFF) +#define IMX307_2L_FULL_LINES_MAX_2TO1_WDR (0x3FFFF) // considering the YOUT_SIZE and bad frame +#define IMX307_2L_VMAX_1080P30_LINEAR 1125 + +/*****Imx307 Register Address*****/ +#define IMX307_2L_HOLD_ADDR 0x3001 +#define IMX307_2L_SHS1_ADDR 0x3020 +#define IMX307_2L_SHS2_ADDR 0x3024 +#define IMX307_2L_GAIN_ADDR 0x3014 +#define IMX307_2L_GAIN1_ADDR 0x30F2 +#define IMX307_2L_HCG_ADDR 0x3009 +#define IMX307_2L_VMAX_ADDR 0x3018 +#define IMX307_2L_YOUT_ADDR 0x3418 +#define IMX307_2L_RHS1_ADDR 0x3030 +#define IMX307_2L_TABLE_END 0xffff + +#define IMX307_2L_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX307_2L_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astImx307_2l_mode[IMX307_2L_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx307_2l_mode[IMX307_2L_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 45740; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astImx307_2l_mode[IMX307_2L_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx307_2l_mode[IMX307_2L_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 45740; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = IMX307_2L_VMAX_1080P30_LINEAR; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astImx307_2l_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx307_2l_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx307_2l_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case IMX307_2L_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX307_2L_FULL_LINES_MAX_2TO1_WDR) ? IMX307_2L_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case IMX307_2L_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX307_2L_FULL_LINES_MAX) ? IMX307_2L_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } else { + pstSnsRegsInfo->astI2cData[DOL2_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx307_2l_State[ViPipe].u32RHS1_MAX = (u32VMAX - g_astImx307_2l_State[ViPipe].u32BRL) * 2 - 21; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHS1 = 0; + CVI_U32 u32SHS2 = 0; + CVI_U32 u32YOUTSIZE; + CVI_U32 u16BRL = 0; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u16BRL = g_astImx307_2l_mode[pstSnsState->u8ImgMode].u16BRL; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[0] < u32LongIntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], u32LongIntTime - 1); + return CVI_FAILURE; + } + u32SHS2 = pstSnsState->au32FL[0] - u32LongIntTime - 1; + + u32SHS1 = (u32ShortIntTime % 2) + 2; + u32RHS1 = u32ShortIntTime + u32SHS1 + 1; + g_astImx307_2l_State[ViPipe].u32RHS1 = u32RHS1; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - (u32SHS1 + 1); + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[0] - (u32SHS2 + 1); + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + u32YOUTSIZE = (u16BRL + (u32RHS1 - 1) / 2) * 2; + u32YOUTSIZE = (u32YOUTSIZE >= 0x1FFF) ? 0x1FFF : u32YOUTSIZE; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHS1 = %d\n", u32ShortIntTime, u32SHS1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d u32YOUTSIZE = %d\n", ViPipe, u32RHS1, u32YOUTSIZE); + + pstSnsRegsInfo->astI2cData[DOL2_SHS1_0].u32Data = (u32SHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_1].u32Data = ((u32SHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_2].u32Data = ((u32SHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHS2_0].u32Data = (u32SHS2 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_1].u32Data = ((u32SHS2 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_2].u32Data = ((u32SHS2 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_0].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_1].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_2].u32Data = ((u32RHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_0].u32Data = (u32YOUTSIZE & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_1].u32Data = ((u32YOUTSIZE & 0x1F00) >> 8); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if (pstSnsState->au32FL[0] < *u32IntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], *u32IntTime - 1); + return CVI_FAILURE; + } + u32Value = pstSnsState->au32FL[0] - *u32IntTime - 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2].u32Data = ((u32Value & 0x30000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 327567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32HCG = g_astImx307_2l_State[ViPipe].u8Hcg; + CVI_U32 u16Mode = g_au16Imx307_2l_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 20) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 20; + } + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = (u32HCG & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + CVI_U8 bEnableHCG = 0; + + if (pu32Again[0] >= 20 && pu32Again[1] >= 20) { + /* hcg bit[4]*/ + u32HCG |= 0x10; + bEnableHCG = 1; + } + + u32Again = pu32Again[1] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + + u32Again = pu32Again[0] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN1].u32Data = (u32Tmp & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 20) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 20; + } + + u32Tmp = u32Again + u32Dgain; + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 2 : 2; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 10; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx307_2l_State[ViPipe].u32RHS1_MAX - 3)) ? + (g_astImx307_2l_State[ViPipe].u32RHS1_MAX - 3) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} +#if 0 +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} +#endif +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX307_2L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx307_2l_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX307_2L_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = IMX307_2L_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx307_2l_mode[pstSnsState->u8ImgMode].u32VtsDef; + g_astImx307_2l_State[ViPipe].u8Hcg = 0x2; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX307_2L_MODE_1080P30) + pstSnsState->u8ImgMode = IMX307_2L_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + g_astImx307_2l_State[ViPipe].u8Hcg = 0x1; + if (pstSnsState->u8ImgMode == IMX307_2L_MODE_1080P30_WDR) { + pstSnsState->u32FLStd = g_astImx307_2l_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx307_2l_State[ViPipe].u32BRL = g_astImx307_2l_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1080p\n"); + } + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx307_2l_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 2; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx307_2l_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx307_2l_addr_byte; + pstI2c_data[i].u32DataByteNum = imx307_2l_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_HOLD].u32RegAddr = IMX307_2L_HOLD_ADDR; + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_SHS1_0].u32RegAddr = IMX307_2L_SHS1_ADDR; + pstI2c_data[DOL2_SHS1_1].u32RegAddr = IMX307_2L_SHS1_ADDR + 1; + pstI2c_data[DOL2_SHS1_2].u32RegAddr = IMX307_2L_SHS1_ADDR + 2; + + pstI2c_data[DOL2_GAIN].u32RegAddr = IMX307_2L_GAIN_ADDR; + pstI2c_data[DOL2_HCG].u32RegAddr = IMX307_2L_HCG_ADDR; + pstI2c_data[DOL2_HCG].u8DelayFrmNum = 1; + pstI2c_data[DOL2_GAIN1].u32RegAddr = IMX307_2L_GAIN1_ADDR; + pstI2c_data[DOL2_RHS1_0].u32RegAddr = IMX307_2L_RHS1_ADDR; + pstI2c_data[DOL2_RHS1_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_1].u32RegAddr = IMX307_2L_RHS1_ADDR + 1; + pstI2c_data[DOL2_RHS1_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_2].u32RegAddr = IMX307_2L_RHS1_ADDR + 2; + pstI2c_data[DOL2_RHS1_2].u8DelayFrmNum = 1; + pstI2c_data[DOL2_SHS2_0].u32RegAddr = IMX307_2L_SHS2_ADDR; + pstI2c_data[DOL2_SHS2_1].u32RegAddr = IMX307_2L_SHS2_ADDR + 1; + pstI2c_data[DOL2_SHS2_2].u32RegAddr = IMX307_2L_SHS2_ADDR + 2; + pstI2c_data[DOL2_VMAX_0].u32RegAddr = IMX307_2L_VMAX_ADDR; + pstI2c_data[DOL2_VMAX_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_1].u32RegAddr = IMX307_2L_VMAX_ADDR + 1; + pstI2c_data[DOL2_VMAX_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_2].u32RegAddr = IMX307_2L_VMAX_ADDR + 2; + pstI2c_data[DOL2_VMAX_2].u8DelayFrmNum = 1; + + pstI2c_data[DOL2_YOUT_SIZE_0].u32RegAddr = IMX307_2L_YOUT_ADDR; + pstI2c_data[DOL2_YOUT_SIZE_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u32RegAddr = IMX307_2L_YOUT_ADDR + 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_REL].u32RegAddr = IMX307_2L_HOLD_ADDR; + pstI2c_data[DOL2_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 1; + break; + default: + pstI2c_data[LINEAR_HOLD].u32RegAddr = IMX307_2L_HOLD_ADDR; + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_SHS1_0].u32RegAddr = IMX307_2L_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1].u32RegAddr = IMX307_2L_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2].u32RegAddr = IMX307_2L_SHS1_ADDR + 2; + pstI2c_data[LINEAR_GAIN].u32RegAddr = IMX307_2L_GAIN_ADDR; + pstI2c_data[LINEAR_HCG].u32RegAddr = IMX307_2L_HCG_ADDR; + pstI2c_data[LINEAR_HCG].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VMAX_0].u32RegAddr = IMX307_2L_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1].u32RegAddr = IMX307_2L_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_2].u32RegAddr = IMX307_2L_VMAX_ADDR + 2; + pstI2c_data[LINEAR_REL].u32RegAddr = IMX307_2L_HOLD_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[DOL2_REL].u32Data = 0; + pstI2c_data[DOL2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX307_2L_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX307_2L_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX307_2L_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX307_2L_MODE_1080P30_WDR; + g_astImx307_2l_State[ViPipe].u32BRL = 1109; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx307_2l_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx307_2l_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx307_2l_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = IMX307_2L_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = IMX307_2L_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[0] = IMX307_2L_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[1] = IMX307_2L_VMAX_1080P30_LINEAR; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx307_2l_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx307_2l_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx307_2l_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx307_2l_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx307_2l_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx307_2l_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx307_2l_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx307_2l_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX307_2L_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX307_2L_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + //AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX307_2L_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } +#if 0 + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stSnsExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } +#endif + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX307_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX307_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } +#if 0 + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX307_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } +#endif + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx307_2l_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return imx307_2l_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsImx307_2l_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx307_2l_standby, + .pfnRestart = imx307_2l_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx307_2l_write_register, + .pfnReadReg = imx307_2l_read_register, + .pfnSetBusInfo = imx307_2l_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx307_2L/imx307_2l_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_2L/imx307_2l_cmos_ex.h new file mode 100644 index 000000000..abdddde7c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_2L/imx307_2l_cmos_ex.h @@ -0,0 +1,124 @@ +#ifndef __IMX307_2L_CMOS_EX_H_ +#define __IMX307_2L_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +/* [TODO] ======== Temporarily definitions start ========*/ +typedef struct _AWB_SENSOR_DEFAULT_S { + CVI_U16 u16InitRgain; /*Init WB gain*/ + CVI_U16 u16InitGgain; + CVI_U16 u16InitBgain; + CVI_U8 u8AWBRunInterval; /*RW;AWB Run Interval*/ +} AWB_SENSOR_DEFAULT_S; + +/* [TODO] ======== Temporarily definitions end ========*/ +enum imx307_2l_linear_regs_e { + LINEAR_HOLD = 0, + LINEAR_SHS1_0, + LINEAR_SHS1_1, + LINEAR_SHS1_2, + LINEAR_GAIN, + LINEAR_HCG, + LINEAR_VMAX_0, + LINEAR_VMAX_1, + LINEAR_VMAX_2, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum imx307_2l_dol2_regs_e { + DOL2_HOLD = 0, + DOL2_SHS1_0, + DOL2_SHS1_1, + DOL2_SHS1_2, + DOL2_GAIN, + DOL2_HCG, + DOL2_GAIN1, + DOL2_RHS1_0, + DOL2_RHS1_1, + DOL2_RHS1_2, + DOL2_SHS2_0, + DOL2_SHS2_1, + DOL2_SHS2_2, + DOL2_VMAX_0, + DOL2_VMAX_1, + DOL2_VMAX_2, + DOL2_YOUT_SIZE_0, + DOL2_YOUT_SIZE_1, + DOL2_REL, + DOL2_REGS_NUM +}; + +typedef enum _IMX307_2L_MODE_E { + IMX307_2L_MODE_1080P30 = 0, + IMX307_2L_MODE_LINEAR_NUM, + IMX307_2L_MODE_1080P30_WDR = IMX307_2L_MODE_LINEAR_NUM, + IMX307_2L_MODE_NUM +} IMX307_2L_MODE_E; + +typedef struct _IMX307_2L_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX307_2L_STATE_S; + +typedef struct _IMX307_2L_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX307_2L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx307_2l[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx307_2l_BusInfo[]; +extern CVI_U16 g_au16Imx307_2l_GainMode[]; +extern const CVI_U8 imx307_2l_i2c_addr; +extern const CVI_U32 imx307_2l_addr_byte; +extern const CVI_U32 imx307_2l_data_byte; +extern void imx307_2l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void imx307_2l_init(VI_PIPE ViPipe); +extern void imx307_2l_exit(VI_PIPE ViPipe); +extern void imx307_2l_standby(VI_PIPE ViPipe); +extern void imx307_2l_restart(VI_PIPE ViPipe); +extern int imx307_2l_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx307_2l_read_register(VI_PIPE ViPipe, int addr); +extern int imx307_2l_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX307_2L_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx307_2L/imx307_2l_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_2L/imx307_2l_cmos_param.h new file mode 100644 index 000000000..ad2475a18 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_2L/imx307_2l_cmos_param.h @@ -0,0 +1,308 @@ +#ifndef __IMX307_2L_CMOS_PARAM_H_ +#define __IMX307_2L_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx307_2l_cmos_ex.h" + +static const IMX307_2L_MODE_S g_astImx307_2l_mode[IMX307_2L_MODE_NUM] = { + [IMX307_2L_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x1130, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX307_2L_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 8, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 2236, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 7, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.03396590426564216614, 2.31280159950256347656}, //B: slope, intercept + {0.02877708896994590759, 1.99502599239349365234}, //Gb: slope, intercept + {0.02853375114500522614, 1.53825533390045166016}, //Gr: slope, intercept + {0.02940983884036540985, 2.40369534492492675781}, //R: slope, intercept + }, + { //iso 200 + {0.03635194525122642517, 5.70069074630737304688}, //B: slope, intercept + {0.02990435808897018433, 6.70210981369018554688}, //Gb: slope, intercept + {0.03183263540267944336, 4.92136955261230468750}, //Gr: slope, intercept + {0.03145531564950942993, 5.97894525527954101563}, //R: slope, intercept + }, + { //iso 400 + {0.04329251870512962341, 7.09708356857299804688}, //B: slope, intercept + {0.03147880360484123230, 11.36076831817626953125}, //Gb: slope, intercept + {0.03299136087298393250, 8.49763488769531250000}, //Gr: slope, intercept + {0.03585162013769149780, 8.31188583374023437500}, //R: slope, intercept + }, + { //iso 800 + {0.05740678682923316956, 10.93907737731933593750}, //B: slope, intercept + {0.03538244962692260742, 21.53132820129394531250}, //Gb: slope, intercept + {0.04014955088496208191, 14.56391811370849609375}, //Gr: slope, intercept + {0.03907874971628189087, 15.16305541992187500000}, //R: slope, intercept + }, + { //iso 1600 + {0.05417122691869735718, 23.33716773986816406250}, //B: slope, intercept + {0.02816017158329486847, 55.33533859252929687500}, //Gb: slope, intercept + {0.03809726238250732422, 30.80285072326660156250}, //Gr: slope, intercept + {0.04028835147619247437, 31.24934768676757812500}, //R: slope, intercept + }, + { //iso 3200 + {0.07438381761312484741, 33.81318664550781250000}, //B: slope, intercept + {0.02690842747688293457, 95.65101623535156250000}, //Gb: slope, intercept + {0.05132644250988960266, 46.27661132812500000000}, //Gr: slope, intercept + {0.05343631654977798462, 44.67097473144531250000}, //R: slope, intercept + }, + { //iso 6400 + {0.10831451416015625000, 49.42535018920898437500}, //B: slope, intercept + {0.04577258601784706116, 122.51580810546875000000}, //Gb: slope, intercept + {0.06677398085594177246, 69.54801177978515625000}, //Gr: slope, intercept + {0.07670628279447555542, 63.47140884399414062500}, //R: slope, intercept + }, + { //iso 12800 + {0.15062870085239410400, 68.36373138427734375000}, //B: slope, intercept + {0.07762257009744644165, 146.30807495117187500000}, //Gb: slope, intercept + {0.09608269482851028442, 96.59751892089843750000}, //Gr: slope, intercept + {0.10346080362796783447, 96.64923095703125000000}, //R: slope, intercept + }, + { //iso 25600 + {0.21278673410415649414, 107.37140655517578125000}, //B: slope, intercept + {0.12505164742469787598, 179.24717712402343750000}, //Gb: slope, intercept + {0.14927712082862854004, 140.71289062500000000000}, //Gr: slope, intercept + {0.15530782938003540039, 139.79985046386718750000}, //R: slope, intercept + }, + { //iso 51200 + {0.32940942049026489258, 149.26779174804687500000}, //B: slope, intercept + {0.18958723545074462891, 247.18806457519531250000}, //Gb: slope, intercept + {0.19027391076087951660, 230.56108093261718750000}, //Gr: slope, intercept + {0.23455394804477691650, 192.10685729980468750000}, //R: slope, intercept + }, + { //iso 102400 + {0.48793542385101318359, 210.41285705566406250000}, //B: slope, intercept + {0.24973315000534057617, 372.87121582031250000000}, //Gb: slope, intercept + {0.23015110194683074951, 402.12283325195312500000}, //Gr: slope, intercept + {0.35159105062484741211, 294.27154541015625000000}, //R: slope, intercept + }, + { //iso 204800 + {0.60629695653915405273, 340.77212524414062500000}, //B: slope, intercept + {0.39248645305633544922, 481.49472045898437500000}, //Gb: slope, intercept + {0.33751612901687622070, 544.22698974609375000000}, //Gr: slope, intercept + {0.43583938479423522949, 458.90490722656250000000}, //R: slope, intercept + }, + { //iso 409600 + {0.71151763200759887695, 544.37280273437500000000}, //B: slope, intercept + {0.47628879547119140625, 697.04498291015625000000}, //Gb: slope, intercept + {0.38568580150604248047, 794.64263916015625000000}, //Gr: slope, intercept + {0.54425776004791259766, 658.77343750000000000000}, //R: slope, intercept + }, + { //iso 819200 + {0.61085152626037597656, 821.67352294921875000000}, //B: slope, intercept + {0.38012877106666564941, 1050.61950683593750000000}, //Gb: slope, intercept + {0.38677954673767089844, 1049.79968261718750000000}, //Gr: slope, intercept + {0.54386067390441894531, 875.86968994140625000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.88969016075134277344, 635.22283935546875000000}, //B: slope, intercept + {0.71133875846862792969, 754.16796875000000000000}, //Gb: slope, intercept + {0.66038286685943603516, 765.11163330078125000000}, //Gr: slope, intercept + {0.61520493030548095703, 817.94128417968750000000}, //R: slope, intercept + }, + { //iso 3276800 + {1.43259191513061523438, 263.03683471679687500000}, //B: slope, intercept + {0.87281060218811035156, 624.04595947265625000000}, //Gb: slope, intercept + {0.81407910585403442383, 666.59527587890625000000}, //Gr: slope, intercept + {0.87593811750411987305, 608.70275878906250000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {239, 239, 239, 239, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1087, 1087, 1087, 1087 +#endif + }, + .stAuto = { + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/243, 252, 290, 395, 681, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1228, 1365, 1365, 1365}, +#endif + }, + }, +}; + +struct combo_dev_attr_s imx307_2l_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {2, 1, 0, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_DOL, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX307_2L_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx307_2L/imx307_2l_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_2L/imx307_2l_sensor_ctl.c new file mode 100644 index 000000000..3a6a472eb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_2L/imx307_2l_sensor_ctl.c @@ -0,0 +1,417 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx307_2l_cmos_ex.h" + +static void imx307_2l_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void imx307_2l_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 imx307_2l_i2c_addr = 0x1A; +const CVI_U32 imx307_2l_addr_byte = 2; +const CVI_U32 imx307_2l_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx307_2l_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx307_2l_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx307_2l_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int imx307_2l_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx307_2l_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (imx307_2l_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, imx307_2l_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, imx307_2l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (imx307_2l_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int imx307_2l_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx307_2l_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx307_2l_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx307_2l_addr_byte + imx307_2l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx307_2l_standby(VI_PIPE ViPipe) +{ + imx307_2l_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx307_2l_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ +} + +void imx307_2l_restart(VI_PIPE ViPipe) +{ + imx307_2l_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx307_2l_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx307_2l_write_register(ViPipe, 0x304b, 0x0a); +} + +void imx307_2l_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx307_2l[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx307_2l_write_register(ViPipe, + g_pastImx307_2l[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx307_2l[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define IMX307_CHIP_ID_ADDR 0x31dc +#define IMX307_CHIP_ID 0x4 +#define IMX307_CHIP_ID_MASK 0x6 + +void imx307_2l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = imx307_2l_read_register(ViPipe, 0x3007) & ~0x3; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + imx307_2l_write_register(ViPipe, 0x3007, val); +} + +int imx307_2l_probe(VI_PIPE ViPipe) +{ + int nVal; + + usleep(100); + if (imx307_2l_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = imx307_2l_read_register(ViPipe, IMX307_CHIP_ID_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((nVal & IMX307_CHIP_ID_MASK) != IMX307_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void imx307_2l_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastImx307_2l[ViPipe]->enWDRMode; + u8ImgMode = g_pastImx307_2l[ViPipe]->u8ImgMode; + + imx307_2l_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == IMX307_2L_MODE_1080P30_WDR) { + imx307_2l_wdr_1080p30_2to1_init(ViPipe); + } + } else { + imx307_2l_linear_1080p30_init(ViPipe); + } + g_pastImx307_2l[ViPipe]->bInit = CVI_TRUE; +} + +void imx307_2l_exit(VI_PIPE ViPipe) +{ + imx307_2l_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void imx307_2l_linear_1080p30_init(VI_PIPE ViPipe) +{ + imx307_2l_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx307_2l_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx307_2l_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx307_2l_write_register(ViPipe, 0x3005, 0x01); /* ADBIT 10bit*/ + imx307_2l_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx307_2l_write_register(ViPipe, 0x3009, 0x02); /**/ + imx307_2l_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx307_2l_write_register(ViPipe, 0x3011, 0x0A); + imx307_2l_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx307_2l_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx307_2l_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx307_2l_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx307_2l_write_register(ViPipe, 0x301C, 0x30); /* HMAX[7:0], TBD*/ + imx307_2l_write_register(ViPipe, 0x301D, 0x11); /* HMAX[15:8]*/ + imx307_2l_write_register(ViPipe, 0x3020, 0x8C); /* SHS[7:0], TBD*/ + imx307_2l_write_register(ViPipe, 0x3021, 0x01); /* SHS[15:8]*/ + imx307_2l_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx307_2l_write_register(ViPipe, 0x3046, 0x01); + imx307_2l_write_register(ViPipe, 0x304B, 0x0A); + imx307_2l_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx307_2l_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx307_2l_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx307_2l_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx307_2l_write_register(ViPipe, 0x309E, 0x4A); + imx307_2l_write_register(ViPipe, 0x309F, 0x4A); + imx307_2l_write_register(ViPipe, 0x311C, 0x0E); + imx307_2l_write_register(ViPipe, 0x3128, 0x04); + imx307_2l_write_register(ViPipe, 0x3129, 0x00); + imx307_2l_write_register(ViPipe, 0x313B, 0x41); + imx307_2l_write_register(ViPipe, 0x315E, 0x1A); + imx307_2l_write_register(ViPipe, 0x3164, 0x1A); + imx307_2l_write_register(ViPipe, 0x317C, 0x00); + imx307_2l_write_register(ViPipe, 0x31EC, 0x0E); + imx307_2l_write_register(ViPipe, 0x3405, 0x10); /* Repetition*/ + imx307_2l_write_register(ViPipe, 0x3407, 0x01); /* physical_lane_nl*/ + imx307_2l_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx307_2l_write_register(ViPipe, 0x3418, 0x49); /* y_out_size*/ + imx307_2l_write_register(ViPipe, 0x3419, 0x04); /* y_out_size*/ + imx307_2l_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx307_2l_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx307_2l_write_register(ViPipe, 0x3443, 0x01); /* csi_lane_mode*/ + imx307_2l_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx307_2l_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx307_2l_write_register(ViPipe, 0x3446, 0x57); /* tclkpost*/ + imx307_2l_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + //imx307_2l_write_register(ViPipe, 0x3448, 0x37); /* thszero*/ + imx307_2l_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx307_2l_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx307_2l_write_register(ViPipe, 0x344A, 0x1F); /* thsprepare*/ + imx307_2l_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx307_2l_write_register(ViPipe, 0x344C, 0x1F); /* tclktrail*/ + imx307_2l_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + //imx307_2l_write_register(ViPipe, 0x344E, 0x1F); /* thstrail*/ + imx307_2l_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx307_2l_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx307_2l_write_register(ViPipe, 0x3450, 0x77); /* tclkzero*/ + imx307_2l_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx307_2l_write_register(ViPipe, 0x3452, 0x1F); /* tclkprepare*/ + imx307_2l_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx307_2l_write_register(ViPipe, 0x3454, 0x17); /* tlpx*/ + imx307_2l_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx307_2l_write_register(ViPipe, 0x3472, 0x9C); /* x_out_size*/ + imx307_2l_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx307_2l_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx307_2l_default_reg_init(ViPipe); + + imx307_2l_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx307_2l_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx307_2l_write_register(ViPipe, 0x304b, 0x0a); + + printf("ViPipe:%d,===IMX307 1080P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void imx307_2l_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + imx307_2l_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx307_2l_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx307_2l_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx307_2l_write_register(ViPipe, 0x3005, 0x01); /* ADBIT*/ + imx307_2l_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx307_2l_write_register(ViPipe, 0x3009, 0x01); /**/ + imx307_2l_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx307_2l_write_register(ViPipe, 0x300C, 0x11); /* WDMODE [0] 0:Normal, 1:DOL, WDSEL [5:4] 1:DOL 2 frames*/ + imx307_2l_write_register(ViPipe, 0x3011, 0x0A); + imx307_2l_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx307_2l_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx307_2l_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx307_2l_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx307_2l_write_register(ViPipe, 0x301C, 0x98); /* HMAX[7:0], TBD*/ + imx307_2l_write_register(ViPipe, 0x301D, 0x08); /* HMAX[15:8]*/ + imx307_2l_write_register(ViPipe, 0x3020, 0x02); /* SHS[7:0], TBD*/ + imx307_2l_write_register(ViPipe, 0x3021, 0x00); /* SHS[15:8]*/ + imx307_2l_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx307_2l_write_register(ViPipe, 0x3024, 0xC9); /* SHS2[7:0], TBD*/ + imx307_2l_write_register(ViPipe, 0x3025, 0x07); /* SHS2[15:8]*/ + imx307_2l_write_register(ViPipe, 0x3026, 0x00); /* SHS2[19:16]*/ + imx307_2l_write_register(ViPipe, 0x3030, 0x0B); /* RHS1[7:0], TBD*/ + imx307_2l_write_register(ViPipe, 0x3031, 0x00); /* RHS1[15:8]*/ + imx307_2l_write_register(ViPipe, 0x3032, 0x00); /* RHS1[19:16]*/ + imx307_2l_write_register(ViPipe, 0x3045, 0x05); /* DOLSCDEN [0] 1: pattern1 0: pattern2*/ + imx307_2l_write_register(ViPipe, 0x3046, 0x01); + imx307_2l_write_register(ViPipe, 0x304B, 0x0A); + imx307_2l_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx307_2l_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx307_2l_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx307_2l_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx307_2l_write_register(ViPipe, 0x309E, 0x4A); + imx307_2l_write_register(ViPipe, 0x309F, 0x4A); + imx307_2l_write_register(ViPipe, 0x3106, 0x15); /*DOLHBFIXEN[7] 0: pattern1 1: pattern2*/ + imx307_2l_write_register(ViPipe, 0x311C, 0x0E); + imx307_2l_write_register(ViPipe, 0x3128, 0x04); + imx307_2l_write_register(ViPipe, 0x3129, 0x00); + imx307_2l_write_register(ViPipe, 0x313B, 0x41); + imx307_2l_write_register(ViPipe, 0x315E, 0x1A); + imx307_2l_write_register(ViPipe, 0x3164, 0x1A); + imx307_2l_write_register(ViPipe, 0x317C, 0x00); + imx307_2l_write_register(ViPipe, 0x31EC, 0x0E); + imx307_2l_write_register(ViPipe, 0x3405, 0x00); /* Repetition*/ + imx307_2l_write_register(ViPipe, 0x3407, 0x01); /* physical_lane_nl*/ + imx307_2l_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx307_2l_write_register(ViPipe, 0x3415, 0x00); /* NULL0_SIZE_V, set to 00h when DOL*/ + imx307_2l_write_register(ViPipe, 0x3418, 0xB4); /* y_out_size*/ + imx307_2l_write_register(ViPipe, 0x3419, 0x08); /* y_out_size*/ + imx307_2l_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx307_2l_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx307_2l_write_register(ViPipe, 0x3443, 0x01); /* csi_lane_mode*/ + imx307_2l_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx307_2l_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx307_2l_write_register(ViPipe, 0x3446, 0x77); /* tclkpost*/ + imx307_2l_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx307_2l_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx307_2l_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx307_2l_write_register(ViPipe, 0x344A, 0x47); /* thsprepare*/ + imx307_2l_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx307_2l_write_register(ViPipe, 0x344C, 0x37); /* tclktrail*/ + imx307_2l_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx307_2l_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx307_2l_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx307_2l_write_register(ViPipe, 0x3450, 0xFF); /* tclkzero*/ + imx307_2l_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx307_2l_write_register(ViPipe, 0x3452, 0x3F); /* tclkprepare*/ + imx307_2l_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx307_2l_write_register(ViPipe, 0x3454, 0x37); /* tlpx*/ + imx307_2l_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx307_2l_write_register(ViPipe, 0x3472, 0xA0); /* x_out_size*/ + imx307_2l_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx307_2l_write_register(ViPipe, 0x347B, 0x23); /**/ + imx307_2l_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx307_2l_default_reg_init(ViPipe); + + if (g_au16Imx307_2l_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + imx307_2l_write_register(ViPipe, 0x30F0, 0xF0); + imx307_2l_write_register(ViPipe, 0x3010, 0x21); + } else { + imx307_2l_write_register(ViPipe, 0x30F0, 0x64); + imx307_2l_write_register(ViPipe, 0x3010, 0x61); + } + + imx307_2l_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx307_2l_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx307_2l_write_register(ViPipe, 0x304b, 0x0a); + + printf("===Imx307 sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx307_slave/Makefile b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_slave/Makefile new file mode 100644 index 000000000..39bacf8ec --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_slave/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx307_slave.a +TARGET_SO = $(MW_LIB)/libsns_imx307_slave.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx307_slave/imx307_slave_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_slave/imx307_slave_cmos.c new file mode 100644 index 000000000..287396783 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_slave/imx307_slave_cmos.c @@ -0,0 +1,1185 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_ae.h" +#include "cvi_isp.h" + +#include "imx307_slave_cmos_ex.h" +#include "imx307_slave_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX307_SLAVE_ID 307 +#define SENSOR_IMX307_SLAVE_WIDTH 1920 +#define SENSOR_IMX307_SLAVE_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx307_Slave[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX307_SLAVE_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx307_Slave[dev]) +#define IMX307_SLAVE_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx307_Slave[dev] = pstCtx) +#define IMX307_SLAVE_SENSOR_RESET_CTX(dev) (g_pastImx307_Slave[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunImx307_Slave_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx307_Slave_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Imx307_Slave_UseHwSync[VI_MAX_PIPE_NUM] = {0}; + +IMX307_SLAVE_STATE_S g_astImx307_Slave_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx307_Slave_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx307 Lines Range*****/ +#define IMX307_SLAVE_FULL_LINES_MAX (0x3FFFF) +#define IMX307_SLAVE_FULL_LINES_MAX_2TO1_WDR (0x3FFFF) // considering the YOUT_SIZE and bad frame +#define IMX307_SLAVE_VMAX_1080P30_LINEAR 1125 + +/*****Imx307 Register Address*****/ +#define IMX307_SLAVE_HOLD_ADDR 0x3001 +#define IMX307_SLAVE_SHS1_ADDR 0x3020 +#define IMX307_SLAVE_SHS2_ADDR 0x3024 +#define IMX307_SLAVE_GAIN_ADDR 0x3014 +#define IMX307_SLAVE_GAIN1_ADDR 0x30F2 +#define IMX307_SLAVE_HCG_ADDR 0x3009 +#define IMX307_SLAVE_VMAX_ADDR 0x3018 +#define IMX307_SLAVE_YOUT_ADDR 0x3418 +#define IMX307_SLAVE_RHS1_ADDR 0x3030 +#define IMX307_SLAVE_TABLE_END 0xffff + +#define IMX307_SLAVE_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX307_SLAVE_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astImx307_Slave_mode[IMX307_SLAVE_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx307_Slave_mode[IMX307_SLAVE_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 45740; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astImx307_Slave_mode[IMX307_SLAVE_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx307_Slave_mode[IMX307_SLAVE_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 45740; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = IMX307_SLAVE_VMAX_1080P30_LINEAR; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case IMX307_SLAVE_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX307_SLAVE_FULL_LINES_MAX_2TO1_WDR) ? + IMX307_SLAVE_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case IMX307_SLAVE_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX307_SLAVE_FULL_LINES_MAX) ? IMX307_SLAVE_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } else { + pstSnsRegsInfo->astI2cData[DOL2_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx307_Slave_State[ViPipe].u32RHS1_MAX = + (u32VMAX - g_astImx307_Slave_State[ViPipe].u32BRL) * 2 - 21; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHS1 = 0; + CVI_U32 u32SHS2 = 0; + CVI_U32 u32YOUTSIZE; + CVI_U32 u16BRL = 0; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u16BRL = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].u16BRL; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[0] < u32LongIntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], u32LongIntTime - 1); + return CVI_FAILURE; + } + u32SHS2 = pstSnsState->au32FL[0] - u32LongIntTime - 1; + + u32SHS1 = (u32ShortIntTime % 2) + 2; + u32RHS1 = u32ShortIntTime + u32SHS1 + 1; + g_astImx307_Slave_State[ViPipe].u32RHS1 = u32RHS1; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - (u32SHS1 + 1); + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[0] - (u32SHS2 + 1); + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + u32YOUTSIZE = (u16BRL + (u32RHS1 - 1) / 2) * 2; + u32YOUTSIZE = (u32YOUTSIZE >= 0x1FFF) ? 0x1FFF : u32YOUTSIZE; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHS1 = %d\n", u32ShortIntTime, u32SHS1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d u32YOUTSIZE = %d\n", ViPipe, u32RHS1, u32YOUTSIZE); + + pstSnsRegsInfo->astI2cData[DOL2_SHS1_0].u32Data = (u32SHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_1].u32Data = ((u32SHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_2].u32Data = ((u32SHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHS2_0].u32Data = (u32SHS2 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_1].u32Data = ((u32SHS2 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_2].u32Data = ((u32SHS2 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_0].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_1].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_2].u32Data = ((u32RHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_0].u32Data = (u32YOUTSIZE & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_1].u32Data = ((u32YOUTSIZE & 0x1F00) >> 8); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if (pstSnsState->au32FL[0] < *u32IntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], *u32IntTime - 1); + return CVI_FAILURE; + } + u32Value = pstSnsState->au32FL[0] - *u32IntTime - 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2].u32Data = ((u32Value & 0x30000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 327567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32HCG = g_astImx307_Slave_State[ViPipe].u8Hcg; + CVI_U32 u16Mode = g_au16Imx307_Slave_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 20) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 20; + } + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = (u32HCG & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + CVI_U8 bEnableHCG = 0; + + if (pu32Again[0] >= 20 && pu32Again[1] >= 20) { + /* hcg bit[4]*/ + u32HCG |= 0x10; + bEnableHCG = 1; + } + + u32Again = pu32Again[1] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + + u32Again = pu32Again[0] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN1].u32Data = (u32Tmp & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 20) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 20; + } + + u32Tmp = u32Again + u32Dgain; + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 2 : 2; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 10; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx307_Slave_State[ViPipe].u32RHS1_MAX - 3)) ? + (g_astImx307_Slave_State[ViPipe].u32RHS1_MAX - 3) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} +#if 0 +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} +#endif +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX307_SLAVE_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx307_Slave_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX307_SLAVE_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = IMX307_SLAVE_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].u32VtsDef; + g_astImx307_Slave_State[ViPipe].u8Hcg = 0x2; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX307_SLAVE_MODE_1080P30) + pstSnsState->u8ImgMode = IMX307_SLAVE_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + g_astImx307_Slave_State[ViPipe].u8Hcg = 0x1; + if (pstSnsState->u8ImgMode == IMX307_SLAVE_MODE_1080P30_WDR) { + pstSnsState->u32FLStd = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx307_Slave_State[ViPipe].u32BRL = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1080p\n"); + } + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx307_Slave_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx307_slave_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx307_slave_addr_byte; + pstI2c_data[i].u32DataByteNum = imx307_slave_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_HOLD].u32RegAddr = IMX307_SLAVE_HOLD_ADDR; + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_SHS1_0].u32RegAddr = IMX307_SLAVE_SHS1_ADDR; + pstI2c_data[DOL2_SHS1_1].u32RegAddr = IMX307_SLAVE_SHS1_ADDR + 1; + pstI2c_data[DOL2_SHS1_2].u32RegAddr = IMX307_SLAVE_SHS1_ADDR + 2; + + pstI2c_data[DOL2_GAIN].u32RegAddr = IMX307_SLAVE_GAIN_ADDR; + pstI2c_data[DOL2_HCG].u32RegAddr = IMX307_SLAVE_HCG_ADDR; + pstI2c_data[DOL2_HCG].u8DelayFrmNum = 1; + pstI2c_data[DOL2_GAIN1].u32RegAddr = IMX307_SLAVE_GAIN1_ADDR; + pstI2c_data[DOL2_RHS1_0].u32RegAddr = IMX307_SLAVE_RHS1_ADDR; + pstI2c_data[DOL2_RHS1_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_1].u32RegAddr = IMX307_SLAVE_RHS1_ADDR + 1; + pstI2c_data[DOL2_RHS1_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_2].u32RegAddr = IMX307_SLAVE_RHS1_ADDR + 2; + pstI2c_data[DOL2_RHS1_2].u8DelayFrmNum = 1; + pstI2c_data[DOL2_SHS2_0].u32RegAddr = IMX307_SLAVE_SHS2_ADDR; + pstI2c_data[DOL2_SHS2_1].u32RegAddr = IMX307_SLAVE_SHS2_ADDR + 1; + pstI2c_data[DOL2_SHS2_2].u32RegAddr = IMX307_SLAVE_SHS2_ADDR + 2; + pstI2c_data[DOL2_VMAX_0].u32RegAddr = IMX307_SLAVE_VMAX_ADDR; + pstI2c_data[DOL2_VMAX_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_1].u32RegAddr = IMX307_SLAVE_VMAX_ADDR + 1; + pstI2c_data[DOL2_VMAX_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_2].u32RegAddr = IMX307_SLAVE_VMAX_ADDR + 2; + pstI2c_data[DOL2_VMAX_2].u8DelayFrmNum = 1; + + pstI2c_data[DOL2_YOUT_SIZE_0].u32RegAddr = IMX307_SLAVE_YOUT_ADDR; + pstI2c_data[DOL2_YOUT_SIZE_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u32RegAddr = IMX307_SLAVE_YOUT_ADDR + 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_REL].u32RegAddr = IMX307_SLAVE_HOLD_ADDR; + pstI2c_data[DOL2_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 1; + break; + default: + pstI2c_data[LINEAR_HOLD].u32RegAddr = IMX307_SLAVE_HOLD_ADDR; + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_SHS1_0].u32RegAddr = IMX307_SLAVE_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1].u32RegAddr = IMX307_SLAVE_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2].u32RegAddr = IMX307_SLAVE_SHS1_ADDR + 2; + pstI2c_data[LINEAR_GAIN].u32RegAddr = IMX307_SLAVE_GAIN_ADDR; + pstI2c_data[LINEAR_HCG].u32RegAddr = IMX307_SLAVE_HCG_ADDR; + pstI2c_data[LINEAR_HCG].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VMAX_0].u32RegAddr = IMX307_SLAVE_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1].u32RegAddr = IMX307_SLAVE_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_2].u32RegAddr = IMX307_SLAVE_VMAX_ADDR + 2; + pstI2c_data[LINEAR_REL].u32RegAddr = IMX307_SLAVE_HOLD_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[DOL2_REL].u32Data = 0; + pstI2c_data[DOL2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX307_SLAVE_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX307_SLAVE_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX307_SLAVE_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX307_SLAVE_MODE_1080P30_WDR; + g_astImx307_Slave_State[ViPipe].u32BRL = 1109; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx307_Slave_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx307_slave_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx307_Slave_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = IMX307_SLAVE_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = IMX307_SLAVE_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[0] = IMX307_SLAVE_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[1] = IMX307_SLAVE_VMAX_1080P30_LINEAR; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx307_slave_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx307_slave_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx307_slave_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx307_slave_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx307_slave_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx307_Slave_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX307_SLAVE_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX307_SLAVE_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + //AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX307_SLAVE_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } +#if 0 + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stSnsExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } +#endif + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX307_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX307_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } +#if 0 + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX307_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } +#endif + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx307_Slave_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Imx307_Slave_UseHwSync[ViPipe] = pstInitAttr->u16UseHwSync; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return imx307_slave_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsImx307_Slave_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx307_slave_standby, + .pfnRestart = imx307_slave_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx307_slave_write_register, + .pfnReadReg = imx307_slave_read_register, + .pfnSetBusInfo = imx307_slave_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx307_slave/imx307_slave_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_slave/imx307_slave_cmos_ex.h new file mode 100644 index 000000000..bfcc7b475 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_slave/imx307_slave_cmos_ex.h @@ -0,0 +1,125 @@ +#ifndef __IMX307_SLAVE_CMOS_EX_H_ +#define __IMX307_SLAVE_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +/* [TODO] ======== Temporarily definitions start ========*/ +typedef struct _AWB_SENSOR_DEFAULT_S { + CVI_U16 u16InitRgain; /*Init WB gain*/ + CVI_U16 u16InitGgain; + CVI_U16 u16InitBgain; + CVI_U8 u8AWBRunInterval; /*RW;AWB Run Interval*/ +} AWB_SENSOR_DEFAULT_S; + +/* [TODO] ======== Temporarily definitions end ========*/ +enum imx307_slave_linear_regs_e { + LINEAR_HOLD = 0, + LINEAR_SHS1_0, + LINEAR_SHS1_1, + LINEAR_SHS1_2, + LINEAR_GAIN, + LINEAR_HCG, + LINEAR_VMAX_0, + LINEAR_VMAX_1, + LINEAR_VMAX_2, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum imx307_slave_dol2_regs_e { + DOL2_HOLD = 0, + DOL2_SHS1_0, + DOL2_SHS1_1, + DOL2_SHS1_2, + DOL2_GAIN, + DOL2_HCG, + DOL2_GAIN1, + DOL2_RHS1_0, + DOL2_RHS1_1, + DOL2_RHS1_2, + DOL2_SHS2_0, + DOL2_SHS2_1, + DOL2_SHS2_2, + DOL2_VMAX_0, + DOL2_VMAX_1, + DOL2_VMAX_2, + DOL2_YOUT_SIZE_0, + DOL2_YOUT_SIZE_1, + DOL2_REL, + DOL2_REGS_NUM +}; + +typedef enum _IMX307_SLAVE_MODE_E { + IMX307_SLAVE_MODE_1080P30 = 0, + IMX307_SLAVE_MODE_LINEAR_NUM, + IMX307_SLAVE_MODE_1080P30_WDR = IMX307_SLAVE_MODE_LINEAR_NUM, + IMX307_SLAVE_MODE_NUM +} IMX307_SLAVE_MODE_E; + +typedef struct _IMX307_SLAVE_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX307_SLAVE_STATE_S; + +typedef struct _IMX307_SLAVE_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX307_SLAVE_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx307_Slave[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx307_Slave_BusInfo[]; +extern CVI_U16 g_au16Imx307_Slave_UseHwSync[]; +extern CVI_U16 g_au16Imx307_Slave_GainMode[]; +extern const CVI_U8 imx307_slave_i2c_addr; +extern const CVI_U32 imx307_slave_addr_byte; +extern const CVI_U32 imx307_slave_data_byte; +extern void imx307_slave_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void imx307_slave_init(VI_PIPE ViPipe); +extern void imx307_slave_exit(VI_PIPE ViPipe); +extern void imx307_slave_standby(VI_PIPE ViPipe); +extern void imx307_slave_restart(VI_PIPE ViPipe); +extern int imx307_slave_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx307_slave_read_register(VI_PIPE ViPipe, int addr); +extern int imx307_slave_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX307_SLAVE_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx307_slave/imx307_slave_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_slave/imx307_slave_cmos_param.h new file mode 100644 index 000000000..558cdd93c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_slave/imx307_slave_cmos_param.h @@ -0,0 +1,307 @@ +#ifndef __IMX307_SLAVE_CMOS_PARAM_H_ +#define __IMX307_SLAVE_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx307_slave_cmos_ex.h" + +static const IMX307_SLAVE_MODE_S g_astImx307_Slave_mode[IMX307_SLAVE_MODE_NUM] = { + [IMX307_SLAVE_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x1130, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX307_SLAVE_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 8, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 2236, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.03396590426564216614, 2.31280159950256347656}, //B: slope, intercept + {0.02877708896994590759, 1.99502599239349365234}, //Gb: slope, intercept + {0.02853375114500522614, 1.53825533390045166016}, //Gr: slope, intercept + {0.02940983884036540985, 2.40369534492492675781}, //R: slope, intercept + }, + { //iso 200 + {0.03635194525122642517, 5.70069074630737304688}, //B: slope, intercept + {0.02990435808897018433, 6.70210981369018554688}, //Gb: slope, intercept + {0.03183263540267944336, 4.92136955261230468750}, //Gr: slope, intercept + {0.03145531564950942993, 5.97894525527954101563}, //R: slope, intercept + }, + { //iso 400 + {0.04329251870512962341, 7.09708356857299804688}, //B: slope, intercept + {0.03147880360484123230, 11.36076831817626953125}, //Gb: slope, intercept + {0.03299136087298393250, 8.49763488769531250000}, //Gr: slope, intercept + {0.03585162013769149780, 8.31188583374023437500}, //R: slope, intercept + }, + { //iso 800 + {0.05740678682923316956, 10.93907737731933593750}, //B: slope, intercept + {0.03538244962692260742, 21.53132820129394531250}, //Gb: slope, intercept + {0.04014955088496208191, 14.56391811370849609375}, //Gr: slope, intercept + {0.03907874971628189087, 15.16305541992187500000}, //R: slope, intercept + }, + { //iso 1600 + {0.05417122691869735718, 23.33716773986816406250}, //B: slope, intercept + {0.02816017158329486847, 55.33533859252929687500}, //Gb: slope, intercept + {0.03809726238250732422, 30.80285072326660156250}, //Gr: slope, intercept + {0.04028835147619247437, 31.24934768676757812500}, //R: slope, intercept + }, + { //iso 3200 + {0.07438381761312484741, 33.81318664550781250000}, //B: slope, intercept + {0.02690842747688293457, 95.65101623535156250000}, //Gb: slope, intercept + {0.05132644250988960266, 46.27661132812500000000}, //Gr: slope, intercept + {0.05343631654977798462, 44.67097473144531250000}, //R: slope, intercept + }, + { //iso 6400 + {0.10831451416015625000, 49.42535018920898437500}, //B: slope, intercept + {0.04577258601784706116, 122.51580810546875000000}, //Gb: slope, intercept + {0.06677398085594177246, 69.54801177978515625000}, //Gr: slope, intercept + {0.07670628279447555542, 63.47140884399414062500}, //R: slope, intercept + }, + { //iso 12800 + {0.15062870085239410400, 68.36373138427734375000}, //B: slope, intercept + {0.07762257009744644165, 146.30807495117187500000}, //Gb: slope, intercept + {0.09608269482851028442, 96.59751892089843750000}, //Gr: slope, intercept + {0.10346080362796783447, 96.64923095703125000000}, //R: slope, intercept + }, + { //iso 25600 + {0.21278673410415649414, 107.37140655517578125000}, //B: slope, intercept + {0.12505164742469787598, 179.24717712402343750000}, //Gb: slope, intercept + {0.14927712082862854004, 140.71289062500000000000}, //Gr: slope, intercept + {0.15530782938003540039, 139.79985046386718750000}, //R: slope, intercept + }, + { //iso 51200 + {0.32940942049026489258, 149.26779174804687500000}, //B: slope, intercept + {0.18958723545074462891, 247.18806457519531250000}, //Gb: slope, intercept + {0.19027391076087951660, 230.56108093261718750000}, //Gr: slope, intercept + {0.23455394804477691650, 192.10685729980468750000}, //R: slope, intercept + }, + { //iso 102400 + {0.48793542385101318359, 210.41285705566406250000}, //B: slope, intercept + {0.24973315000534057617, 372.87121582031250000000}, //Gb: slope, intercept + {0.23015110194683074951, 402.12283325195312500000}, //Gr: slope, intercept + {0.35159105062484741211, 294.27154541015625000000}, //R: slope, intercept + }, + { //iso 204800 + {0.60629695653915405273, 340.77212524414062500000}, //B: slope, intercept + {0.39248645305633544922, 481.49472045898437500000}, //Gb: slope, intercept + {0.33751612901687622070, 544.22698974609375000000}, //Gr: slope, intercept + {0.43583938479423522949, 458.90490722656250000000}, //R: slope, intercept + }, + { //iso 409600 + {0.71151763200759887695, 544.37280273437500000000}, //B: slope, intercept + {0.47628879547119140625, 697.04498291015625000000}, //Gb: slope, intercept + {0.38568580150604248047, 794.64263916015625000000}, //Gr: slope, intercept + {0.54425776004791259766, 658.77343750000000000000}, //R: slope, intercept + }, + { //iso 819200 + {0.61085152626037597656, 821.67352294921875000000}, //B: slope, intercept + {0.38012877106666564941, 1050.61950683593750000000}, //Gb: slope, intercept + {0.38677954673767089844, 1049.79968261718750000000}, //Gr: slope, intercept + {0.54386067390441894531, 875.86968994140625000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.88969016075134277344, 635.22283935546875000000}, //B: slope, intercept + {0.71133875846862792969, 754.16796875000000000000}, //Gb: slope, intercept + {0.66038286685943603516, 765.11163330078125000000}, //Gr: slope, intercept + {0.61520493030548095703, 817.94128417968750000000}, //R: slope, intercept + }, + { //iso 3276800 + {1.43259191513061523438, 263.03683471679687500000}, //B: slope, intercept + {0.87281060218811035156, 624.04595947265625000000}, //Gb: slope, intercept + {0.81407910585403442383, 666.59527587890625000000}, //Gr: slope, intercept + {0.87593811750411987305, 608.70275878906250000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {239, 239, 239, 239, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1087, 1087, 1087, 1087 +#endif + }, + .stAuto = { + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/243, 252, 290, 395, 681, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1228, 1365, 1365, 1365}, +#endif + }, + }, +}; + +struct combo_dev_attr_s imx307_slave_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {4, 3, 5, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_DOL, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 1, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX307_SLAVE_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx307_slave/imx307_slave_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_slave/imx307_slave_sensor_ctl.c new file mode 100644 index 000000000..d925384c7 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx307_slave/imx307_slave_sensor_ctl.c @@ -0,0 +1,420 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx307_slave_cmos_ex.h" + +static void imx307_slave_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void imx307_slave_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 imx307_slave_i2c_addr = 0x1A; +const CVI_U32 imx307_slave_addr_byte = 2; +const CVI_U32 imx307_slave_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx307_slave_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx307_Slave_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx307_slave_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int imx307_slave_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx307_slave_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (imx307_slave_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, imx307_slave_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, imx307_slave_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (imx307_slave_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int imx307_slave_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx307_slave_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx307_slave_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx307_slave_addr_byte + imx307_slave_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx307_slave_standby(VI_PIPE ViPipe) +{ + imx307_slave_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ +} + +void imx307_slave_restart(VI_PIPE ViPipe) +{ + imx307_slave_write_register(ViPipe, 0x3000, 0x00); /* standby */ +} + +void imx307_slave_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx307_Slave[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx307_slave_write_register(ViPipe, + g_pastImx307_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx307_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define IMX307_CHIP_ID_ADDR 0x31dc +#define IMX307_CHIP_ID 0x4 +#define IMX307_CHIP_ID_MASK 0x6 + +void imx307_slave_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = imx307_slave_read_register(ViPipe, 0x3007) & ~0x3; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + imx307_slave_write_register(ViPipe, 0x3007, val); +} + +int imx307_slave_probe(VI_PIPE ViPipe) +{ + int nVal; + + usleep(100); + if (imx307_slave_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = imx307_slave_read_register(ViPipe, IMX307_CHIP_ID_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((nVal & IMX307_CHIP_ID_MASK) != IMX307_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void imx307_slave_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastImx307_Slave[ViPipe]->enWDRMode; + u8ImgMode = g_pastImx307_Slave[ViPipe]->u8ImgMode; + + imx307_slave_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == IMX307_SLAVE_MODE_1080P30_WDR) { + imx307_slave_wdr_1080p30_2to1_init(ViPipe); + } + } else { + imx307_slave_linear_1080p30_init(ViPipe); + } + g_pastImx307_Slave[ViPipe]->bInit = CVI_TRUE; +} + +void imx307_slave_exit(VI_PIPE ViPipe) +{ + imx307_slave_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void imx307_slave_linear_1080p30_init(VI_PIPE ViPipe) +{ + imx307_slave_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx307_slave_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx307_slave_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx307_slave_write_register(ViPipe, 0x3005, 0x01); /* ADBIT 10bit*/ + imx307_slave_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx307_slave_write_register(ViPipe, 0x3009, 0x02); /**/ + imx307_slave_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx307_slave_write_register(ViPipe, 0x3011, 0x0A); + imx307_slave_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx307_slave_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx307_slave_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx307_slave_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx307_slave_write_register(ViPipe, 0x301C, 0x30); /* HMAX[7:0], TBD*/ + imx307_slave_write_register(ViPipe, 0x301D, 0x11); /* HMAX[15:8]*/ + imx307_slave_write_register(ViPipe, 0x3020, 0x8C); /* SHS[7:0], TBD*/ + imx307_slave_write_register(ViPipe, 0x3021, 0x01); /* SHS[15:8]*/ + imx307_slave_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx307_slave_write_register(ViPipe, 0x3046, 0x01); + imx307_slave_write_register(ViPipe, 0x304B, 0x00); + imx307_slave_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx307_slave_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx307_slave_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx307_slave_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx307_slave_write_register(ViPipe, 0x309E, 0x4A); + imx307_slave_write_register(ViPipe, 0x309F, 0x4A); + imx307_slave_write_register(ViPipe, 0x311C, 0x0E); + imx307_slave_write_register(ViPipe, 0x3128, 0x04); + imx307_slave_write_register(ViPipe, 0x3129, 0x00); + imx307_slave_write_register(ViPipe, 0x313B, 0x41); + imx307_slave_write_register(ViPipe, 0x315E, 0x1A); + imx307_slave_write_register(ViPipe, 0x3164, 0x1A); + imx307_slave_write_register(ViPipe, 0x317C, 0x00); + imx307_slave_write_register(ViPipe, 0x31EC, 0x0E); + imx307_slave_write_register(ViPipe, 0x3405, 0x10); /* Repetition*/ + imx307_slave_write_register(ViPipe, 0x3407, 0x01); /* physical_lane_nl*/ + imx307_slave_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx307_slave_write_register(ViPipe, 0x3418, 0x49); /* y_out_size*/ + imx307_slave_write_register(ViPipe, 0x3419, 0x04); /* y_out_size*/ + imx307_slave_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx307_slave_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx307_slave_write_register(ViPipe, 0x3443, 0x01); /* csi_lane_mode*/ + imx307_slave_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx307_slave_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx307_slave_write_register(ViPipe, 0x3446, 0x57); /* tclkpost*/ + imx307_slave_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + //imx307_slave_write_register(ViPipe, 0x3448, 0x37); /* thszero*/ + imx307_slave_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx307_slave_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx307_slave_write_register(ViPipe, 0x344A, 0x1F); /* thsprepare*/ + imx307_slave_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx307_slave_write_register(ViPipe, 0x344C, 0x1F); /* tclktrail*/ + imx307_slave_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + //imx307_slave_write_register(ViPipe, 0x344E, 0x1F); /* thstrail*/ + imx307_slave_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx307_slave_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx307_slave_write_register(ViPipe, 0x3450, 0x77); /* tclkzero*/ + imx307_slave_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx307_slave_write_register(ViPipe, 0x3452, 0x1F); /* tclkprepare*/ + imx307_slave_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx307_slave_write_register(ViPipe, 0x3454, 0x17); /* tlpx*/ + imx307_slave_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx307_slave_write_register(ViPipe, 0x3472, 0x9C); /* x_out_size*/ + imx307_slave_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx307_slave_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx307_slave_default_reg_init(ViPipe); + + imx307_slave_write_register(ViPipe, 0x3000, 0x00); /* standby */ + + if (!g_au16Imx307_Slave_UseHwSync[ViPipe]) { + delay_ms(20); + imx307_slave_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx307_slave_write_register(ViPipe, 0x304b, 0x0a); + } + + printf("ViPipe:%d,===IMX307 1080P 30fps 12bit LINE Slave Init OK!===\n", ViPipe); +} + +static void imx307_slave_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + imx307_slave_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx307_slave_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx307_slave_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx307_slave_write_register(ViPipe, 0x3005, 0x01); /* ADBIT*/ + imx307_slave_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx307_slave_write_register(ViPipe, 0x3009, 0x01); /**/ + imx307_slave_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx307_slave_write_register(ViPipe, 0x300C, 0x11); /* WDMODE [0] 0:Normal, 1:DOL, WDSEL [5:4] 1:DOL 2 frames*/ + imx307_slave_write_register(ViPipe, 0x3011, 0x0A); + imx307_slave_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx307_slave_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx307_slave_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx307_slave_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx307_slave_write_register(ViPipe, 0x301C, 0x98); /* HMAX[7:0], TBD*/ + imx307_slave_write_register(ViPipe, 0x301D, 0x08); /* HMAX[15:8]*/ + imx307_slave_write_register(ViPipe, 0x3020, 0x02); /* SHS[7:0], TBD*/ + imx307_slave_write_register(ViPipe, 0x3021, 0x00); /* SHS[15:8]*/ + imx307_slave_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx307_slave_write_register(ViPipe, 0x3024, 0xC9); /* SHS2[7:0], TBD*/ + imx307_slave_write_register(ViPipe, 0x3025, 0x07); /* SHS2[15:8]*/ + imx307_slave_write_register(ViPipe, 0x3026, 0x00); /* SHS2[19:16]*/ + imx307_slave_write_register(ViPipe, 0x3030, 0x0B); /* RHS1[7:0], TBD*/ + imx307_slave_write_register(ViPipe, 0x3031, 0x00); /* RHS1[15:8]*/ + imx307_slave_write_register(ViPipe, 0x3032, 0x00); /* RHS1[19:16]*/ + imx307_slave_write_register(ViPipe, 0x3045, 0x05); /* DOLSCDEN [0] 1: pattern1 0: pattern2*/ + imx307_slave_write_register(ViPipe, 0x3046, 0x01); + imx307_slave_write_register(ViPipe, 0x304B, 0x00); + imx307_slave_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx307_slave_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx307_slave_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx307_slave_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx307_slave_write_register(ViPipe, 0x309E, 0x4A); + imx307_slave_write_register(ViPipe, 0x309F, 0x4A); + imx307_slave_write_register(ViPipe, 0x3106, 0x11); /*DOLHBFIXEN[7] 0: pattern1 1: pattern2*/ + imx307_slave_write_register(ViPipe, 0x311C, 0x0E); + imx307_slave_write_register(ViPipe, 0x3128, 0x04); + imx307_slave_write_register(ViPipe, 0x3129, 0x00); + imx307_slave_write_register(ViPipe, 0x313B, 0x41); + imx307_slave_write_register(ViPipe, 0x315E, 0x1A); + imx307_slave_write_register(ViPipe, 0x3164, 0x1A); + imx307_slave_write_register(ViPipe, 0x317C, 0x00); + imx307_slave_write_register(ViPipe, 0x31EC, 0x0E); + imx307_slave_write_register(ViPipe, 0x3405, 0x00); /* Repetition*/ + imx307_slave_write_register(ViPipe, 0x3407, 0x01); /* physical_lane_nl*/ + imx307_slave_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx307_slave_write_register(ViPipe, 0x3415, 0x00); /* NULL0_SIZE_V, set to 00h when DOL*/ + imx307_slave_write_register(ViPipe, 0x3418, 0xB4); /* y_out_size*/ + imx307_slave_write_register(ViPipe, 0x3419, 0x08); /* y_out_size*/ + imx307_slave_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx307_slave_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx307_slave_write_register(ViPipe, 0x3443, 0x01); /* csi_lane_mode*/ + imx307_slave_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx307_slave_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx307_slave_write_register(ViPipe, 0x3446, 0x77); /* tclkpost*/ + imx307_slave_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx307_slave_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx307_slave_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx307_slave_write_register(ViPipe, 0x344A, 0x47); /* thsprepare*/ + imx307_slave_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx307_slave_write_register(ViPipe, 0x344C, 0x37); /* tclktrail*/ + imx307_slave_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx307_slave_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx307_slave_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx307_slave_write_register(ViPipe, 0x3450, 0xFF); /* tclkzero*/ + imx307_slave_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx307_slave_write_register(ViPipe, 0x3452, 0x3F); /* tclkprepare*/ + imx307_slave_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx307_slave_write_register(ViPipe, 0x3454, 0x37); /* tlpx*/ + imx307_slave_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx307_slave_write_register(ViPipe, 0x3472, 0xA0); /* x_out_size*/ + imx307_slave_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx307_slave_write_register(ViPipe, 0x347B, 0x23); /**/ + imx307_slave_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx307_slave_default_reg_init(ViPipe); + + if (g_au16Imx307_Slave_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + imx307_slave_write_register(ViPipe, 0x30F0, 0xF0); + imx307_slave_write_register(ViPipe, 0x3010, 0x21); + } else { + imx307_slave_write_register(ViPipe, 0x30F0, 0x64); + imx307_slave_write_register(ViPipe, 0x3010, 0x61); + } + + imx307_slave_write_register(ViPipe, 0x3000, 0x00); /* standby */ + + if (!g_au16Imx307_Slave_UseHwSync[ViPipe]) { + delay_ms(20); + imx307_slave_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx307_slave_write_register(ViPipe, 0x304b, 0x0a); + } else + imx307_slave_write_register(ViPipe, 0x3106, 0x40); /* XVS/XHS sub-sampling */ + + printf("===Imx307 sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) Slave init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327/Makefile b/middleware/v2/component/isp/sensor/cv180x/sony_imx327/Makefile new file mode 100644 index 000000000..c0d94bc4a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx327.a +TARGET_SO = $(MW_LIB)/libsns_imx327.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327/imx327_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx327/imx327_cmos.c new file mode 100644 index 000000000..adf621d8e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327/imx327_cmos.c @@ -0,0 +1,1206 @@ +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "imx327_cmos_ex.h" +#include "imx327_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX327_ID 327 +#define SENSOR_IMX327_WIDTH 1920 +#define SENSOR_IMX327_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx327[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX327_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx327[dev]) +#define IMX327_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx327[dev] = pstCtx) +#define IMX327_SENSOR_RESET_CTX(dev) (g_pastImx327[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunImx327_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx327_GainMode[VI_MAX_PIPE_NUM] = {0}; + +IMX327_STATE_S g_astImx327_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx327_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx327 Lines Range*****/ +#define IMX327_FULL_LINES_MAX (0x3FFFF) +#define IMX327_FULL_LINES_MAX_2TO1_WDR (0x3FFFF) // considering the YOUT_SIZE and bad frame +#define IMX327_VMAX_1080P30_LINEAR 1125 + +/*****Imx327 Register Address*****/ +#define IMX327_HOLD_ADDR 0x3001 +#define IMX327_SHS1_ADDR 0x3020 +#define IMX327_SHS2_ADDR 0x3024 +#define IMX327_GAIN_ADDR 0x3014 +#define IMX327_GAIN1_ADDR 0x30F2 +#define IMX327_HCG_ADDR 0x3009 +#define IMX327_VMAX_ADDR 0x3018 +#define IMX327_YOUT_ADDR 0x3418 +#define IMX327_RHS1_ADDR 0x3030 +#define IMX327_TABLE_END 0xffff + +#define IMX327_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 fps = 30; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + if (pstSnsState->u8ImgMode == IMX327_MODE_1080P60) + fps = 60; + +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX327_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * fps); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * fps / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + if (pstSnsState->u8ImgMode == IMX327_MODE_1080P60) { + pstAeSnsDft->f32Fps = g_astImx327_mode[IMX327_MODE_1080P60].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_mode[IMX327_MODE_1080P60].f32MinFps; + } else { + pstAeSnsDft->f32Fps = g_astImx327_mode[IMX327_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_mode[IMX327_MODE_1080P30].f32MinFps; + } + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astImx327_mode[IMX327_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_mode[IMX327_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = IMX327_VMAX_1080P30_LINEAR; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astImx327_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx327_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx327_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case IMX327_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_FULL_LINES_MAX_2TO1_WDR) ? IMX327_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case IMX327_MODE_1080P30: + case IMX327_MODE_1080P60: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_FULL_LINES_MAX) ? IMX327_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } else { + pstSnsRegsInfo->astI2cData[DOL2_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx327_State[ViPipe].u32RHS1_MAX = (u32VMAX - g_astImx327_State[ViPipe].u32BRL) * 2 - 21; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHS1 = 0; + CVI_U32 u32SHS2 = 0; + CVI_U32 u32YOUTSIZE; + CVI_U32 u16BRL = 0; + + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u16BRL = g_astImx327_mode[pstSnsState->u8ImgMode].u16BRL; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[0] < u32LongIntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], u32LongIntTime - 1); + return CVI_FAILURE; + } + u32SHS2 = pstSnsState->au32FL[0] - u32LongIntTime - 1; + + u32SHS1 = (u32ShortIntTime % 2) + 2; + u32RHS1 = u32ShortIntTime + u32SHS1 + 1; + g_astImx327_State[ViPipe].u32RHS1 = u32RHS1; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - (u32SHS1 + 1); + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[0] - (u32SHS2 + 1); + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + u32YOUTSIZE = (u16BRL + (u32RHS1 - 1) / 2) * 2; + u32YOUTSIZE = (u32YOUTSIZE >= 0x1FFF) ? 0x1FFF : u32YOUTSIZE; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHS1 = %d\n", u32ShortIntTime, u32SHS1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d u32YOUTSIZE = %d\n", ViPipe, u32RHS1, u32YOUTSIZE); + + pstSnsRegsInfo->astI2cData[DOL2_SHS1_0].u32Data = (u32SHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_1].u32Data = ((u32SHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_2].u32Data = ((u32SHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHS2_0].u32Data = (u32SHS2 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_1].u32Data = ((u32SHS2 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_2].u32Data = ((u32SHS2 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_0].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_1].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_2].u32Data = ((u32RHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_0].u32Data = (u32YOUTSIZE & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_1].u32Data = ((u32YOUTSIZE & 0x1F00) >> 8); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if (pstSnsState->au32FL[0] < *u32IntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], *u32IntTime - 1); + return CVI_FAILURE; + } + u32Value = pstSnsState->au32FL[0] - *u32IntTime - 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2].u32Data = ((u32Value & 0x30000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 327567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32HCG = g_astImx327_State[ViPipe].u8Hcg; + CVI_U32 u16Mode = g_au16Imx327_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = (u32HCG & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + CVI_U8 bEnableHCG = 0; + + if (pu32Again[0] >= 20 && pu32Again[1] >= 20) { + /* hcg bit[4]*/ + u32HCG |= 0x10; + bEnableHCG = 1; + } + + u32Again = pu32Again[1] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + + u32Again = pu32Again[0] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN1].u32Data = (u32Tmp & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + if (u32HCG > 0xFF) { + u32HCG = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 2 : 2; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 10; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx327_State[ViPipe].u32RHS1_MAX - 3)) ? + (g_astImx327_State[ViPipe].u32RHS1_MAX - 3) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX327_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx327_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX327_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = IMX327_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx327_mode[pstSnsState->u8ImgMode].u32VtsDef; + if (pstSnsState->u8ImgMode == IMX327_MODE_1080P60) + g_astImx327_State[ViPipe].u8Hcg = 0x1; + else + g_astImx327_State[ViPipe].u8Hcg = 0x2; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX327_MODE_1080P30) + pstSnsState->u8ImgMode = IMX327_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + g_astImx327_State[ViPipe].u8Hcg = 0x1; + if (pstSnsState->u8ImgMode == IMX327_MODE_1080P30_WDR) { + pstSnsState->u32FLStd = g_astImx327_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx327_State[ViPipe].u32BRL = g_astImx327_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1080p\n"); + } + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx327_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 2; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx327_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx327_addr_byte; + pstI2c_data[i].u32DataByteNum = imx327_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_HOLD].u32RegAddr = IMX327_HOLD_ADDR; + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_SHS1_0].u32RegAddr = IMX327_SHS1_ADDR; + pstI2c_data[DOL2_SHS1_1].u32RegAddr = IMX327_SHS1_ADDR + 1; + pstI2c_data[DOL2_SHS1_2].u32RegAddr = IMX327_SHS1_ADDR + 2; + + pstI2c_data[DOL2_GAIN].u32RegAddr = IMX327_GAIN_ADDR; + pstI2c_data[DOL2_HCG].u32RegAddr = IMX327_HCG_ADDR; + pstI2c_data[DOL2_HCG].u8DelayFrmNum = 1; + pstI2c_data[DOL2_GAIN1].u32RegAddr = IMX327_GAIN1_ADDR; + pstI2c_data[DOL2_RHS1_0].u32RegAddr = IMX327_RHS1_ADDR; + pstI2c_data[DOL2_RHS1_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_1].u32RegAddr = IMX327_RHS1_ADDR + 1; + pstI2c_data[DOL2_RHS1_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_2].u32RegAddr = IMX327_RHS1_ADDR + 2; + pstI2c_data[DOL2_RHS1_2].u8DelayFrmNum = 1; + pstI2c_data[DOL2_SHS2_0].u32RegAddr = IMX327_SHS2_ADDR; + pstI2c_data[DOL2_SHS2_1].u32RegAddr = IMX327_SHS2_ADDR + 1; + pstI2c_data[DOL2_SHS2_2].u32RegAddr = IMX327_SHS2_ADDR + 2; + pstI2c_data[DOL2_VMAX_0].u32RegAddr = IMX327_VMAX_ADDR; + pstI2c_data[DOL2_VMAX_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_1].u32RegAddr = IMX327_VMAX_ADDR + 1; + pstI2c_data[DOL2_VMAX_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_2].u32RegAddr = IMX327_VMAX_ADDR + 2; + pstI2c_data[DOL2_VMAX_2].u8DelayFrmNum = 1; + + pstI2c_data[DOL2_YOUT_SIZE_0].u32RegAddr = IMX327_YOUT_ADDR; + pstI2c_data[DOL2_YOUT_SIZE_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u32RegAddr = IMX327_YOUT_ADDR + 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_REL].u32RegAddr = IMX327_HOLD_ADDR; + pstI2c_data[DOL2_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 1; + break; + default: + pstI2c_data[LINEAR_HOLD].u32RegAddr = IMX327_HOLD_ADDR; + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_SHS1_0].u32RegAddr = IMX327_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1].u32RegAddr = IMX327_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2].u32RegAddr = IMX327_SHS1_ADDR + 2; + pstI2c_data[LINEAR_GAIN].u32RegAddr = IMX327_GAIN_ADDR; + pstI2c_data[LINEAR_HCG].u32RegAddr = IMX327_HCG_ADDR; + pstI2c_data[LINEAR_HCG].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VMAX_0].u32RegAddr = IMX327_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1].u32RegAddr = IMX327_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_2].u32RegAddr = IMX327_VMAX_ADDR + 2; + pstI2c_data[LINEAR_REL].u32RegAddr = IMX327_HOLD_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[DOL2_REL].u32Data = 0; + pstI2c_data[DOL2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX327_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX327_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_MODE_1080P30_WDR; + g_astImx327_State[ViPipe].u32BRL = 1109; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSensorImageMode->f32Fps <= 60) { + u8SensorImageMode = IMX327_MODE_1080P60; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx327_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx327_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx327_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = IMX327_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = IMX327_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[0] = IMX327_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[1] = IMX327_VMAX_1080P30_LINEAR; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx327_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx327_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx327_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx327_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx327_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx327_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx327_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx327_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX327_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX327_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX327_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX327_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX327_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX327_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx327_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return imx327_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsImx327_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx327_standby, + .pfnRestart = imx327_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx327_write_register, + .pfnReadReg = imx327_read_register, + .pfnSetBusInfo = imx327_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327/imx327_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx327/imx327_cmos_ex.h new file mode 100644 index 000000000..22f02af1e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327/imx327_cmos_ex.h @@ -0,0 +1,117 @@ +#ifndef __IMX327_CMOS_EX_H_ +#define __IMX327_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum imx327_linear_regs_e { + LINEAR_HOLD = 0, + LINEAR_SHS1_0, + LINEAR_SHS1_1, + LINEAR_SHS1_2, + LINEAR_GAIN, + LINEAR_HCG, + LINEAR_VMAX_0, + LINEAR_VMAX_1, + LINEAR_VMAX_2, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum imx327_dol2_regs_e { + DOL2_HOLD = 0, + DOL2_SHS1_0, + DOL2_SHS1_1, + DOL2_SHS1_2, + DOL2_GAIN, + DOL2_HCG, + DOL2_GAIN1, + DOL2_RHS1_0, + DOL2_RHS1_1, + DOL2_RHS1_2, + DOL2_SHS2_0, + DOL2_SHS2_1, + DOL2_SHS2_2, + DOL2_VMAX_0, + DOL2_VMAX_1, + DOL2_VMAX_2, + DOL2_YOUT_SIZE_0, + DOL2_YOUT_SIZE_1, + DOL2_REL, + DOL2_REGS_NUM +}; + +typedef enum _IMX327_MODE_E { + IMX327_MODE_1080P30 = 0, + IMX327_MODE_1080P60, + IMX327_MODE_LINEAR_NUM, + IMX327_MODE_1080P30_WDR = IMX327_MODE_LINEAR_NUM, + IMX327_MODE_NUM +} IMX327_MODE_E; + +typedef struct _IMX327_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX327_STATE_S; + +typedef struct _IMX327_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX327_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx327[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx327_BusInfo[]; +extern CVI_U16 g_au16Imx327_GainMode[]; +extern const CVI_U8 imx327_i2c_addr; +extern const CVI_U32 imx327_addr_byte; +extern const CVI_U32 imx327_data_byte; +extern void imx327_init(VI_PIPE ViPipe); +extern void imx327_exit(VI_PIPE ViPipe); +extern void imx327_standby(VI_PIPE ViPipe); +extern void imx327_restart(VI_PIPE ViPipe); +extern int imx327_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx327_read_register(VI_PIPE ViPipe, int addr); +extern void imx327_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int imx327_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327/imx327_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx327/imx327_cmos_param.h new file mode 100644 index 000000000..30ca7f88b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327/imx327_cmos_param.h @@ -0,0 +1,465 @@ +#ifndef __IMX327_CMOS_PARAM_H_ +#define __IMX327_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_cmos_ex.h" + +static const IMX327_MODE_S g_astImx327_mode[IMX327_MODE_NUM] = { + [IMX327_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x1130, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX327_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 8, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 2236, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 7, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX327_MODE_1080P60] = { + .name = "1080p60", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 60, + .f32MinFps = 0.26, /* 1125 * 60 / 0x3FFFF */ + .u32HtsDef = 0x898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, +}; + +// F1.8 Lens +#ifdef F18 +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = { + /*************Calibration LUT Table*************/ + .CalibrationCoef = { + { //iso 100 + {0.03243722766637802, 3.855583906173706}, //B: slope, intercept + {0.024103811010718346, 3.9538209438323975}, //Gb: slope, intercept + {0.022307759150862694, 4.970882892608643}, //Gr: slope, intercept + {0.02794046327471733, 3.1342978477478027}, //R: slope, intercept + }, + { //iso 200 + {0.03799639642238617, 5.526010990142822}, //B: slope, intercept + {0.02662081830203533, 7.61380672454834}, //Gb: slope, intercept + {0.025447502732276917, 8.231551170349121}, //Gr: slope, intercept + {0.032776281237602234, 5.149646282196045}, //R: slope, intercept + }, + { //iso 400 + {0.050715841352939606, 7.763713836669922}, //B: slope, intercept + {0.032093651592731476, 12.182195663452148}, //Gb: slope, intercept + {0.030688125640153885, 12.43420696258545}, //Gr: slope, intercept + {0.040235333144664764, 8.544824600219727}, //R: slope, intercept + }, + { //iso 800 + {0.06888508796691895, 10.970534324645996}, //B: slope, intercept + {0.03813415393233299, 19.28471565246582}, //Gb: slope, intercept + {0.03805641457438469, 19.625152587890625}, //Gr: slope, intercept + {0.04966627061367035, 12.69924545288086}, //R: slope, intercept + }, + { //iso 1600 + {0.08884920179843903, 15.890214920043945}, //B: slope, intercept + {0.046779610216617584, 30.772066116333008}, //Gb: slope, intercept + {0.045214589685201645, 31.489530563354492}, //Gr: slope, intercept + {0.06512749195098877, 20.34792137145996}, //R: slope, intercept + }, + { //iso 3200 + {0.1241341084241867, 20.70075225830078}, //B: slope, intercept + {0.05977431312203407, 45.98811721801758}, //Gb: slope, intercept + {0.05858884006738663, 47.11114501953125}, //Gr: slope, intercept + {0.08636551350355148, 30.561227798461914}, //R: slope, intercept + }, + { //iso 6400 + {0.1791478991508484, 30.803356170654297}, //B: slope, intercept + {0.09205856174230576, 65.60118103027344}, //Gb: slope, intercept + {0.08692053705453873, 69.85540771484375}, //Gr: slope, intercept + {0.12406758964061737, 45.617835998535156}, //R: slope, intercept + }, + { //iso 12800 + {0.2464703917503357, 44.136966705322266}, //B: slope, intercept + {0.11594483256340027, 97.8382797241211}, //Gb: slope, intercept + {0.11075824499130249, 101.47943115234375}, //Gr: slope, intercept + {0.17024046182632446, 66.47021484375}, //R: slope, intercept + }, + { //iso 25600 + {0.3376912772655487, 68.80254364013672}, //B: slope, intercept + {0.15025299787521362, 145.10032653808594}, //Gb: slope, intercept + {0.14386454224586487, 148.1698455810547}, //Gr: slope, intercept + {0.23965470492839813, 96.42337036132812}, //R: slope, intercept + }, + { //iso 51200 + {0.4279725253582001, 117.4070816040039}, //B: slope, intercept + {0.17134547233581543, 243.6494598388672}, //Gb: slope, intercept + {0.16668814420700073, 241.21603393554688}, //Gr: slope, intercept + {0.29862311482429504, 156.05364990234375}, //R: slope, intercept + }, + { //iso 102400 + {0.534967303276062, 181.45118713378906}, //B: slope, intercept + {0.2024478018283844, 365.00177001953125}, //Gb: slope, intercept + {0.20520392060279846, 362.1013488769531}, //Gr: slope, intercept + {0.40533769130706787, 241.33485412597656}, //R: slope, intercept + }, + { //iso 204800 + {0.6578512191772461, 286.16363525390625}, //B: slope, intercept + {0.223756805062294, 551.998779296875}, //Gb: slope, intercept + {0.22110669314861298, 562.9724731445312}, //Gr: slope, intercept + {0.4937806725502014, 371.5768737792969}, //R: slope, intercept + }, + { //iso 409600 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + //------------------------------------------------------------- + { //iso 819200 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + { //iso 1638400 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + { //iso 3276800 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + } + /*********************************************/ +}; +#endif + +// F1.0 Lens +#ifdef F10 +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.038478557020425796517, 2.14561891555786132813}, //B: slope, intercept + {0.03633839637041091919, 0.17788629233837127686}, //Gb: slope, intercept + {0.03592018783092498779, 0.21645727753639221191}, //Gr: slope, intercept + {0.03592239692807197571, 1.48806631565093994141}, //R: slope, intercept + }, + { //iso 200 + {0.04168356582522392273, 4.38879251480102539063}, //B: slope, intercept + {0.03754633292555809021, 3.21502065658569335938}, //Gb: slope, intercept + {0.03759334236383438110, 3.48370814323425292969}, //Gr: slope, intercept + {0.03719408065080642700, 4.63629007339477539063}, //R: slope, intercept + }, + { //iso 400 + {0.05050259083509445190, 6.85188436508178710938}, //B: slope, intercept + {0.04007886722683906555, 8.49916744232177734375}, //Gb: slope, intercept + {0.03934165090322494507, 8.68585968017578125000}, //Gr: slope, intercept + {0.04134147986769676208, 8.89877605438232421875}, //R: slope, intercept + }, + { //iso 800 + {0.04306267201900482178, 15.41853904724121093750}, //B: slope, intercept + {0.03570587188005447388, 18.56583213806152343750}, //Gb: slope, intercept + {0.03533876314759254456, 19.57685661315917968750}, //Gr: slope, intercept + {0.03832129389047622681, 17.90320968627929687500}, //R: slope, intercept + }, + { //iso 1600 + {0.06225715205073356628, 21.87150573730468750000}, //B: slope, intercept + {0.04437549784779548645, 30.87298965454101562500}, //Gb: slope, intercept + {0.04517432302236557007, 29.32084465026855468750}, //Gr: slope, intercept + {0.05255207046866416931, 26.26001358032226562500}, //R: slope, intercept + }, + { //iso 3200 + {0.07859147340059280396, 32.48978424072265625000}, //B: slope, intercept + {0.05918205901980400085, 45.08999633789062500000}, //Gb: slope, intercept + {0.05711782723665237427, 48.86173248291015625000}, //Gr: slope, intercept + {0.07310666143894195557, 36.88227081298828125000}, //R: slope, intercept + }, + { //iso 6400 + {0.11759266257286071777, 45.81345367431640625000}, //B: slope, intercept + {0.07679814100265502930, 69.04325866699218750000}, //Gb: slope, intercept + {0.07774948328733444214, 66.52905273437500000000}, //Gr: slope, intercept + {0.10286796092987060547, 51.73817443847656250000}, //R: slope, intercept + }, + { //iso 12800 + {0.15860086679458618164, 64.15329742431640625000}, //B: slope, intercept + {0.10511043667793273926, 91.36695098876953125000}, //Gb: slope, intercept + {0.10040879994630813599, 92.05632781982421875000}, //Gr: slope, intercept + {0.13499946892261505127, 73.36162567138671875000}, //R: slope, intercept + }, + { //iso 25600 + {0.22810073196887969971, 100.01741027832031250000}, //B: slope, intercept + {0.14736327528953552246, 146.62678527832031250000}, //Gb: slope, intercept + {0.15503610670566558838, 136.06079101562500000000}, //Gr: slope, intercept + {0.20250190794467926025, 112.74269104003906250000}, //R: slope, intercept + }, + { //iso 51200 + {0.29010805487632751465, 155.05882263183593750000}, //B: slope, intercept + {0.20221179723739624023, 210.97210693359375000000}, //Gb: slope, intercept + {0.21603405475616455078, 201.40393066406250000000}, //Gr: slope, intercept + {0.27819159626960754395, 165.48959350585937500000}, //R: slope, intercept + }, + { //iso 102400 + {0.40437409281730651855, 245.11883544921875000000}, //B: slope, intercept + {0.26703724265098571777, 345.62698364257812500000}, //Gb: slope, intercept + {0.27536261081695556641, 318.75701904296875000000}, //Gr: slope, intercept + {0.44441288709640502930, 222.47651672363281250000}, //R: slope, intercept + }, + { //iso 204800 + {0.48959052562713623047, 383.21560668945312500000}, //B: slope, intercept + {0.37694901227951049805, 442.55813598632812500000}, //Gb: slope, intercept + {0.38724529743194580078, 449.72384643554687500000}, //Gr: slope, intercept + {0.60220617055892944336, 318.92291259765625000000}, //R: slope, intercept + }, + { //iso 409600 + {0.59899300336837768555, 580.43414306640625000000}, //B: slope, intercept + {0.43681395053863525391, 700.22204589843750000000}, //Gb: slope, intercept + {0.50216537714004516602, 633.89794921875000000000}, //Gr: slope, intercept + {0.77917146682739257813, 453.13076782226562500000}, //R: slope, intercept + }, + { //iso 819200 + {0.54956322908401489258, 871.06585693359375000000}, //B: slope, intercept + {0.38088488578796386719, 1040.72192382812500000000}, //Gb: slope, intercept + {0.47245877981185913086, 937.37445068359375000000}, //Gr: slope, intercept + {0.70387065410614013672, 730.45373535156250000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.67512661218643188477, 797.11108398437500000000}, //B: slope, intercept + {0.50457936525344848633, 962.40740966796875000000}, //Gb: slope, intercept + {0.59857457876205444336, 856.90533447265625000000}, //Gr: slope, intercept + {0.74725526571273803711, 740.04290771484375000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.79927802085876464844, 687.07183837890625000000}, //B: slope, intercept + {0.81719654798507690430, 687.01580810546875000000}, //Gb: slope, intercept + {0.83395677804946899414, 658.91857910156250000000}, //Gr: slope, intercept + {0.72803622484207153320, 746.19427490234375000000}, //R: slope, intercept + }, +} }; +#endif + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {240, 240, 240, 240, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1088, 1088, 1088, 1088 +#endif + }, + .stAuto = { + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, +#endif + }, + }, +}; + + +struct combo_dev_attr_s imx327_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {2, 3, 1, 4, 0}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_DOL, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327/imx327_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx327/imx327_sensor_ctl.c new file mode 100644 index 000000000..542170ca1 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327/imx327_sensor_ctl.c @@ -0,0 +1,499 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_cmos_ex.h" + +static void imx327_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void imx327_linear_1080p30_init(VI_PIPE ViPipe); +static void imx327_linear_1080p60_init(VI_PIPE ViPipe); + +const CVI_U8 imx327_i2c_addr = 0x1A; +const CVI_U32 imx327_addr_byte = 2; +const CVI_U32 imx327_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx327_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx327_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx327_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int imx327_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx327_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (imx327_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, imx327_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, imx327_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (imx327_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int imx327_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx327_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx327_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx327_addr_byte + imx327_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx327_standby(VI_PIPE ViPipe) +{ + imx327_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ +} + +void imx327_restart(VI_PIPE ViPipe) +{ + imx327_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_write_register(ViPipe, 0x304b, 0x0a); +} + +void imx327_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx327[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx327_write_register(ViPipe, + g_pastImx327[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx327[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define IMX327_CHIP_ID_ADDR 0x31dc +#define IMX327_CHIP_ID 0x6 +#define IMX327_CHIP_ID_MASK 0x6 + +void imx327_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = imx327_read_register(ViPipe, 0x3007) & ~0x3; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + imx327_write_register(ViPipe, 0x3007, val); +} + +int imx327_probe(VI_PIPE ViPipe) +{ + int nVal; + + usleep(100); + if (imx327_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = imx327_read_register(ViPipe, IMX327_CHIP_ID_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((nVal & IMX327_CHIP_ID_MASK) != IMX327_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void imx327_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastImx327[ViPipe]->enWDRMode; + u8ImgMode = g_pastImx327[ViPipe]->u8ImgMode; + + imx327_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == IMX327_MODE_1080P30_WDR) { + imx327_wdr_1080p30_2to1_init(ViPipe); + } + } else { + if (u8ImgMode == IMX327_MODE_1080P60) + imx327_linear_1080p60_init(ViPipe); + else + imx327_linear_1080p30_init(ViPipe); + } + g_pastImx327[ViPipe]->bInit = CVI_TRUE; +} + +void imx327_exit(VI_PIPE ViPipe) +{ + imx327_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void imx327_linear_1080p30_init(VI_PIPE ViPipe) +{ + imx327_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx327_write_register(ViPipe, 0x3005, 0x01); /* ADBIT 10bit*/ + imx327_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx327_write_register(ViPipe, 0x3009, 0x02); /**/ + imx327_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx327_write_register(ViPipe, 0x3010, 0x21); + imx327_write_register(ViPipe, 0x3011, 0x02); + imx327_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx327_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx327_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx327_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx327_write_register(ViPipe, 0x301C, 0x30); /* HMAX[7:0], TBD*/ + imx327_write_register(ViPipe, 0x301D, 0x11); /* HMAX[15:8]*/ + imx327_write_register(ViPipe, 0x3020, 0x8C); /* SHS[7:0], TBD*/ + imx327_write_register(ViPipe, 0x3021, 0x01); /* SHS[15:8]*/ + imx327_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx327_write_register(ViPipe, 0x3046, 0x01); + imx327_write_register(ViPipe, 0x304B, 0x0A); + imx327_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx327_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx327_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx327_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx327_write_register(ViPipe, 0x309E, 0x4A); + imx327_write_register(ViPipe, 0x309F, 0x4A); + imx327_write_register(ViPipe, 0x30D2, 0x19); + imx327_write_register(ViPipe, 0x30D7, 0x03); + imx327_write_register(ViPipe, 0x3129, 0x00); + imx327_write_register(ViPipe, 0x313B, 0x61); + imx327_write_register(ViPipe, 0x315E, 0x1A); + imx327_write_register(ViPipe, 0x3164, 0x1A); + imx327_write_register(ViPipe, 0x317C, 0x00); + imx327_write_register(ViPipe, 0x31EC, 0x0E); + imx327_write_register(ViPipe, 0x3405, 0x20); /* Repetition*/ + imx327_write_register(ViPipe, 0x3407, 0x03); /* physical_lane_nl*/ + imx327_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx327_write_register(ViPipe, 0x3418, 0x49); /* y_out_size*/ + imx327_write_register(ViPipe, 0x3419, 0x04); /* y_out_size*/ + imx327_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx327_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx327_write_register(ViPipe, 0x3443, 0x03); /* csi_lane_mode*/ + imx327_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx327_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx327_write_register(ViPipe, 0x3446, 0x47); /* tclkpost*/ + imx327_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx327_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx327_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx327_write_register(ViPipe, 0x344A, 0x17); /* thsprepare*/ + imx327_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx327_write_register(ViPipe, 0x344C, 0x0F); /* tclktrail*/ + imx327_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx327_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx327_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx327_write_register(ViPipe, 0x3450, 0x47); /* tclkzero*/ + imx327_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx327_write_register(ViPipe, 0x3452, 0x0F); /* tclkprepare*/ + imx327_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx327_write_register(ViPipe, 0x3454, 0x0F); /* tlpx*/ + imx327_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx327_write_register(ViPipe, 0x3472, 0x9C); /* x_out_size*/ + imx327_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx327_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx327_default_reg_init(ViPipe); + + imx327_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_write_register(ViPipe, 0x304b, 0x0a); + + printf("ViPipe:%d,===IMX327 1080P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void imx327_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + imx327_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx327_write_register(ViPipe, 0x3005, 0x01); /* ADBIT*/ + imx327_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx327_write_register(ViPipe, 0x3009, 0x01); /**/ + imx327_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx327_write_register(ViPipe, 0x300C, 0x11); /* WDMODE [0] 0:Normal, 1:DOL, WDSEL [5:4] 1:DOL 2 frames*/ + imx327_write_register(ViPipe, 0x3011, 0x02); + imx327_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx327_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx327_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx327_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx327_write_register(ViPipe, 0x301C, 0x98); /* HMAX[7:0], TBD*/ + imx327_write_register(ViPipe, 0x301D, 0x08); /* HMAX[15:8]*/ + imx327_write_register(ViPipe, 0x3020, 0x02); /* SHS[7:0], TBD*/ + imx327_write_register(ViPipe, 0x3021, 0x00); /* SHS[15:8]*/ + imx327_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx327_write_register(ViPipe, 0x3024, 0xC9); /* SHS2[7:0], TBD*/ + imx327_write_register(ViPipe, 0x3025, 0x07); /* SHS2[15:8]*/ + imx327_write_register(ViPipe, 0x3026, 0x00); /* SHS2[19:16]*/ + imx327_write_register(ViPipe, 0x3030, 0x0B); /* RHS1[7:0], TBD*/ + imx327_write_register(ViPipe, 0x3031, 0x00); /* RHS1[15:8]*/ + imx327_write_register(ViPipe, 0x3032, 0x00); /* RHS1[19:16]*/ + imx327_write_register(ViPipe, 0x3045, 0x05); /* DOLSCDEN [0] 1: pattern1 0: pattern2*/ + imx327_write_register(ViPipe, 0x3046, 0x01); + imx327_write_register(ViPipe, 0x304B, 0x0A); + imx327_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx327_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx327_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx327_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx327_write_register(ViPipe, 0x309E, 0x4A); + imx327_write_register(ViPipe, 0x309F, 0x4A); + imx327_write_register(ViPipe, 0x30D2, 0x19); + imx327_write_register(ViPipe, 0x30D7, 0x03); + imx327_write_register(ViPipe, 0x3106, 0x11); /*DOLHBFIXEN[7] 0: pattern1 1: pattern2*/ + imx327_write_register(ViPipe, 0x3129, 0x00); + imx327_write_register(ViPipe, 0x313B, 0x61); + imx327_write_register(ViPipe, 0x315E, 0x1A); + imx327_write_register(ViPipe, 0x3164, 0x1A); + imx327_write_register(ViPipe, 0x317C, 0x00); + imx327_write_register(ViPipe, 0x31EC, 0x0E); + imx327_write_register(ViPipe, 0x3405, 0x10); /* Repetition*/ + imx327_write_register(ViPipe, 0x3407, 0x03); /* physical_lane_nl*/ + imx327_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx327_write_register(ViPipe, 0x3415, 0x00); /* NULL0_SIZE_V, set to 00h when DOL*/ + imx327_write_register(ViPipe, 0x3418, 0xB4); /* y_out_size*/ + imx327_write_register(ViPipe, 0x3419, 0x08); /* y_out_size*/ + imx327_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx327_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx327_write_register(ViPipe, 0x3443, 0x03); /* csi_lane_mode*/ + imx327_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx327_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx327_write_register(ViPipe, 0x3446, 0x57); /* tclkpost*/ + imx327_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx327_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx327_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx327_write_register(ViPipe, 0x344A, 0x1F); /* thsprepare*/ + imx327_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx327_write_register(ViPipe, 0x344C, 0x1F); /* tclktrail*/ + imx327_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx327_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx327_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx327_write_register(ViPipe, 0x3450, 0x77); /* tclkzero*/ + imx327_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx327_write_register(ViPipe, 0x3452, 0x1F); /* tclkprepare*/ + imx327_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx327_write_register(ViPipe, 0x3454, 0x17); /* tlpx*/ + imx327_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx327_write_register(ViPipe, 0x3472, 0xA0); /* x_out_size*/ + imx327_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx327_write_register(ViPipe, 0x347B, 0x23); /**/ + imx327_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx327_default_reg_init(ViPipe); + + if (g_au16Imx327_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + imx327_write_register(ViPipe, 0x30F0, 0xF0); + imx327_write_register(ViPipe, 0x3010, 0x21); + } else { + imx327_write_register(ViPipe, 0x30F0, 0x64); + imx327_write_register(ViPipe, 0x3010, 0x61); + } + + imx327_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_write_register(ViPipe, 0x304b, 0x0a); + + printf("===Imx327 sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} + +/* 1080P60 and 1080P50 */ +static void imx327_linear_1080p60_init(VI_PIPE ViPipe) +{ + imx327_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx327_write_register(ViPipe, 0x3005, 0x01); /* ADBIT 10bit*/ + imx327_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx327_write_register(ViPipe, 0x3009, 0x01); /**/ + imx327_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx327_write_register(ViPipe, 0x3010, 0x21); + imx327_write_register(ViPipe, 0x3011, 0x00); + imx327_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx327_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx327_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx327_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx327_write_register(ViPipe, 0x301C, 0x98); /* HMAX[7:0], TBD*/ + imx327_write_register(ViPipe, 0x301D, 0x08); /* HMAX[15:8]*/ + imx327_write_register(ViPipe, 0x3020, 0x8C); /* SHS[7:0], TBD*/ + imx327_write_register(ViPipe, 0x3021, 0x01); /* SHS[15:8]*/ + imx327_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx327_write_register(ViPipe, 0x3046, 0x01); + imx327_write_register(ViPipe, 0x304B, 0x0A); + imx327_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx327_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx327_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx327_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx327_write_register(ViPipe, 0x309E, 0x4A); + imx327_write_register(ViPipe, 0x309F, 0x4A); + imx327_write_register(ViPipe, 0x30D2, 0x19); + imx327_write_register(ViPipe, 0x30D7, 0x03); + imx327_write_register(ViPipe, 0x3129, 0x00); + imx327_write_register(ViPipe, 0x313B, 0x61); + imx327_write_register(ViPipe, 0x315E, 0x1A); + imx327_write_register(ViPipe, 0x3164, 0x1A); + imx327_write_register(ViPipe, 0x317C, 0x00); + imx327_write_register(ViPipe, 0x31EC, 0x0E); + imx327_write_register(ViPipe, 0x3405, 0x10); /* Repetition*/ + imx327_write_register(ViPipe, 0x3407, 0x03); /* physical_lane_nl*/ + imx327_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx327_write_register(ViPipe, 0x3418, 0x49); /* y_out_size*/ + imx327_write_register(ViPipe, 0x3419, 0x04); /* y_out_size*/ + imx327_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx327_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx327_write_register(ViPipe, 0x3443, 0x03); /* csi_lane_mode*/ + imx327_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx327_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx327_write_register(ViPipe, 0x3446, 0x57); /* tclkpost*/ + imx327_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx327_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx327_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx327_write_register(ViPipe, 0x344A, 0x1F); /* thsprepare*/ + imx327_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx327_write_register(ViPipe, 0x344C, 0x1F); /* tclktrail*/ + imx327_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx327_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx327_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx327_write_register(ViPipe, 0x3450, 0x77); /* tclkzero*/ + imx327_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx327_write_register(ViPipe, 0x3452, 0x1F); /* tclkprepare*/ + imx327_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx327_write_register(ViPipe, 0x3454, 0x17); /* tlpx*/ + imx327_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx327_write_register(ViPipe, 0x3472, 0x9C); /* x_out_size*/ + imx327_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx327_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx327_default_reg_init(ViPipe); + + imx327_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_write_register(ViPipe, 0x304b, 0x0a); + + printf("ViPipe:%d,===IMX327 1080P 60fps 12bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_2L/Makefile b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_2L/Makefile new file mode 100644 index 000000000..7570d61b7 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_2L/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx327_2l.a +TARGET_SO = $(MW_LIB)/libsns_imx327_2l.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_2L/imx327_2l_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_2L/imx327_2l_cmos.c new file mode 100644 index 000000000..c20f4fad6 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_2L/imx327_2l_cmos.c @@ -0,0 +1,1194 @@ +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "imx327_2l_cmos_ex.h" +#include "imx327_2l_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX327_2L_ID 327 +#define SENSOR_IMX327_2L_WIDTH 1920 +#define SENSOR_IMX327_2L_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx327_2l[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX327_2L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx327_2l[dev]) +#define IMX327_2L_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx327_2l[dev] = pstCtx) +#define IMX327_2L_SENSOR_RESET_CTX(dev) (g_pastImx327_2l[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunImx327_2l_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx327_2l_GainMode[VI_MAX_PIPE_NUM] = {0}; + +IMX327_2L_STATE_S g_astImx327_2l_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx327_2l_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx327 Lines Range*****/ +#define IMX327_2L_FULL_LINES_MAX (0x3FFFF) +#define IMX327_2L_FULL_LINES_MAX_2TO1_WDR (0x3FFFF) // considering the YOUT_SIZE and bad frame +#define IMX327_2L_VMAX_1080P30_LINEAR 1125 + +/*****Imx327 Register Address*****/ +#define IMX327_2L_HOLD_ADDR 0x3001 +#define IMX327_2L_SHS1_ADDR 0x3020 +#define IMX327_2L_SHS2_ADDR 0x3024 +#define IMX327_2L_GAIN_ADDR 0x3014 +#define IMX327_2L_GAIN1_ADDR 0x30F2 +#define IMX327_2L_HCG_ADDR 0x3009 +#define IMX327_2L_VMAX_ADDR 0x3018 +#define IMX327_2L_YOUT_ADDR 0x3418 +#define IMX327_2L_RHS1_ADDR 0x3030 +#define IMX327_2L_TABLE_END 0xffff + +#define IMX327_2L_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX327_2L_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astImx327_2l_mode[IMX327_2L_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_2l_mode[IMX327_2L_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astImx327_2l_mode[IMX327_2L_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_2l_mode[IMX327_2L_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = IMX327_2L_VMAX_1080P30_LINEAR; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astImx327_2l_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx327_2l_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx327_2l_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case IMX327_2L_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_2L_FULL_LINES_MAX_2TO1_WDR) ? IMX327_2L_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case IMX327_2L_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_2L_FULL_LINES_MAX) ? IMX327_2L_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } else { + pstSnsRegsInfo->astI2cData[DOL2_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx327_2l_State[ViPipe].u32RHS1_MAX = (u32VMAX - g_astImx327_2l_State[ViPipe].u32BRL) * 2 - 21; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHS1 = 0; + CVI_U32 u32SHS2 = 0; + CVI_U32 u32YOUTSIZE; + CVI_U32 u16BRL = 0; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u16BRL = g_astImx327_2l_mode[pstSnsState->u8ImgMode].u16BRL; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[0] < u32LongIntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], u32LongIntTime - 1); + return CVI_FAILURE; + } + u32SHS2 = pstSnsState->au32FL[0] - u32LongIntTime - 1; + + u32SHS1 = (u32ShortIntTime % 2) + 2; + u32RHS1 = u32ShortIntTime + u32SHS1 + 1; + g_astImx327_2l_State[ViPipe].u32RHS1 = u32RHS1; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - (u32SHS1 + 1); + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[0] - (u32SHS2 + 1); + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + u32YOUTSIZE = (u16BRL + (u32RHS1 - 1) / 2) * 2; + u32YOUTSIZE = (u32YOUTSIZE >= 0x1FFF) ? 0x1FFF : u32YOUTSIZE; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHS1 = %d\n", u32ShortIntTime, u32SHS1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d u32YOUTSIZE = %d\n", ViPipe, u32RHS1, u32YOUTSIZE); + + pstSnsRegsInfo->astI2cData[DOL2_SHS1_0].u32Data = (u32SHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_1].u32Data = ((u32SHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_2].u32Data = ((u32SHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHS2_0].u32Data = (u32SHS2 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_1].u32Data = ((u32SHS2 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_2].u32Data = ((u32SHS2 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_0].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_1].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_2].u32Data = ((u32RHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_0].u32Data = (u32YOUTSIZE & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_1].u32Data = ((u32YOUTSIZE & 0x1F00) >> 8); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if (pstSnsState->au32FL[0] < *u32IntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], *u32IntTime - 1); + return CVI_FAILURE; + } + u32Value = pstSnsState->au32FL[0] - *u32IntTime - 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2].u32Data = ((u32Value & 0x30000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 327567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32HCG = g_astImx327_2l_State[ViPipe].u8Hcg; + CVI_U32 u16Mode = g_au16Imx327_2l_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = (u32HCG & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + CVI_U8 bEnableHCG = 0; + + if (pu32Again[0] >= 20 && pu32Again[1] >= 20) { + /* hcg bit[4]*/ + u32HCG |= 0x10; + bEnableHCG = 1; + } + + u32Again = pu32Again[1] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + + u32Again = pu32Again[0] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN1].u32Data = (u32Tmp & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + if (u32HCG > 0xFF) { + u32HCG = 0xFF; + } + + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 2 : 2; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 10; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx327_2l_State[ViPipe].u32RHS1_MAX - 3)) ? + (g_astImx327_2l_State[ViPipe].u32RHS1_MAX - 3) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX327_2L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx327_2l_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX327_2L_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = IMX327_2L_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx327_2l_mode[pstSnsState->u8ImgMode].u32VtsDef; + g_astImx327_2l_State[ViPipe].u8Hcg = 0x2; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX327_2L_MODE_1080P30) + pstSnsState->u8ImgMode = IMX327_2L_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + g_astImx327_2l_State[ViPipe].u8Hcg = 0x1; + if (pstSnsState->u8ImgMode == IMX327_2L_MODE_1080P30_WDR) { + pstSnsState->u32FLStd = g_astImx327_2l_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx327_2l_State[ViPipe].u32BRL = g_astImx327_2l_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1080p\n"); + } + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx327_2l_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 2; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx327_2l_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx327_2l_addr_byte; + pstI2c_data[i].u32DataByteNum = imx327_2l_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_HOLD].u32RegAddr = IMX327_2L_HOLD_ADDR; + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_SHS1_0].u32RegAddr = IMX327_2L_SHS1_ADDR; + pstI2c_data[DOL2_SHS1_1].u32RegAddr = IMX327_2L_SHS1_ADDR + 1; + pstI2c_data[DOL2_SHS1_2].u32RegAddr = IMX327_2L_SHS1_ADDR + 2; + + pstI2c_data[DOL2_GAIN].u32RegAddr = IMX327_2L_GAIN_ADDR; + pstI2c_data[DOL2_HCG].u32RegAddr = IMX327_2L_HCG_ADDR; + pstI2c_data[DOL2_HCG].u8DelayFrmNum = 1; + pstI2c_data[DOL2_GAIN1].u32RegAddr = IMX327_2L_GAIN1_ADDR; + pstI2c_data[DOL2_RHS1_0].u32RegAddr = IMX327_2L_RHS1_ADDR; + pstI2c_data[DOL2_RHS1_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_1].u32RegAddr = IMX327_2L_RHS1_ADDR + 1; + pstI2c_data[DOL2_RHS1_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_2].u32RegAddr = IMX327_2L_RHS1_ADDR + 2; + pstI2c_data[DOL2_RHS1_2].u8DelayFrmNum = 1; + pstI2c_data[DOL2_SHS2_0].u32RegAddr = IMX327_2L_SHS2_ADDR; + pstI2c_data[DOL2_SHS2_1].u32RegAddr = IMX327_2L_SHS2_ADDR + 1; + pstI2c_data[DOL2_SHS2_2].u32RegAddr = IMX327_2L_SHS2_ADDR + 2; + pstI2c_data[DOL2_VMAX_0].u32RegAddr = IMX327_2L_VMAX_ADDR; + pstI2c_data[DOL2_VMAX_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_1].u32RegAddr = IMX327_2L_VMAX_ADDR + 1; + pstI2c_data[DOL2_VMAX_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_2].u32RegAddr = IMX327_2L_VMAX_ADDR + 2; + pstI2c_data[DOL2_VMAX_2].u8DelayFrmNum = 1; + + pstI2c_data[DOL2_YOUT_SIZE_0].u32RegAddr = IMX327_2L_YOUT_ADDR; + pstI2c_data[DOL2_YOUT_SIZE_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u32RegAddr = IMX327_2L_YOUT_ADDR + 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_REL].u32RegAddr = IMX327_2L_HOLD_ADDR; + pstI2c_data[DOL2_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 1; + break; + default: + pstI2c_data[LINEAR_HOLD].u32RegAddr = IMX327_2L_HOLD_ADDR; + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_SHS1_0].u32RegAddr = IMX327_2L_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1].u32RegAddr = IMX327_2L_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2].u32RegAddr = IMX327_2L_SHS1_ADDR + 2; + pstI2c_data[LINEAR_GAIN].u32RegAddr = IMX327_2L_GAIN_ADDR; + pstI2c_data[LINEAR_HCG].u32RegAddr = IMX327_2L_HCG_ADDR; + pstI2c_data[LINEAR_HCG].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VMAX_0].u32RegAddr = IMX327_2L_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1].u32RegAddr = IMX327_2L_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_2].u32RegAddr = IMX327_2L_VMAX_ADDR + 2; + pstI2c_data[LINEAR_REL].u32RegAddr = IMX327_2L_HOLD_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[DOL2_REL].u32Data = 0; + pstI2c_data[DOL2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX327_2L_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_2L_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX327_2L_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_2L_MODE_1080P30_WDR; + g_astImx327_2l_State[ViPipe].u32BRL = 1109; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx327_2l_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx327_2l_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx327_2l_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = IMX327_2L_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = IMX327_2L_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[0] = IMX327_2L_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[1] = IMX327_2L_VMAX_1080P30_LINEAR; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx327_2l_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx327_2l_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx327_2l_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx327_2l_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx327_2l_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx327_2l_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx327_2l_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx327_2l_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX327_2L_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX327_2L_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX327_2L_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX327_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX327_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX327_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx327_2l_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return imx327_2l_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsImx327_2l_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx327_2l_standby, + .pfnRestart = imx327_2l_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx327_2l_write_register, + .pfnReadReg = imx327_2l_read_register, + .pfnSetBusInfo = imx327_2l_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_2L/imx327_2l_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_2L/imx327_2l_cmos_ex.h new file mode 100644 index 000000000..7998d0590 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_2L/imx327_2l_cmos_ex.h @@ -0,0 +1,116 @@ +#ifndef __IMX327_2L_CMOS_EX_H_ +#define __IMX327_2L_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum imx327_2l_linear_regs_e { + LINEAR_HOLD = 0, + LINEAR_SHS1_0, + LINEAR_SHS1_1, + LINEAR_SHS1_2, + LINEAR_GAIN, + LINEAR_HCG, + LINEAR_VMAX_0, + LINEAR_VMAX_1, + LINEAR_VMAX_2, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum imx327_2l_dol2_regs_e { + DOL2_HOLD = 0, + DOL2_SHS1_0, + DOL2_SHS1_1, + DOL2_SHS1_2, + DOL2_GAIN, + DOL2_HCG, + DOL2_GAIN1, + DOL2_RHS1_0, + DOL2_RHS1_1, + DOL2_RHS1_2, + DOL2_SHS2_0, + DOL2_SHS2_1, + DOL2_SHS2_2, + DOL2_VMAX_0, + DOL2_VMAX_1, + DOL2_VMAX_2, + DOL2_YOUT_SIZE_0, + DOL2_YOUT_SIZE_1, + DOL2_REL, + DOL2_REGS_NUM +}; + +typedef enum _IMX327_2L_MODE_E { + IMX327_2L_MODE_1080P30 = 0, + IMX327_2L_MODE_LINEAR_NUM, + IMX327_2L_MODE_1080P30_WDR = IMX327_2L_MODE_LINEAR_NUM, + IMX327_2L_MODE_NUM +} IMX327_2L_MODE_E; + +typedef struct _IMX327_2L_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX327_2L_STATE_S; + +typedef struct _IMX327_2L_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX327_2L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx327_2l[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx327_2l_BusInfo[]; +extern CVI_U16 g_au16Imx327_2l_GainMode[]; +extern const CVI_U8 imx327_2l_i2c_addr; +extern const CVI_U32 imx327_2l_addr_byte; +extern const CVI_U32 imx327_2l_data_byte; +extern void imx327_2l_init(VI_PIPE ViPipe); +extern void imx327_2l_exit(VI_PIPE ViPipe); +extern void imx327_2l_standby(VI_PIPE ViPipe); +extern void imx327_2l_restart(VI_PIPE ViPipe); +extern int imx327_2l_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx327_2l_read_register(VI_PIPE ViPipe, int addr); +extern void imx327_2l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int imx327_2l_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_2L_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_2L/imx327_2l_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_2L/imx327_2l_cmos_param.h new file mode 100644 index 000000000..bef9b2e83 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_2L/imx327_2l_cmos_param.h @@ -0,0 +1,418 @@ +#ifndef __IMX327_2L_CMOS_PARAM_H_ +#define __IMX327_2L_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_2l_cmos_ex.h" + +static const IMX327_2L_MODE_S g_astImx327_2l_mode[IMX327_2L_MODE_NUM] = { + [IMX327_2L_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x1130, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX327_2L_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 8, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 2236, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 7, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, +}; + +// F1.8 Lens +#ifdef F18 +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = { + /*************Calibration LUT Table*************/ + .CalibrationCoef = { + { //iso 100 + {0.03243722766637802, 3.855583906173706}, //B: slope, intercept + {0.024103811010718346, 3.9538209438323975}, //Gb: slope, intercept + {0.022307759150862694, 4.970882892608643}, //Gr: slope, intercept + {0.02794046327471733, 3.1342978477478027}, //R: slope, intercept + }, + { //iso 200 + {0.03799639642238617, 5.526010990142822}, //B: slope, intercept + {0.02662081830203533, 7.61380672454834}, //Gb: slope, intercept + {0.025447502732276917, 8.231551170349121}, //Gr: slope, intercept + {0.032776281237602234, 5.149646282196045}, //R: slope, intercept + }, + { //iso 400 + {0.050715841352939606, 7.763713836669922}, //B: slope, intercept + {0.032093651592731476, 12.182195663452148}, //Gb: slope, intercept + {0.030688125640153885, 12.43420696258545}, //Gr: slope, intercept + {0.040235333144664764, 8.544824600219727}, //R: slope, intercept + }, + { //iso 800 + {0.06888508796691895, 10.970534324645996}, //B: slope, intercept + {0.03813415393233299, 19.28471565246582}, //Gb: slope, intercept + {0.03805641457438469, 19.625152587890625}, //Gr: slope, intercept + {0.04966627061367035, 12.69924545288086}, //R: slope, intercept + }, + { //iso 1600 + {0.08884920179843903, 15.890214920043945}, //B: slope, intercept + {0.046779610216617584, 30.772066116333008}, //Gb: slope, intercept + {0.045214589685201645, 31.489530563354492}, //Gr: slope, intercept + {0.06512749195098877, 20.34792137145996}, //R: slope, intercept + }, + { //iso 3200 + {0.1241341084241867, 20.70075225830078}, //B: slope, intercept + {0.05977431312203407, 45.98811721801758}, //Gb: slope, intercept + {0.05858884006738663, 47.11114501953125}, //Gr: slope, intercept + {0.08636551350355148, 30.561227798461914}, //R: slope, intercept + }, + { //iso 6400 + {0.1791478991508484, 30.803356170654297}, //B: slope, intercept + {0.09205856174230576, 65.60118103027344}, //Gb: slope, intercept + {0.08692053705453873, 69.85540771484375}, //Gr: slope, intercept + {0.12406758964061737, 45.617835998535156}, //R: slope, intercept + }, + { //iso 12800 + {0.2464703917503357, 44.136966705322266}, //B: slope, intercept + {0.11594483256340027, 97.8382797241211}, //Gb: slope, intercept + {0.11075824499130249, 101.47943115234375}, //Gr: slope, intercept + {0.17024046182632446, 66.47021484375}, //R: slope, intercept + }, + { //iso 25600 + {0.3376912772655487, 68.80254364013672}, //B: slope, intercept + {0.15025299787521362, 145.10032653808594}, //Gb: slope, intercept + {0.14386454224586487, 148.1698455810547}, //Gr: slope, intercept + {0.23965470492839813, 96.42337036132812}, //R: slope, intercept + }, + { //iso 51200 + {0.4279725253582001, 117.4070816040039}, //B: slope, intercept + {0.17134547233581543, 243.6494598388672}, //Gb: slope, intercept + {0.16668814420700073, 241.21603393554688}, //Gr: slope, intercept + {0.29862311482429504, 156.05364990234375}, //R: slope, intercept + }, + { //iso 102400 + {0.534967303276062, 181.45118713378906}, //B: slope, intercept + {0.2024478018283844, 365.00177001953125}, //Gb: slope, intercept + {0.20520392060279846, 362.1013488769531}, //Gr: slope, intercept + {0.40533769130706787, 241.33485412597656}, //R: slope, intercept + }, + { //iso 204800 + {0.6578512191772461, 286.16363525390625}, //B: slope, intercept + {0.223756805062294, 551.998779296875}, //Gb: slope, intercept + {0.22110669314861298, 562.9724731445312}, //Gr: slope, intercept + {0.4937806725502014, 371.5768737792969}, //R: slope, intercept + }, + { //iso 409600 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + //------------------------------------------------------------- + { //iso 819200 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + { //iso 1638400 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + { //iso 3276800 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + } + /*********************************************/ +}; +#endif + +// F1.0 Lens +#ifdef F10 +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.038478557020425796517, 2.14561891555786132813}, //B: slope, intercept + {0.03633839637041091919, 0.17788629233837127686}, //Gb: slope, intercept + {0.03592018783092498779, 0.21645727753639221191}, //Gr: slope, intercept + {0.03592239692807197571, 1.48806631565093994141}, //R: slope, intercept + }, + { //iso 200 + {0.04168356582522392273, 4.38879251480102539063}, //B: slope, intercept + {0.03754633292555809021, 3.21502065658569335938}, //Gb: slope, intercept + {0.03759334236383438110, 3.48370814323425292969}, //Gr: slope, intercept + {0.03719408065080642700, 4.63629007339477539063}, //R: slope, intercept + }, + { //iso 400 + {0.05050259083509445190, 6.85188436508178710938}, //B: slope, intercept + {0.04007886722683906555, 8.49916744232177734375}, //Gb: slope, intercept + {0.03934165090322494507, 8.68585968017578125000}, //Gr: slope, intercept + {0.04134147986769676208, 8.89877605438232421875}, //R: slope, intercept + }, + { //iso 800 + {0.04306267201900482178, 15.41853904724121093750}, //B: slope, intercept + {0.03570587188005447388, 18.56583213806152343750}, //Gb: slope, intercept + {0.03533876314759254456, 19.57685661315917968750}, //Gr: slope, intercept + {0.03832129389047622681, 17.90320968627929687500}, //R: slope, intercept + }, + { //iso 1600 + {0.06225715205073356628, 21.87150573730468750000}, //B: slope, intercept + {0.04437549784779548645, 30.87298965454101562500}, //Gb: slope, intercept + {0.04517432302236557007, 29.32084465026855468750}, //Gr: slope, intercept + {0.05255207046866416931, 26.26001358032226562500}, //R: slope, intercept + }, + { //iso 3200 + {0.07859147340059280396, 32.48978424072265625000}, //B: slope, intercept + {0.05918205901980400085, 45.08999633789062500000}, //Gb: slope, intercept + {0.05711782723665237427, 48.86173248291015625000}, //Gr: slope, intercept + {0.07310666143894195557, 36.88227081298828125000}, //R: slope, intercept + }, + { //iso 6400 + {0.11759266257286071777, 45.81345367431640625000}, //B: slope, intercept + {0.07679814100265502930, 69.04325866699218750000}, //Gb: slope, intercept + {0.07774948328733444214, 66.52905273437500000000}, //Gr: slope, intercept + {0.10286796092987060547, 51.73817443847656250000}, //R: slope, intercept + }, + { //iso 12800 + {0.15860086679458618164, 64.15329742431640625000}, //B: slope, intercept + {0.10511043667793273926, 91.36695098876953125000}, //Gb: slope, intercept + {0.10040879994630813599, 92.05632781982421875000}, //Gr: slope, intercept + {0.13499946892261505127, 73.36162567138671875000}, //R: slope, intercept + }, + { //iso 25600 + {0.22810073196887969971, 100.01741027832031250000}, //B: slope, intercept + {0.14736327528953552246, 146.62678527832031250000}, //Gb: slope, intercept + {0.15503610670566558838, 136.06079101562500000000}, //Gr: slope, intercept + {0.20250190794467926025, 112.74269104003906250000}, //R: slope, intercept + }, + { //iso 51200 + {0.29010805487632751465, 155.05882263183593750000}, //B: slope, intercept + {0.20221179723739624023, 210.97210693359375000000}, //Gb: slope, intercept + {0.21603405475616455078, 201.40393066406250000000}, //Gr: slope, intercept + {0.27819159626960754395, 165.48959350585937500000}, //R: slope, intercept + }, + { //iso 102400 + {0.40437409281730651855, 245.11883544921875000000}, //B: slope, intercept + {0.26703724265098571777, 345.62698364257812500000}, //Gb: slope, intercept + {0.27536261081695556641, 318.75701904296875000000}, //Gr: slope, intercept + {0.44441288709640502930, 222.47651672363281250000}, //R: slope, intercept + }, + { //iso 204800 + {0.48959052562713623047, 383.21560668945312500000}, //B: slope, intercept + {0.37694901227951049805, 442.55813598632812500000}, //Gb: slope, intercept + {0.38724529743194580078, 449.72384643554687500000}, //Gr: slope, intercept + {0.60220617055892944336, 318.92291259765625000000}, //R: slope, intercept + }, + { //iso 409600 + {0.59899300336837768555, 580.43414306640625000000}, //B: slope, intercept + {0.43681395053863525391, 700.22204589843750000000}, //Gb: slope, intercept + {0.50216537714004516602, 633.89794921875000000000}, //Gr: slope, intercept + {0.77917146682739257813, 453.13076782226562500000}, //R: slope, intercept + }, + { //iso 819200 + {0.54956322908401489258, 871.06585693359375000000}, //B: slope, intercept + {0.38088488578796386719, 1040.72192382812500000000}, //Gb: slope, intercept + {0.47245877981185913086, 937.37445068359375000000}, //Gr: slope, intercept + {0.70387065410614013672, 730.45373535156250000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.67512661218643188477, 797.11108398437500000000}, //B: slope, intercept + {0.50457936525344848633, 962.40740966796875000000}, //Gb: slope, intercept + {0.59857457876205444336, 856.90533447265625000000}, //Gr: slope, intercept + {0.74725526571273803711, 740.04290771484375000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.79927802085876464844, 687.07183837890625000000}, //B: slope, intercept + {0.81719654798507690430, 687.01580810546875000000}, //Gb: slope, intercept + {0.83395677804946899414, 658.91857910156250000000}, //Gr: slope, intercept + {0.72803622484207153320, 746.19427490234375000000}, //R: slope, intercept + }, +} }; +#endif + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {240, 240, 240, 240, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1088, 1088, 1088, 1088 +#endif + }, + .stAuto = { + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, +#endif + }, + }, +}; + +struct combo_dev_attr_s imx327_2l_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {2, 1, 0, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_DOL, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_2L_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_2L/imx327_2l_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_2L/imx327_2l_sensor_ctl.c new file mode 100644 index 000000000..7f3108481 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_2L/imx327_2l_sensor_ctl.c @@ -0,0 +1,418 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_2l_cmos_ex.h" + +static void imx327_2l_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void imx327_2l_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 imx327_2l_i2c_addr = 0x1A; +const CVI_U32 imx327_2l_addr_byte = 2; +const CVI_U32 imx327_2l_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx327_2l_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx327_2l_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx327_2l_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int imx327_2l_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx327_2l_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (imx327_2l_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, imx327_2l_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, imx327_2l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (imx327_2l_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int imx327_2l_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx327_2l_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx327_2l_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx327_2l_addr_byte + imx327_2l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx327_2l_standby(VI_PIPE ViPipe) +{ + imx327_2l_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_2l_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ +} + +void imx327_2l_restart(VI_PIPE ViPipe) +{ + imx327_2l_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_2l_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_2l_write_register(ViPipe, 0x304b, 0x0a); +} + +void imx327_2l_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx327_2l[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx327_2l_write_register(ViPipe, + g_pastImx327_2l[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx327_2l[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define IMX327_CHIP_ID_ADDR 0x31dc +#define IMX327_CHIP_ID 0x6 +#define IMX327_CHIP_ID_MASK 0x6 + +void imx327_2l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = imx327_2l_read_register(ViPipe, 0x3007) & ~0x3; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + imx327_2l_write_register(ViPipe, 0x3007, val); +} + +int imx327_2l_probe(VI_PIPE ViPipe) +{ + int nVal; + + usleep(100); + if (imx327_2l_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = imx327_2l_read_register(ViPipe, IMX327_CHIP_ID_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((nVal & IMX327_CHIP_ID_MASK) != IMX327_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void imx327_2l_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastImx327_2l[ViPipe]->enWDRMode; + u8ImgMode = g_pastImx327_2l[ViPipe]->u8ImgMode; + + imx327_2l_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == IMX327_2L_MODE_1080P30_WDR) { + imx327_2l_wdr_1080p30_2to1_init(ViPipe); + } + } else { + imx327_2l_linear_1080p30_init(ViPipe); + } + g_pastImx327_2l[ViPipe]->bInit = CVI_TRUE; +} + +void imx327_2l_exit(VI_PIPE ViPipe) +{ + imx327_2l_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void imx327_2l_linear_1080p30_init(VI_PIPE ViPipe) +{ + imx327_2l_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_2l_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_2l_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx327_2l_write_register(ViPipe, 0x3005, 0x01); /* ADBIT 10bit*/ + imx327_2l_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx327_2l_write_register(ViPipe, 0x3009, 0x02); /**/ + imx327_2l_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx327_2l_write_register(ViPipe, 0x3010, 0x21); + imx327_2l_write_register(ViPipe, 0x3011, 0x02); + imx327_2l_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx327_2l_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx327_2l_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx327_2l_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx327_2l_write_register(ViPipe, 0x301C, 0x30); /* HMAX[7:0], TBD*/ + imx327_2l_write_register(ViPipe, 0x301D, 0x11); /* HMAX[15:8]*/ + imx327_2l_write_register(ViPipe, 0x3020, 0x8C); /* SHS[7:0], TBD*/ + imx327_2l_write_register(ViPipe, 0x3021, 0x01); /* SHS[15:8]*/ + imx327_2l_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx327_2l_write_register(ViPipe, 0x3046, 0x01); + imx327_2l_write_register(ViPipe, 0x304B, 0x0A); + imx327_2l_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx327_2l_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx327_2l_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx327_2l_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx327_2l_write_register(ViPipe, 0x309E, 0x4A); + imx327_2l_write_register(ViPipe, 0x309F, 0x4A); + imx327_2l_write_register(ViPipe, 0x30D2, 0x19); + imx327_2l_write_register(ViPipe, 0x30D7, 0x03); + imx327_2l_write_register(ViPipe, 0x3129, 0x00); + imx327_2l_write_register(ViPipe, 0x313B, 0x61); + imx327_2l_write_register(ViPipe, 0x315E, 0x1A); + imx327_2l_write_register(ViPipe, 0x3164, 0x1A); + imx327_2l_write_register(ViPipe, 0x317C, 0x00); + imx327_2l_write_register(ViPipe, 0x31EC, 0x0E); + imx327_2l_write_register(ViPipe, 0x3405, 0x10); /* Repetition*/ + imx327_2l_write_register(ViPipe, 0x3407, 0x01); /* physical_lane_nl*/ + imx327_2l_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx327_2l_write_register(ViPipe, 0x3418, 0x49); /* y_out_size*/ + imx327_2l_write_register(ViPipe, 0x3419, 0x04); /* y_out_size*/ + imx327_2l_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx327_2l_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx327_2l_write_register(ViPipe, 0x3443, 0x01); /* csi_lane_mode*/ + imx327_2l_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx327_2l_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx327_2l_write_register(ViPipe, 0x3446, 0x57); /* tclkpost*/ + imx327_2l_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + //imx327_2l_write_register(ViPipe, 0x3448, 0x37); /* thszero*/ + imx327_2l_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx327_2l_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx327_2l_write_register(ViPipe, 0x344A, 0x1F); /* thsprepare*/ + imx327_2l_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx327_2l_write_register(ViPipe, 0x344C, 0x1F); /* tclktrail*/ + imx327_2l_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + //imx327_2l_write_register(ViPipe, 0x344E, 0x1F); /* thstrail*/ + imx327_2l_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx327_2l_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx327_2l_write_register(ViPipe, 0x3450, 0x77); /* tclkzero*/ + imx327_2l_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx327_2l_write_register(ViPipe, 0x3452, 0x1F); /* tclkprepare*/ + imx327_2l_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx327_2l_write_register(ViPipe, 0x3454, 0x17); /* tlpx*/ + imx327_2l_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx327_2l_write_register(ViPipe, 0x3472, 0x9C); /* x_out_size*/ + imx327_2l_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx327_2l_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx327_2l_default_reg_init(ViPipe); + + imx327_2l_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_2l_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_2l_write_register(ViPipe, 0x304b, 0x0a); + + printf("ViPipe:%d,===IMX327 1080P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void imx327_2l_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + imx327_2l_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_2l_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_2l_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx327_2l_write_register(ViPipe, 0x3005, 0x01); /* ADBIT*/ + imx327_2l_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx327_2l_write_register(ViPipe, 0x3009, 0x01); /**/ + imx327_2l_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx327_2l_write_register(ViPipe, 0x300C, 0x11); /* WDMODE [0] 0:Normal, 1:DOL, WDSEL [5:4] 1:DOL 2 frames*/ + imx327_2l_write_register(ViPipe, 0x3011, 0x02); + imx327_2l_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx327_2l_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx327_2l_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx327_2l_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx327_2l_write_register(ViPipe, 0x301C, 0x98); /* HMAX[7:0], TBD*/ + imx327_2l_write_register(ViPipe, 0x301D, 0x08); /* HMAX[15:8]*/ + imx327_2l_write_register(ViPipe, 0x3020, 0x02); /* SHS[7:0], TBD*/ + imx327_2l_write_register(ViPipe, 0x3021, 0x00); /* SHS[15:8]*/ + imx327_2l_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx327_2l_write_register(ViPipe, 0x3024, 0xC9); /* SHS2[7:0], TBD*/ + imx327_2l_write_register(ViPipe, 0x3025, 0x07); /* SHS2[15:8]*/ + imx327_2l_write_register(ViPipe, 0x3026, 0x00); /* SHS2[19:16]*/ + imx327_2l_write_register(ViPipe, 0x3030, 0x0B); /* RHS1[7:0], TBD*/ + imx327_2l_write_register(ViPipe, 0x3031, 0x00); /* RHS1[15:8]*/ + imx327_2l_write_register(ViPipe, 0x3032, 0x00); /* RHS1[19:16]*/ + imx327_2l_write_register(ViPipe, 0x3045, 0x05); /* DOLSCDEN [0] 1: pattern1 0: pattern2*/ + imx327_2l_write_register(ViPipe, 0x3046, 0x01); + imx327_2l_write_register(ViPipe, 0x304B, 0x0A); + imx327_2l_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx327_2l_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx327_2l_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx327_2l_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx327_2l_write_register(ViPipe, 0x309E, 0x4A); + imx327_2l_write_register(ViPipe, 0x309F, 0x4A); + imx327_2l_write_register(ViPipe, 0x30D2, 0x19); + imx327_2l_write_register(ViPipe, 0x30D7, 0x03); + imx327_2l_write_register(ViPipe, 0x3106, 0x15); /*DOLHBFIXEN[7] 0: pattern1 1: pattern2*/ + imx327_2l_write_register(ViPipe, 0x3129, 0x00); + imx327_2l_write_register(ViPipe, 0x313B, 0x61); + imx327_2l_write_register(ViPipe, 0x315E, 0x1A); + imx327_2l_write_register(ViPipe, 0x3164, 0x1A); + imx327_2l_write_register(ViPipe, 0x317C, 0x00); + imx327_2l_write_register(ViPipe, 0x31EC, 0x0E); + imx327_2l_write_register(ViPipe, 0x3405, 0x00); /* Repetition*/ + imx327_2l_write_register(ViPipe, 0x3407, 0x01); /* physical_lane_nl*/ + imx327_2l_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx327_2l_write_register(ViPipe, 0x3415, 0x00); /* NULL0_SIZE_V, set to 00h when DOL*/ + imx327_2l_write_register(ViPipe, 0x3418, 0xB4); /* y_out_size*/ + imx327_2l_write_register(ViPipe, 0x3419, 0x08); /* y_out_size*/ + imx327_2l_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx327_2l_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx327_2l_write_register(ViPipe, 0x3443, 0x01); /* csi_lane_mode*/ + imx327_2l_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx327_2l_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx327_2l_write_register(ViPipe, 0x3446, 0x77); /* tclkpost*/ + imx327_2l_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx327_2l_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx327_2l_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx327_2l_write_register(ViPipe, 0x344A, 0x47); /* thsprepare*/ + imx327_2l_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx327_2l_write_register(ViPipe, 0x344C, 0x37); /* tclktrail*/ + imx327_2l_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx327_2l_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx327_2l_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx327_2l_write_register(ViPipe, 0x3450, 0xFF); /* tclkzero*/ + imx327_2l_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx327_2l_write_register(ViPipe, 0x3452, 0x3F); /* tclkprepare*/ + imx327_2l_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx327_2l_write_register(ViPipe, 0x3454, 0x37); /* tlpx*/ + imx327_2l_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx327_2l_write_register(ViPipe, 0x3472, 0xA0); /* x_out_size*/ + imx327_2l_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx327_2l_write_register(ViPipe, 0x347B, 0x23); /**/ + imx327_2l_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx327_2l_default_reg_init(ViPipe); + + if (g_au16Imx327_2l_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + imx327_2l_write_register(ViPipe, 0x30F0, 0xF0); + imx327_2l_write_register(ViPipe, 0x3010, 0x21); + } else { + imx327_2l_write_register(ViPipe, 0x30F0, 0x64); + imx327_2l_write_register(ViPipe, 0x3010, 0x61); + } + + imx327_2l_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_2l_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_2l_write_register(ViPipe, 0x304b, 0x0a); + + printf("===Imx327 sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_fpga/Makefile b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_fpga/Makefile new file mode 100644 index 000000000..77b5fb33b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_fpga/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx327_fpga.a +TARGET_SO = $(MW_LIB)/libsns_imx327_fpga.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_fpga/imx327_fpga_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_fpga/imx327_fpga_cmos.c new file mode 100644 index 000000000..f04db5919 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_fpga/imx327_fpga_cmos.c @@ -0,0 +1,1251 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "imx327_fpga_cmos_ex.h" +#include "imx327_fpga_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX327_FPGA_ID 327 +#define SENSOR_IMX327_FPGA_WIDTH 1920 +#define SENSOR_IMX327_FPGA_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx327_fpga[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX327_FPGA_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx327_fpga[dev]) +#define IMX327_FPGA_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx327_fpga[dev] = pstCtx) +#define IMX327_FPGA_SENSOR_RESET_CTX(dev) (g_pastImx327_fpga[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunImx327_fpga_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx327_fpga_GainMode[VI_MAX_PIPE_NUM] = {0}; + +IMX327_FPGA_STATE_S g_astImx327_fpga_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx327_fpga_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx327 Lines Range*****/ +#define IMX327_FPGA_FULL_LINES_MAX (0x3FFFF) +#define IMX327_FPGA_FULL_LINES_MAX_2TO1_WDR (0x3FFFF) // considering the YOUT_SIZE and bad frame +#define IMX327_FPGA_VMAX_1080P30_LINEAR 1125 +#define IMX327_FPGA_VMAX_720P30_LINEAR 750 + +/*****Imx327 Register Address*****/ +#define IMX327_FPGA_HOLD_ADDR 0x3001 +#define IMX327_FPGA_SHS1_ADDR 0x3020 +#define IMX327_FPGA_SHS2_ADDR 0x3024 +#define IMX327_FPGA_GAIN_ADDR 0x3014 +#define IMX327_FPGA_GAIN1_ADDR 0x30F2 +#define IMX327_FPGA_HCG_ADDR 0x3009 +#define IMX327_FPGA_VMAX_ADDR 0x3018 +#define IMX327_FPGA_YOUT_ADDR 0x3418 +#define IMX327_FPGA_RHS1_ADDR 0x3030 +#define IMX327_FPGA_TABLE_END 0xffff + +#define IMX327_FPGA_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) +#define IMX327_FPGA_RES_IS_720P(w, h) ((w) <= 1280 && (h) <= 720) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX327_FPGA_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + if (pstSnsState->u8ImgMode == IMX327_FPGA_MODE_1080P30) { + pstAeSnsDft->f32Fps = g_astImx327_fpga_mode[IMX327_FPGA_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_fpga_mode[IMX327_FPGA_MODE_1080P30].f32MinFps; + } else { + pstAeSnsDft->f32Fps = g_astImx327_fpga_mode[IMX327_FPGA_MODE_720P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_fpga_mode[IMX327_FPGA_MODE_720P30].f32MinFps; + } + + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX327_FPGA_MODE_1080P30_WDR) { + pstAeSnsDft->f32Fps = g_astImx327_fpga_mode[IMX327_FPGA_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_fpga_mode[IMX327_FPGA_MODE_1080P30_WDR].f32MinFps; + } else { + pstAeSnsDft->f32Fps = g_astImx327_fpga_mode[IMX327_FPGA_MODE_720P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_fpga_mode[IMX327_FPGA_MODE_720P30_WDR].f32MinFps; + } + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = IMX327_FPGA_VMAX_1080P30_LINEAR; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case IMX327_FPGA_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_FPGA_FULL_LINES_MAX_2TO1_WDR) ? + IMX327_FPGA_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case IMX327_FPGA_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_FPGA_FULL_LINES_MAX) ? IMX327_FPGA_FULL_LINES_MAX : u32VMAX; + break; + case IMX327_FPGA_MODE_720P30: + case IMX327_FPGA_MODE_720P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_FPGA_FULL_LINES_MAX) ? IMX327_FPGA_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } else { + pstSnsRegsInfo->astI2cData[DOL2_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx327_fpga_State[ViPipe].u32RHS1_MAX = (u32VMAX - g_astImx327_fpga_State[ViPipe].u32BRL) * 2 - 21; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHS1 = 0; + CVI_U32 u32SHS2 = 0; + CVI_U32 u32YOUTSIZE; + CVI_U32 u16BRL = 0; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u16BRL = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].u16BRL; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[1] < u32LongIntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "WDR FL %d is smaller than = %d\n", + pstSnsState->au32FL[1], u32LongIntTime - 1); + return CVI_FAILURE; + } + u32SHS2 = pstSnsState->au32FL[1] - u32LongIntTime - 1; + + u32SHS1 = (u32ShortIntTime % 2) + 2; + u32RHS1 = u32ShortIntTime + u32SHS1 + 1; + g_astImx327_fpga_State[ViPipe].u32RHS1 = u32RHS1; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - (u32SHS1 + 1); + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[1] - (u32SHS2 + 1); + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + u32YOUTSIZE = (u16BRL + (u32RHS1 - 1) / 2) * 2; + u32YOUTSIZE = (u32YOUTSIZE >= 0x1FFF) ? 0x1FFF : u32YOUTSIZE; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHS1 = %d\n", u32ShortIntTime, u32SHS1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d u32YOUTSIZE = %d\n", ViPipe, u32RHS1, u32YOUTSIZE); + + pstSnsRegsInfo->astI2cData[DOL2_SHS1_0].u32Data = (u32SHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_1].u32Data = ((u32SHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_2].u32Data = ((u32SHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHS2_0].u32Data = (u32SHS2 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_1].u32Data = ((u32SHS2 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_2].u32Data = ((u32SHS2 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_0].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_1].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_2].u32Data = ((u32RHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_0].u32Data = (u32YOUTSIZE & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_1].u32Data = ((u32YOUTSIZE & 0x1F00) >> 8); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if (pstSnsState->au32FL[0] < *u32IntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], *u32IntTime - 1); + return CVI_FAILURE; + } + u32Value = pstSnsState->au32FL[0] - *u32IntTime - 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2].u32Data = ((u32Value & 0x30000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 327567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32HCG = g_astImx327_fpga_State[ViPipe].u8Hcg; + CVI_U32 u16Mode = g_au16Imx327_fpga_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = (u32HCG & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + CVI_U8 bEnableHCG = 0; + + if (pu32Again[0] >= 20 && pu32Again[1] >= 20) { + /* hcg bit[4]*/ + u32HCG |= 0x10; + bEnableHCG = 1; + } + + u32Again = pu32Again[1] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + + u32Again = pu32Again[0] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN1].u32Data = (u32Tmp & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) + u32Tmp = 0xFF; + + if (u32HCG > 0xFF) + u32HCG = 0xFF; + + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 2 : 2; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 10; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx327_fpga_State[ViPipe].u32RHS1_MAX - 3)) ? + (g_astImx327_fpga_State[ViPipe].u32RHS1_MAX - 3) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX327_FPGA_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx327_fpga_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + // CVI_U32 u32VBP1; + // CVI_U32 u32VBP1_MAX; + /* output height = BRL + VBP1 + * VBP1 = (RHS1 - 1)/2 + * long frame start_y = op_size_v + margin_top + * short frame start_y = op_size_v + margin_top + VBP1 + */ + // u32VBP1 = (g_astImx327_fpga_State[ViPipe].u32RHS1 - 1) >> 1; + // u32VBP1_MAX = (g_astImx327_fpga_State[ViPipe].u32RHS1_MAX - 1) >> 1; + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + // pstIspCfg->img_size[1].stSnsSize.u32Height = pstMode->u16BRL + u32VBP1; + // pstIspCfg->img_size[1].stWndRect.s32Y = pstMode->u16OpbSize + pstMode->u16MarginVtop; + // pstIspCfg->img_size[1].stMaxSize.u32Height = pstMode->u16BRL + u32VBP1_MAX; + // pstIspCfg->img_size[0].stSnsSize.u32Height = pstIspCfg->img_size[1].stSnsSize.u32Height; + // pstIspCfg->img_size[0].stWndRect.s32Y = pstMode->u16OpbSize + pstMode->u16MarginVtop + u32VBP1; + // pstIspCfg->img_size[0].stMaxSize.u32Height = pstIspCfg->img_size[1].stMaxSize.u32Height; + + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX327_FPGA_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = IMX327_FPGA_MODE_1080P30; + else if (pstSnsState->u8ImgMode == IMX327_FPGA_MODE_720P30_WDR) + pstSnsState->u8ImgMode = IMX327_FPGA_MODE_720P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].u32VtsDef; + g_astImx327_fpga_State[ViPipe].u8Hcg = 0x2; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX327_FPGA_MODE_1080P30) + pstSnsState->u8ImgMode = IMX327_FPGA_MODE_1080P30_WDR; + else if (pstSnsState->u8ImgMode == IMX327_FPGA_MODE_720P30) + pstSnsState->u8ImgMode = IMX327_FPGA_MODE_720P30_WDR; + + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + g_astImx327_fpga_State[ViPipe].u8Hcg = 0x1; + if (pstSnsState->u8ImgMode == IMX327_FPGA_MODE_1080P30_WDR) { + pstSnsState->u32FLStd = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx327_fpga_State[ViPipe].u32BRL = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1080p\n"); + } else if (pstSnsState->u8ImgMode == IMX327_FPGA_MODE_720P30_WDR) { + pstSnsState->u32FLStd = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx327_fpga_State[ViPipe].u32BRL = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 720P\n"); + } + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx327_fpga_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 2; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx327_fpga_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx327_fpga_addr_byte; + pstI2c_data[i].u32DataByteNum = imx327_fpga_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_HOLD].u32RegAddr = IMX327_FPGA_HOLD_ADDR; + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_SHS1_0].u32RegAddr = IMX327_FPGA_SHS1_ADDR; + pstI2c_data[DOL2_SHS1_1].u32RegAddr = IMX327_FPGA_SHS1_ADDR + 1; + pstI2c_data[DOL2_SHS1_2].u32RegAddr = IMX327_FPGA_SHS1_ADDR + 2; + + pstI2c_data[DOL2_GAIN].u32RegAddr = IMX327_FPGA_GAIN_ADDR; + pstI2c_data[DOL2_HCG].u32RegAddr = IMX327_FPGA_HCG_ADDR; + pstI2c_data[DOL2_HCG].u8DelayFrmNum = 1; + pstI2c_data[DOL2_GAIN1].u32RegAddr = IMX327_FPGA_GAIN1_ADDR; + pstI2c_data[DOL2_RHS1_0].u32RegAddr = IMX327_FPGA_RHS1_ADDR; + pstI2c_data[DOL2_RHS1_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_1].u32RegAddr = IMX327_FPGA_RHS1_ADDR + 1; + pstI2c_data[DOL2_RHS1_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_2].u32RegAddr = IMX327_FPGA_RHS1_ADDR + 2; + pstI2c_data[DOL2_RHS1_2].u8DelayFrmNum = 1; + pstI2c_data[DOL2_SHS2_0].u32RegAddr = IMX327_FPGA_SHS2_ADDR; + pstI2c_data[DOL2_SHS2_1].u32RegAddr = IMX327_FPGA_SHS2_ADDR + 1; + pstI2c_data[DOL2_SHS2_2].u32RegAddr = IMX327_FPGA_SHS2_ADDR + 2; + pstI2c_data[DOL2_VMAX_0].u32RegAddr = IMX327_FPGA_VMAX_ADDR; + pstI2c_data[DOL2_VMAX_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_1].u32RegAddr = IMX327_FPGA_VMAX_ADDR + 1; + pstI2c_data[DOL2_VMAX_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_2].u32RegAddr = IMX327_FPGA_VMAX_ADDR + 2; + pstI2c_data[DOL2_VMAX_2].u8DelayFrmNum = 1; + + pstI2c_data[DOL2_YOUT_SIZE_0].u32RegAddr = IMX327_FPGA_YOUT_ADDR; + pstI2c_data[DOL2_YOUT_SIZE_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u32RegAddr = IMX327_FPGA_YOUT_ADDR + 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_REL].u32RegAddr = IMX327_FPGA_HOLD_ADDR; + pstI2c_data[DOL2_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 1; + break; + default: + pstI2c_data[LINEAR_HOLD].u32RegAddr = IMX327_FPGA_HOLD_ADDR; + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_SHS1_0].u32RegAddr = IMX327_FPGA_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1].u32RegAddr = IMX327_FPGA_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2].u32RegAddr = IMX327_FPGA_SHS1_ADDR + 2; + pstI2c_data[LINEAR_GAIN].u32RegAddr = IMX327_FPGA_GAIN_ADDR; + pstI2c_data[LINEAR_HCG].u32RegAddr = IMX327_FPGA_HCG_ADDR; + pstI2c_data[LINEAR_HCG].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VMAX_0].u32RegAddr = IMX327_FPGA_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1].u32RegAddr = IMX327_FPGA_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_2].u32RegAddr = IMX327_FPGA_VMAX_ADDR + 2; + pstI2c_data[LINEAR_REL].u32RegAddr = IMX327_FPGA_HOLD_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[DOL2_REL].u32Data = 0; + pstI2c_data[DOL2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX327_FPGA_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_FPGA_MODE_720P30; + } else if (IMX327_FPGA_RES_IS_1080P(pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_FPGA_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX327_FPGA_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_FPGA_MODE_720P30_WDR; + CVI_TRACE_SNS(CVI_DBG_ERR, "enter IMX327_FPGA_MODE_720P30_WDR mode\n"); + } else if (IMX327_FPGA_RES_IS_1080P(pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_FPGA_MODE_1080P30_WDR; + g_astImx327_fpga_State[ViPipe].u32BRL = 1109; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) + return CVI_FAILURE; + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx327_fpga_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx327_fpga_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx327_fpga_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u8ImgMode = IMX327_FPGA_MODE_720P30_WDR; + // pstSnsState->u8ImgMode = IMX327_FPGA_MODE_1080P30; + pstSnsState->u32FLStd = IMX327_FPGA_VMAX_720P30_LINEAR; + pstSnsState->au32FL[0] = IMX327_FPGA_VMAX_720P30_LINEAR; + pstSnsState->au32FL[1] = IMX327_FPGA_VMAX_720P30_LINEAR; + // pstSnsState->u32FLStd = IMX327_FPGA_VMAX_1080P30_LINEAR; + // pstSnsState->au32FL[0] = IMX327_FPGA_VMAX_1080P30_LINEAR; + // pstSnsState->au32FL[1] = IMX327_FPGA_VMAX_1080P30_LINEAR; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx327_fpga_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + CVI_TRACE_SNS(CVI_DBG_INFO, "sensor_rx_attr/enWDRMode=%d\n", pstSnsState->enWDRMode); + pstRxAttr->wdr_manu.manual_en = 1; + pstRxAttr->wdr_manu.l2s_distance = 0; + pstRxAttr->wdr_manu.lsef_length = 0x1FFF; + pstRxAttr->wdr_manu.discard_padding_lines = 1; + pstRxAttr->wdr_manu.update = 1; + } else { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx327_fpga_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx327_fpga_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx327_fpga_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx327_fpga_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx327_fpga_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX327_FPGA_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX327_FPGA_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX327_FPGA_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX327_FPGA_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX327_FPGA_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX327_FPGA_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx327_fpga_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsImx327_fpga_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx327_fpga_standby, + .pfnRestart = imx327_fpga_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx327_fpga_write_register, + .pfnReadReg = imx327_fpga_read_register, + .pfnSetBusInfo = imx327_fpga_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_fpga/imx327_fpga_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_fpga/imx327_fpga_cmos_ex.h new file mode 100644 index 000000000..83bcf6cfe --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_fpga/imx327_fpga_cmos_ex.h @@ -0,0 +1,116 @@ +#ifndef __IMX327_FPGA_CMOS_EX_H_ +#define __IMX327_FPGA_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +enum imx327_fpga_linear_regs_e { + LINEAR_HOLD = 0, + LINEAR_SHS1_0, + LINEAR_SHS1_1, + LINEAR_SHS1_2, + LINEAR_GAIN, + LINEAR_HCG, + LINEAR_VMAX_0, + LINEAR_VMAX_1, + LINEAR_VMAX_2, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum imx327_fpga_dol2_regs_e { + DOL2_HOLD = 0, + DOL2_SHS1_0, + DOL2_SHS1_1, + DOL2_SHS1_2, + DOL2_GAIN, + DOL2_HCG, + DOL2_GAIN1, + DOL2_RHS1_0, + DOL2_RHS1_1, + DOL2_RHS1_2, + DOL2_SHS2_0, + DOL2_SHS2_1, + DOL2_SHS2_2, + DOL2_VMAX_0, + DOL2_VMAX_1, + DOL2_VMAX_2, + DOL2_YOUT_SIZE_0, + DOL2_YOUT_SIZE_1, + DOL2_REL, + DOL2_REGS_NUM +}; + +typedef enum _IMX327_FPGA_MODE_E { + IMX327_FPGA_MODE_720P30, + IMX327_FPGA_MODE_1080P30, + IMX327_FPGA_MODE_LINEAR_NUM, + IMX327_FPGA_MODE_720P30_WDR = IMX327_FPGA_MODE_LINEAR_NUM, + IMX327_FPGA_MODE_1080P30_WDR, + IMX327_FPGA_MODE_NUM +} IMX327_FPGA_MODE_E; + +typedef struct _IMX327_FPGA_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX327_FPGA_STATE_S; + +typedef struct _IMX327_FPGA_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX327_FPGA_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx327_fpga[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx327_fpga_BusInfo[]; +extern CVI_U16 g_au16Imx327_fpga_GainMode[]; +extern const CVI_U8 imx327_fpga_i2c_addr; +extern const CVI_U32 imx327_fpga_addr_byte; +extern const CVI_U32 imx327_fpga_data_byte; +extern void imx327_fpga_init(VI_PIPE ViPipe); +extern void imx327_fpga_exit(VI_PIPE ViPipe); +extern void imx327_fpga_standby(VI_PIPE ViPipe); +extern void imx327_fpga_restart(VI_PIPE ViPipe); +extern int imx327_fpga_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx327_fpga_read_register(VI_PIPE ViPipe, int addr); +extern void imx327_fpga_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_FPGA_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_fpga/imx327_fpga_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_fpga/imx327_fpga_cmos_param.h new file mode 100644 index 000000000..251b36507 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_fpga/imx327_fpga_cmos_param.h @@ -0,0 +1,544 @@ +#ifndef __IMX327_FPGA_CMOS_PARAM_FPGA_H_ +#define __IMX327_FPGA_CMOS_PARAM_FPGA_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_fpga_cmos_ex.h" + +static const IMX327_FPGA_MODE_S g_astImx327_fpga_mode[IMX327_FPGA_MODE_NUM] = { + [IMX327_FPGA_MODE_720P30] = { + .name = "720p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1308, + .u32Height = 729, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1308, + .u32Height = 729, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.09, /* 750 *30 / 0x3FFFF */ + .u32HtsDef = 0x19C8, + .u32VtsDef = 750, + .stExp[0] = { + .u16Min = 1, + .u16Max = 750, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 9, + .u16BRL = 735, + .u16OpbSize = 4, + .u16MarginVtop = 4, + .u16MarginVbot = 5, + }, + [IMX327_FPGA_MODE_720P30_WDR] = { + .name = "720p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1308, + .u32Height = 729, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1308, + .u32Height = 729, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 1308, + .u32Height = 729, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1308, + .u32Height = 729, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.09, /* 750 *30 / 0x3FFFF */ + .u32HtsDef = 0x19C8, + .u32VtsDef = 750, + .stExp[0] = { + .u16Min = 1, + .u16Max = 750, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 750, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 9, + .u16BRL = 735, + .u16OpbSize = 4, + .u16MarginVtop = 4, + .u16MarginVbot = 5, + }, + [IMX327_FPGA_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x1130, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX327_FPGA_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 1952, + .u32Height = 1114, + }, + .stWndRect = { + .s32X = 16, + .s32Y = 20, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1952, + .u32Height = 1114, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 1952, + .u32Height = 1114, + }, + .stWndRect = { + .s32X = 16, + .s32Y = 15, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1952, + .u32Height = 1114, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 8, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 2236, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 7, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, +}; + +// F1.8 Lens +#ifdef F18 +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = { + /*************Calibration LUT Table*************/ + .CalibrationCoef = { + { //iso 100 + {0.03243722766637802, 3.855583906173706}, //B: slope, intercept + {0.024103811010718346, 3.9538209438323975}, //Gb: slope, intercept + {0.022307759150862694, 4.970882892608643}, //Gr: slope, intercept + {0.02794046327471733, 3.1342978477478027}, //R: slope, intercept + }, + { //iso 200 + {0.03799639642238617, 5.526010990142822}, //B: slope, intercept + {0.02662081830203533, 7.61380672454834}, //Gb: slope, intercept + {0.025447502732276917, 8.231551170349121}, //Gr: slope, intercept + {0.032776281237602234, 5.149646282196045}, //R: slope, intercept + }, + { //iso 400 + {0.050715841352939606, 7.763713836669922}, //B: slope, intercept + {0.032093651592731476, 12.182195663452148}, //Gb: slope, intercept + {0.030688125640153885, 12.43420696258545}, //Gr: slope, intercept + {0.040235333144664764, 8.544824600219727}, //R: slope, intercept + }, + { //iso 800 + {0.06888508796691895, 10.970534324645996}, //B: slope, intercept + {0.03813415393233299, 19.28471565246582}, //Gb: slope, intercept + {0.03805641457438469, 19.625152587890625}, //Gr: slope, intercept + {0.04966627061367035, 12.69924545288086}, //R: slope, intercept + }, + { //iso 1600 + {0.08884920179843903, 15.890214920043945}, //B: slope, intercept + {0.046779610216617584, 30.772066116333008}, //Gb: slope, intercept + {0.045214589685201645, 31.489530563354492}, //Gr: slope, intercept + {0.06512749195098877, 20.34792137145996}, //R: slope, intercept + }, + { //iso 3200 + {0.1241341084241867, 20.70075225830078}, //B: slope, intercept + {0.05977431312203407, 45.98811721801758}, //Gb: slope, intercept + {0.05858884006738663, 47.11114501953125}, //Gr: slope, intercept + {0.08636551350355148, 30.561227798461914}, //R: slope, intercept + }, + { //iso 6400 + {0.1791478991508484, 30.803356170654297}, //B: slope, intercept + {0.09205856174230576, 65.60118103027344}, //Gb: slope, intercept + {0.08692053705453873, 69.85540771484375}, //Gr: slope, intercept + {0.12406758964061737, 45.617835998535156}, //R: slope, intercept + }, + { //iso 12800 + {0.2464703917503357, 44.136966705322266}, //B: slope, intercept + {0.11594483256340027, 97.8382797241211}, //Gb: slope, intercept + {0.11075824499130249, 101.47943115234375}, //Gr: slope, intercept + {0.17024046182632446, 66.47021484375}, //R: slope, intercept + }, + { //iso 25600 + {0.3376912772655487, 68.80254364013672}, //B: slope, intercept + {0.15025299787521362, 145.10032653808594}, //Gb: slope, intercept + {0.14386454224586487, 148.1698455810547}, //Gr: slope, intercept + {0.23965470492839813, 96.42337036132812}, //R: slope, intercept + }, + { //iso 51200 + {0.4279725253582001, 117.4070816040039}, //B: slope, intercept + {0.17134547233581543, 243.6494598388672}, //Gb: slope, intercept + {0.16668814420700073, 241.21603393554688}, //Gr: slope, intercept + {0.29862311482429504, 156.05364990234375}, //R: slope, intercept + }, + { //iso 102400 + {0.534967303276062, 181.45118713378906}, //B: slope, intercept + {0.2024478018283844, 365.00177001953125}, //Gb: slope, intercept + {0.20520392060279846, 362.1013488769531}, //Gr: slope, intercept + {0.40533769130706787, 241.33485412597656}, //R: slope, intercept + }, + { //iso 204800 + {0.6578512191772461, 286.16363525390625}, //B: slope, intercept + {0.223756805062294, 551.998779296875}, //Gb: slope, intercept + {0.22110669314861298, 562.9724731445312}, //Gr: slope, intercept + {0.4937806725502014, 371.5768737792969}, //R: slope, intercept + }, + { //iso 409600 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + //------------------------------------------------------------- + { //iso 819200 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + { //iso 1638400 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + { //iso 3276800 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + } + /*********************************************/ +}; +#endif + +// F1.0 Lens +#ifdef F10 +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.038478557020425796517, 2.14561891555786132813}, //B: slope, intercept + {0.03633839637041091919, 0.17788629233837127686}, //Gb: slope, intercept + {0.03592018783092498779, 0.21645727753639221191}, //Gr: slope, intercept + {0.03592239692807197571, 1.48806631565093994141}, //R: slope, intercept + }, + { //iso 200 + {0.04168356582522392273, 4.38879251480102539063}, //B: slope, intercept + {0.03754633292555809021, 3.21502065658569335938}, //Gb: slope, intercept + {0.03759334236383438110, 3.48370814323425292969}, //Gr: slope, intercept + {0.03719408065080642700, 4.63629007339477539063}, //R: slope, intercept + }, + { //iso 400 + {0.05050259083509445190, 6.85188436508178710938}, //B: slope, intercept + {0.04007886722683906555, 8.49916744232177734375}, //Gb: slope, intercept + {0.03934165090322494507, 8.68585968017578125000}, //Gr: slope, intercept + {0.04134147986769676208, 8.89877605438232421875}, //R: slope, intercept + }, + { //iso 800 + {0.04306267201900482178, 15.41853904724121093750}, //B: slope, intercept + {0.03570587188005447388, 18.56583213806152343750}, //Gb: slope, intercept + {0.03533876314759254456, 19.57685661315917968750}, //Gr: slope, intercept + {0.03832129389047622681, 17.90320968627929687500}, //R: slope, intercept + }, + { //iso 1600 + {0.06225715205073356628, 21.87150573730468750000}, //B: slope, intercept + {0.04437549784779548645, 30.87298965454101562500}, //Gb: slope, intercept + {0.04517432302236557007, 29.32084465026855468750}, //Gr: slope, intercept + {0.05255207046866416931, 26.26001358032226562500}, //R: slope, intercept + }, + { //iso 3200 + {0.07859147340059280396, 32.48978424072265625000}, //B: slope, intercept + {0.05918205901980400085, 45.08999633789062500000}, //Gb: slope, intercept + {0.05711782723665237427, 48.86173248291015625000}, //Gr: slope, intercept + {0.07310666143894195557, 36.88227081298828125000}, //R: slope, intercept + }, + { //iso 6400 + {0.11759266257286071777, 45.81345367431640625000}, //B: slope, intercept + {0.07679814100265502930, 69.04325866699218750000}, //Gb: slope, intercept + {0.07774948328733444214, 66.52905273437500000000}, //Gr: slope, intercept + {0.10286796092987060547, 51.73817443847656250000}, //R: slope, intercept + }, + { //iso 12800 + {0.15860086679458618164, 64.15329742431640625000}, //B: slope, intercept + {0.10511043667793273926, 91.36695098876953125000}, //Gb: slope, intercept + {0.10040879994630813599, 92.05632781982421875000}, //Gr: slope, intercept + {0.13499946892261505127, 73.36162567138671875000}, //R: slope, intercept + }, + { //iso 25600 + {0.22810073196887969971, 100.01741027832031250000}, //B: slope, intercept + {0.14736327528953552246, 146.62678527832031250000}, //Gb: slope, intercept + {0.15503610670566558838, 136.06079101562500000000}, //Gr: slope, intercept + {0.20250190794467926025, 112.74269104003906250000}, //R: slope, intercept + }, + { //iso 51200 + {0.29010805487632751465, 155.05882263183593750000}, //B: slope, intercept + {0.20221179723739624023, 210.97210693359375000000}, //Gb: slope, intercept + {0.21603405475616455078, 201.40393066406250000000}, //Gr: slope, intercept + {0.27819159626960754395, 165.48959350585937500000}, //R: slope, intercept + }, + { //iso 102400 + {0.40437409281730651855, 245.11883544921875000000}, //B: slope, intercept + {0.26703724265098571777, 345.62698364257812500000}, //Gb: slope, intercept + {0.27536261081695556641, 318.75701904296875000000}, //Gr: slope, intercept + {0.44441288709640502930, 222.47651672363281250000}, //R: slope, intercept + }, + { //iso 204800 + {0.48959052562713623047, 383.21560668945312500000}, //B: slope, intercept + {0.37694901227951049805, 442.55813598632812500000}, //Gb: slope, intercept + {0.38724529743194580078, 449.72384643554687500000}, //Gr: slope, intercept + {0.60220617055892944336, 318.92291259765625000000}, //R: slope, intercept + }, + { //iso 409600 + {0.59899300336837768555, 580.43414306640625000000}, //B: slope, intercept + {0.43681395053863525391, 700.22204589843750000000}, //Gb: slope, intercept + {0.50216537714004516602, 633.89794921875000000000}, //Gr: slope, intercept + {0.77917146682739257813, 453.13076782226562500000}, //R: slope, intercept + }, + { //iso 819200 + {0.54956322908401489258, 871.06585693359375000000}, //B: slope, intercept + {0.38088488578796386719, 1040.72192382812500000000}, //Gb: slope, intercept + {0.47245877981185913086, 937.37445068359375000000}, //Gr: slope, intercept + {0.70387065410614013672, 730.45373535156250000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.67512661218643188477, 797.11108398437500000000}, //B: slope, intercept + {0.50457936525344848633, 962.40740966796875000000}, //Gb: slope, intercept + {0.59857457876205444336, 856.90533447265625000000}, //Gr: slope, intercept + {0.74725526571273803711, 740.04290771484375000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.79927802085876464844, 687.07183837890625000000}, //B: slope, intercept + {0.81719654798507690430, 687.01580810546875000000}, //Gb: slope, intercept + {0.83395677804946899414, 658.91857910156250000000}, //Gr: slope, intercept + {0.72803622484207153320, 746.19427490234375000000}, //R: slope, intercept + }, +} }; +#endif + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {240, 240, 240, 240, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1088, 1088, 1088, 1088 +#endif + }, + .stAuto = { + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, +#endif + }, + }, +}; + + +struct combo_dev_attr_s imx327_fpga_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {0, 1, 2, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_DOL, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_FPGA_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_fpga/imx327_fpga_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_fpga/imx327_fpga_sensor_ctl.c new file mode 100644 index 000000000..bbf9887b4 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_fpga/imx327_fpga_sensor_ctl.c @@ -0,0 +1,370 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_fpga_cmos_ex.h" + +static void imx327_fpga_wdr_720p30_2to1_init(VI_PIPE ViPipe); +static void imx327_fpga_linear_720p30_init(VI_PIPE ViPipe); + +const CVI_U8 imx327_fpga_i2c_addr = 0x1A; +const CVI_U32 imx327_fpga_addr_byte = 2; +const CVI_U32 imx327_fpga_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx327_fpga_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx327_fpga_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx327_fpga_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + CVI_TRACE_SNS(CVI_DBG_INFO, "Open /dev/i2c-%u ok!\n", u8DevNum); + return CVI_SUCCESS; +} + +int imx327_fpga_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx327_fpga_read_register(VI_PIPE ViPipe, int addr) +{ + /* TODO:*/ + (void) ViPipe; + (void) addr; + + return CVI_SUCCESS; +} + + +int imx327_fpga_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx327_fpga_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx327_fpga_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx327_fpga_addr_byte + imx327_fpga_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE 0x%x 0x%x error!\n", addr, data); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx327_fpga_standby(VI_PIPE ViPipe) +{ + imx327_fpga_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_fpga_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ +} + +void imx327_fpga_restart(VI_PIPE ViPipe) +{ + imx327_fpga_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_fpga_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_fpga_write_register(ViPipe, 0x304b, 0x0a); +} + +void imx327_fpga_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx327_fpga[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx327_fpga_write_register(ViPipe, + g_pastImx327_fpga[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx327_fpga[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void imx327_fpga_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = imx327_fpga_read_register(ViPipe, 0x3007) & ~0x3; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + imx327_fpga_write_register(ViPipe, 0x3007, val); +} + +void imx327_fpga_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + + enWDRMode = g_pastImx327_fpga[ViPipe]->enWDRMode; + + imx327_fpga_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) + imx327_fpga_wdr_720p30_2to1_init(ViPipe); + else + imx327_fpga_linear_720p30_init(ViPipe); + + g_pastImx327_fpga[ViPipe]->bInit = CVI_TRUE; +} + +void imx327_fpga_exit(VI_PIPE ViPipe) +{ + imx327_fpga_i2c_exit(ViPipe); +} + +static void imx327_fpga_linear_720p30_init(VI_PIPE ViPipe) +{ + imx327_fpga_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_fpga_write_register(ViPipe, 0x3000, 0x01); // STANDBY + imx327_fpga_write_register(ViPipe, 0x3001, 0x00); // HOLD + imx327_fpga_write_register(ViPipe, 0x3002, 0x00); // XMSTA + imx327_fpga_write_register(ViPipe, 0x3005, 0x00); // ADBIT 10bit +// imx327_fpga_write_register(ViPipe, 0x3007, 0x10); // VREVERS, ... + imx327_fpga_write_register(ViPipe, 0x3007, 0x11); // V VREVERS, ... + imx327_fpga_write_register(ViPipe, 0x3009, 0x02); // + imx327_fpga_write_register(ViPipe, 0x300A, 0x3C); // BLKLEVEL + //imx327_fpga_write_register(ViPipe, 0x300C, 0x00); // WDMODE [0] 0:Normal, 1:DOL, WDSEL [5:4] 1:DOL 2 frames + imx327_fpga_write_register(ViPipe, 0x3011, 0x02); +// imx327_fpga_write_register(ViPipe, 0x3014, 0x16); // GAIN, 0x2A=>12.6dB TBD + imx327_fpga_write_register(ViPipe, 0x3014, 0x00); // GAIN, 0x0=>0 dB TBD + //imx327_fpga_write_register(ViPipe, 0x3016, 0x08); // [TODO] sony's secrect register? + imx327_fpga_write_register(ViPipe, 0x3018, 0xEE); // VMAX[7:0] TBD=750 + imx327_fpga_write_register(ViPipe, 0x3019, 0x02); // VMAX[15:8] + imx327_fpga_write_register(ViPipe, 0x301A, 0x00); // VMAX[17:16]:=:0x301A[1:0] +// imx327_fpga_write_register(ViPipe, 0x301C, 0xC8); // HMAX[7:0], TBD=6600 +// imx327_fpga_write_register(ViPipe, 0x301D, 0x19); // HMAX[15:8] + imx327_fpga_write_register(ViPipe, 0x301C, 0x58); // HMAX[7:0], TBD=19800 + imx327_fpga_write_register(ViPipe, 0x301D, 0x4D); // HMAX[15:8] +// imx327_fpga_write_register(ViPipe, 0x3020, 0x8C); // SHS[7:0], TBD +// imx327_fpga_write_register(ViPipe, 0x3021, 0x01); // SHS[15:8] +// imx327_fpga_write_register(ViPipe, 0x3022, 0x00); // SHS[19:16] + imx327_fpga_write_register(ViPipe, 0x3020, 0x00); // SHS[7:0], TBD + imx327_fpga_write_register(ViPipe, 0x3021, 0x01); // SHS[15:8] + imx327_fpga_write_register(ViPipe, 0x3022, 0x00); // SHS[19:16] + //imx327_fpga_write_register(ViPipe, 0x3024, 0x00); // SHS2[7:0], TBD + //imx327_fpga_write_register(ViPipe, 0x3025, 0x00); // SHS2[15:8] + //imx327_fpga_write_register(ViPipe, 0x3026, 0x00); // SHS2[19:16] + //imx327_fpga_write_register(ViPipe, 0x3030, 0x00); // RHS1[7:0], TBD + //imx327_fpga_write_register(ViPipe, 0x3031, 0x00); // RHS1[15:8] + //imx327_fpga_write_register(ViPipe, 0x3032, 0x00); // RHS1[19:16] + //imx327_fpga_write_register(ViPipe, 0x3045, 0x00); // DOLSCDEN [0] 1: pattern1 0: pattern2 + // DOLSYDINFOEN[1] 1: embed the id code into 4th of sync + // code. 0: disable + // HINFOEN [2] 1: insert id code after 4th sync code 0: disable + imx327_fpga_write_register(ViPipe, 0x3046, 0x00); + imx327_fpga_write_register(ViPipe, 0x304B, 0x0A); + imx327_fpga_write_register(ViPipe, 0x305C, 0x20); // INCKSEL1 + imx327_fpga_write_register(ViPipe, 0x305D, 0x00); // INCKSEL2 + imx327_fpga_write_register(ViPipe, 0x305E, 0x20); // INCKSEL3 + imx327_fpga_write_register(ViPipe, 0x305F, 0x01); // INCKSEL4 + imx327_fpga_write_register(ViPipe, 0x309E, 0x4A); + imx327_fpga_write_register(ViPipe, 0x309F, 0x4A); + imx327_fpga_write_register(ViPipe, 0x30D2, 0x19); + imx327_fpga_write_register(ViPipe, 0x30D7, 0x03); + //imx327_fpga_write_register(ViPipe, 0x3106, 0x00); //DOLHBFIXEN[7] 0: pattern1 1: pattern2 + imx327_fpga_write_register(ViPipe, 0x3129, 0x1D); + imx327_fpga_write_register(ViPipe, 0x313B, 0x61); + imx327_fpga_write_register(ViPipe, 0x315E, 0x1A); + imx327_fpga_write_register(ViPipe, 0x3164, 0x1A); + imx327_fpga_write_register(ViPipe, 0x317C, 0x12); + imx327_fpga_write_register(ViPipe, 0x31EC, 0x37); + imx327_fpga_write_register(ViPipe, 0x3405, 0x10); // Repetition + imx327_fpga_write_register(ViPipe, 0x3407, 0x01); // physical_lane_nl + imx327_fpga_write_register(ViPipe, 0x3414, 0x04); // opb_size_v + imx327_fpga_write_register(ViPipe, 0x3418, 0xD9); // y_out_size + imx327_fpga_write_register(ViPipe, 0x3419, 0x02); // y_out_size + imx327_fpga_write_register(ViPipe, 0x3441, 0x0A); // csi_dt_fmt + imx327_fpga_write_register(ViPipe, 0x3442, 0x0A); // csi_dt_fmt + imx327_fpga_write_register(ViPipe, 0x3443, 0x01); // csi_lane_mode + imx327_fpga_write_register(ViPipe, 0x3444, 0x20); // extck_freq + imx327_fpga_write_register(ViPipe, 0x3445, 0x25); // extck_freq + imx327_fpga_write_register(ViPipe, 0x3446, 0x4F); // tclkpost + imx327_fpga_write_register(ViPipe, 0x3447, 0x00); // tclkpost + imx327_fpga_write_register(ViPipe, 0x3448, 0x80); // thszero + imx327_fpga_write_register(ViPipe, 0x3449, 0x00); // thszero + imx327_fpga_write_register(ViPipe, 0x344A, 0x17); // thsprepare + imx327_fpga_write_register(ViPipe, 0x344B, 0x00); // thsprepare + imx327_fpga_write_register(ViPipe, 0x344C, 0x17); // tclktrail + imx327_fpga_write_register(ViPipe, 0x344D, 0x00); // tclktrail + imx327_fpga_write_register(ViPipe, 0x344E, 0x80); // thstrail + imx327_fpga_write_register(ViPipe, 0x344F, 0x00); // thstrail + imx327_fpga_write_register(ViPipe, 0x3450, 0x57); // tclkzero + imx327_fpga_write_register(ViPipe, 0x3451, 0x00); // tclkzero + imx327_fpga_write_register(ViPipe, 0x3452, 0x17); // tclkprepare + imx327_fpga_write_register(ViPipe, 0x3453, 0x00); // tckkprepare + imx327_fpga_write_register(ViPipe, 0x3454, 0x17); // tlpx + imx327_fpga_write_register(ViPipe, 0x3455, 0x00); // tlpx + imx327_fpga_write_register(ViPipe, 0x3472, 0x1C); // x_out_size + imx327_fpga_write_register(ViPipe, 0x3473, 0x05); // x_out_size + imx327_fpga_write_register(ViPipe, 0x3480, 0x49); // incksel7 + +// imx327_fpga_default_reg_init(ViPipe); + + imx327_fpga_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_fpga_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_fpga_write_register(ViPipe, 0x304b, 0x0a); + + printf("ViPipe:%d,===IMX327 720P 30fps 10bit LINE Init for FPGA OK!===\n", ViPipe); +} + +static void imx327_fpga_wdr_720p30_2to1_init(VI_PIPE ViPipe) +{ + imx327_fpga_write_register(ViPipe, 0x3003, 0x01); // SW Reset + delay_ms(3); + imx327_fpga_write_register(ViPipe, 0x3000, 0x01); // STANDBY + imx327_fpga_write_register(ViPipe, 0x3001, 0x00); // HOLD + imx327_fpga_write_register(ViPipe, 0x3002, 0x00); // XMSTA + imx327_fpga_write_register(ViPipe, 0x3005, 0x00); // ADBIT=10bit + imx327_fpga_write_register(ViPipe, 0x3007, 0x11); // VREVERS, ... + imx327_fpga_write_register(ViPipe, 0x3009, 0x02); // + imx327_fpga_write_register(ViPipe, 0x300A, 0x3C); // BLKLEVEL + imx327_fpga_write_register(ViPipe, 0x300C, 0x11); // WDMODE [0] 0:Normal, 1:DOL, WDSEL [5:4] 1:DOL 2 frames + imx327_fpga_write_register(ViPipe, 0x3011, 0x02); + imx327_fpga_write_register(ViPipe, 0x3014, 0x16); // GAIN, 0x2A=>12.6dB TBD + //imx327_fpga_write_register(ViPipe, 0x3016, 0x08); // [TODO] sony's secrect register? + imx327_fpga_write_register(ViPipe, 0x3018, 0xEE); // VMAX[7:0] + imx327_fpga_write_register(ViPipe, 0x3019, 0x02); // VMAX[15:8] + imx327_fpga_write_register(ViPipe, 0x301A, 0x00); // VMAX[17:16]:=:0x301A[1:0] + // imx327_fpga_write_register(ViPipe, 0x301C, 0xC8); // HMAX[7:0], TBD=6600 + // imx327_fpga_write_register(ViPipe, 0x301D, 0x19); // HMAX[15:8] + imx327_fpga_write_register(ViPipe, 0x301C, 0x58); // HMAX[7:0], TBD=19800 + imx327_fpga_write_register(ViPipe, 0x301D, 0x4D); // HMAX[15:8] + imx327_fpga_write_register(ViPipe, 0x3020, 0x02); // SHS[7:0], TBD + imx327_fpga_write_register(ViPipe, 0x3021, 0x00); // SHS[15:8] + imx327_fpga_write_register(ViPipe, 0x3022, 0x00); // SHS[19:16] + imx327_fpga_write_register(ViPipe, 0x3024, 0x1B); // SHS2[7:0], TBD + imx327_fpga_write_register(ViPipe, 0x3025, 0x05); // SHS2[15:8] + imx327_fpga_write_register(ViPipe, 0x3026, 0x00); // SHS2[19:16] + imx327_fpga_write_register(ViPipe, 0x3030, 0x09); // RHS1[7:0], TBD + imx327_fpga_write_register(ViPipe, 0x3031, 0x00); // RHS1[15:8] + imx327_fpga_write_register(ViPipe, 0x3032, 0x00); // RHS1[19:16] + imx327_fpga_write_register(ViPipe, 0x3045, 0x05); // DOLSCDEN [0] 1: pattern1 0: pattern2 + // DOLSYDINFOEN[1] 1: embed the id code into 4th of sync + // code. 0: disable + // HINFOEN [2] 1: insert id code after 4th sync code 0: disable + imx327_fpga_write_register(ViPipe, 0x3046, 0x00); + imx327_fpga_write_register(ViPipe, 0x304B, 0x0A); + imx327_fpga_write_register(ViPipe, 0x305C, 0x20); // INCKSEL1 + imx327_fpga_write_register(ViPipe, 0x305D, 0x00); // INCKSEL2 + imx327_fpga_write_register(ViPipe, 0x305E, 0x20); // INCKSEL3 + imx327_fpga_write_register(ViPipe, 0x305F, 0x01); // INCKSEL4 + imx327_fpga_write_register(ViPipe, 0x309E, 0x4A); + imx327_fpga_write_register(ViPipe, 0x309F, 0x4A); + imx327_fpga_write_register(ViPipe, 0x30D2, 0x19); + imx327_fpga_write_register(ViPipe, 0x30D7, 0x03); + imx327_fpga_write_register(ViPipe, 0x3106, 0x11); //DOLHBFIXEN[7] 0: pattern1 1: pattern2 + imx327_fpga_write_register(ViPipe, 0x3129, 0x1D); + imx327_fpga_write_register(ViPipe, 0x313B, 0x61); + imx327_fpga_write_register(ViPipe, 0x315E, 0x1A); + imx327_fpga_write_register(ViPipe, 0x3164, 0x1A); + imx327_fpga_write_register(ViPipe, 0x317C, 0x12); + imx327_fpga_write_register(ViPipe, 0x31EC, 0x37); + imx327_fpga_write_register(ViPipe, 0x3405, 0x10); // Repetition + imx327_fpga_write_register(ViPipe, 0x3407, 0x01); // physical_lane_nl + imx327_fpga_write_register(ViPipe, 0x3414, 0x04); // opb_size_v + imx327_fpga_write_register(ViPipe, 0x3415, 0x00); // NULL0_SIZE_V, set to 00h when DOL + imx327_fpga_write_register(ViPipe, 0x3418, 0xC6); // y_out_size + imx327_fpga_write_register(ViPipe, 0x3419, 0x05); // y_out_size + imx327_fpga_write_register(ViPipe, 0x3441, 0x0A); // csi_dt_fmt + imx327_fpga_write_register(ViPipe, 0x3442, 0x0A); // csi_dt_fmt + imx327_fpga_write_register(ViPipe, 0x3443, 0x01); // csi_lane_mode + imx327_fpga_write_register(ViPipe, 0x3444, 0x20); // extck_freq + imx327_fpga_write_register(ViPipe, 0x3445, 0x25); // extck_freq + imx327_fpga_write_register(ViPipe, 0x3446, 0x4F); // tclkpost + imx327_fpga_write_register(ViPipe, 0x3447, 0x00); // tclkpost + imx327_fpga_write_register(ViPipe, 0x3448, 0x80); // thszero + imx327_fpga_write_register(ViPipe, 0x3449, 0x00); // thszero + imx327_fpga_write_register(ViPipe, 0x344A, 0x17); // thsprepare + imx327_fpga_write_register(ViPipe, 0x344B, 0x00); // thsprepare + imx327_fpga_write_register(ViPipe, 0x344C, 0x17); // tclktrail + imx327_fpga_write_register(ViPipe, 0x344D, 0x00); // tclktrail + imx327_fpga_write_register(ViPipe, 0x344E, 0x80); // thstrail + imx327_fpga_write_register(ViPipe, 0x344F, 0x00); // thstrail + imx327_fpga_write_register(ViPipe, 0x3450, 0x57); // tclkzero + imx327_fpga_write_register(ViPipe, 0x3451, 0x00); // tclkzero + imx327_fpga_write_register(ViPipe, 0x3452, 0x17); // tclkprepare + imx327_fpga_write_register(ViPipe, 0x3453, 0x00); // tckkprepare + imx327_fpga_write_register(ViPipe, 0x3454, 0x17); // tlpx + imx327_fpga_write_register(ViPipe, 0x3455, 0x00); // tlpx + imx327_fpga_write_register(ViPipe, 0x3472, 0x20); // x_out_size + imx327_fpga_write_register(ViPipe, 0x3473, 0x05); // x_out_size + imx327_fpga_write_register(ViPipe, 0x347B, 0x23); // + imx327_fpga_write_register(ViPipe, 0x3480, 0x49); // incksel7 + + delay_ms(20); // delay + imx327_fpga_write_register(ViPipe, 0x3000, 0x00); // STANDBY + imx327_fpga_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_fpga_write_register(ViPipe, 0x304b, 0x0a); + + printf("===Imx327 sensor 720P15fps 10bit 2to1 WDR(30fps->15fps) init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_slave/Makefile b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_slave/Makefile new file mode 100644 index 000000000..95045e73c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_slave/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx327_slave.a +TARGET_SO = $(MW_LIB)/libsns_imx327_slave.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_slave/imx327_slave_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_slave/imx327_slave_cmos.c new file mode 100644 index 000000000..46b7483c3 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_slave/imx327_slave_cmos.c @@ -0,0 +1,1198 @@ +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "imx327_slave_cmos_ex.h" +#include "imx327_slave_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX327_SLAVE_ID 327 +#define SENSOR_IMX327_SLAVE_WIDTH 1920 +#define SENSOR_IMX327_SLAVE_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx327_Slave[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX327_SLAVE_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx327_Slave[dev]) +#define IMX327_SLAVE_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx327_Slave[dev] = pstCtx) +#define IMX327_SLAVE_SENSOR_RESET_CTX(dev) (g_pastImx327_Slave[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunImx327_Slave_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx327_Slave_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Imx327_Slave_UseHwSync[VI_MAX_PIPE_NUM] = {0}; + +IMX327_SLAVE_STATE_S g_astImx327_Slave_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx327_Slave_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx327 Lines Range*****/ +#define IMX327_SLAVE_FULL_LINES_MAX (0x3FFFF) +#define IMX327_SLAVE_FULL_LINES_MAX_2TO1_WDR (0x3FFFF) // considering the YOUT_SIZE and bad frame +#define IMX327_SLAVE_VMAX_1080P30_LINEAR 1125 + +/*****Imx327 Register Address*****/ +#define IMX327_SLAVE_HOLD_ADDR 0x3001 +#define IMX327_SLAVE_SHS1_ADDR 0x3020 +#define IMX327_SLAVE_SHS2_ADDR 0x3024 +#define IMX327_SLAVE_GAIN_ADDR 0x3014 +#define IMX327_SLAVE_GAIN1_ADDR 0x30F2 +#define IMX327_SLAVE_HCG_ADDR 0x3009 +#define IMX327_SLAVE_VMAX_ADDR 0x3018 +#define IMX327_SLAVE_YOUT_ADDR 0x3418 +#define IMX327_SLAVE_RHS1_ADDR 0x3030 +#define IMX327_SLAVE_TABLE_END 0xffff + +#define IMX327_SLAVE_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX327_SLAVE_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astImx327_Slave_mode[IMX327_SLAVE_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_Slave_mode[IMX327_SLAVE_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astImx327_Slave_mode[IMX327_SLAVE_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_Slave_mode[IMX327_SLAVE_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = IMX327_SLAVE_VMAX_1080P30_LINEAR; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case IMX327_SLAVE_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_SLAVE_FULL_LINES_MAX_2TO1_WDR) ? + IMX327_SLAVE_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case IMX327_SLAVE_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_SLAVE_FULL_LINES_MAX) ? IMX327_SLAVE_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } else { + pstSnsRegsInfo->astI2cData[DOL2_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx327_Slave_State[ViPipe].u32RHS1_MAX = + (u32VMAX - g_astImx327_Slave_State[ViPipe].u32BRL) * 2 - 21; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHS1 = 0; + CVI_U32 u32SHS2 = 0; + CVI_U32 u32YOUTSIZE; + CVI_U32 u16BRL = 0; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u16BRL = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].u16BRL; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[0] < u32LongIntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], u32LongIntTime - 1); + return CVI_FAILURE; + } + u32SHS2 = pstSnsState->au32FL[0] - u32LongIntTime - 1; + + u32SHS1 = (u32ShortIntTime % 2) + 2; + u32RHS1 = u32ShortIntTime + u32SHS1 + 1; + g_astImx327_Slave_State[ViPipe].u32RHS1 = u32RHS1; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - (u32SHS1 + 1); + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[0] - (u32SHS2 + 1); + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + u32YOUTSIZE = (u16BRL + (u32RHS1 - 1) / 2) * 2; + u32YOUTSIZE = (u32YOUTSIZE >= 0x1FFF) ? 0x1FFF : u32YOUTSIZE; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHS1 = %d\n", u32ShortIntTime, u32SHS1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d u32YOUTSIZE = %d\n", ViPipe, u32RHS1, u32YOUTSIZE); + + pstSnsRegsInfo->astI2cData[DOL2_SHS1_0].u32Data = (u32SHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_1].u32Data = ((u32SHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_2].u32Data = ((u32SHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHS2_0].u32Data = (u32SHS2 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_1].u32Data = ((u32SHS2 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_2].u32Data = ((u32SHS2 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_0].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_1].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_2].u32Data = ((u32RHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_0].u32Data = (u32YOUTSIZE & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_1].u32Data = ((u32YOUTSIZE & 0x1F00) >> 8); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if (pstSnsState->au32FL[0] < *u32IntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], *u32IntTime - 1); + return CVI_FAILURE; + } + u32Value = pstSnsState->au32FL[0] - *u32IntTime - 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2].u32Data = ((u32Value & 0x30000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 327567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32HCG = g_astImx327_Slave_State[ViPipe].u8Hcg; + CVI_U32 u16Mode = g_au16Imx327_Slave_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = (u32HCG & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + CVI_U8 bEnableHCG = 0; + + if (pu32Again[0] >= 20 && pu32Again[1] >= 20) { + /* hcg bit[4]*/ + u32HCG |= 0x10; + bEnableHCG = 1; + } + + u32Again = pu32Again[1] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + + u32Again = pu32Again[0] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN1].u32Data = (u32Tmp & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + if (u32HCG > 0xFF) { + u32HCG = 0xFF; + } + + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 2 : 2; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 10; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx327_Slave_State[ViPipe].u32RHS1_MAX - 3)) ? + (g_astImx327_Slave_State[ViPipe].u32RHS1_MAX - 3) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX327_SLAVE_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx327_Slave_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX327_SLAVE_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = IMX327_SLAVE_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].u32VtsDef; + g_astImx327_Slave_State[ViPipe].u8Hcg = 0x2; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX327_SLAVE_MODE_1080P30) + pstSnsState->u8ImgMode = IMX327_SLAVE_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + g_astImx327_Slave_State[ViPipe].u8Hcg = 0x1; + if (pstSnsState->u8ImgMode == IMX327_SLAVE_MODE_1080P30_WDR) { + pstSnsState->u32FLStd = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx327_Slave_State[ViPipe].u32BRL = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1080p\n"); + } + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx327_Slave_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx327_slave_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx327_slave_addr_byte; + pstI2c_data[i].u32DataByteNum = imx327_slave_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_HOLD].u32RegAddr = IMX327_SLAVE_HOLD_ADDR; + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_SHS1_0].u32RegAddr = IMX327_SLAVE_SHS1_ADDR; + pstI2c_data[DOL2_SHS1_1].u32RegAddr = IMX327_SLAVE_SHS1_ADDR + 1; + pstI2c_data[DOL2_SHS1_2].u32RegAddr = IMX327_SLAVE_SHS1_ADDR + 2; + + pstI2c_data[DOL2_GAIN].u32RegAddr = IMX327_SLAVE_GAIN_ADDR; + pstI2c_data[DOL2_HCG].u32RegAddr = IMX327_SLAVE_HCG_ADDR; + pstI2c_data[DOL2_HCG].u8DelayFrmNum = 1; + pstI2c_data[DOL2_GAIN1].u32RegAddr = IMX327_SLAVE_GAIN1_ADDR; + pstI2c_data[DOL2_RHS1_0].u32RegAddr = IMX327_SLAVE_RHS1_ADDR; + pstI2c_data[DOL2_RHS1_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_1].u32RegAddr = IMX327_SLAVE_RHS1_ADDR + 1; + pstI2c_data[DOL2_RHS1_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_2].u32RegAddr = IMX327_SLAVE_RHS1_ADDR + 2; + pstI2c_data[DOL2_RHS1_2].u8DelayFrmNum = 1; + pstI2c_data[DOL2_SHS2_0].u32RegAddr = IMX327_SLAVE_SHS2_ADDR; + pstI2c_data[DOL2_SHS2_1].u32RegAddr = IMX327_SLAVE_SHS2_ADDR + 1; + pstI2c_data[DOL2_SHS2_2].u32RegAddr = IMX327_SLAVE_SHS2_ADDR + 2; + pstI2c_data[DOL2_VMAX_0].u32RegAddr = IMX327_SLAVE_VMAX_ADDR; + pstI2c_data[DOL2_VMAX_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_1].u32RegAddr = IMX327_SLAVE_VMAX_ADDR + 1; + pstI2c_data[DOL2_VMAX_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_2].u32RegAddr = IMX327_SLAVE_VMAX_ADDR + 2; + pstI2c_data[DOL2_VMAX_2].u8DelayFrmNum = 1; + + pstI2c_data[DOL2_YOUT_SIZE_0].u32RegAddr = IMX327_SLAVE_YOUT_ADDR; + pstI2c_data[DOL2_YOUT_SIZE_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u32RegAddr = IMX327_SLAVE_YOUT_ADDR + 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_REL].u32RegAddr = IMX327_SLAVE_HOLD_ADDR; + pstI2c_data[DOL2_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 1; + break; + default: + pstI2c_data[LINEAR_HOLD].u32RegAddr = IMX327_SLAVE_HOLD_ADDR; + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_SHS1_0].u32RegAddr = IMX327_SLAVE_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1].u32RegAddr = IMX327_SLAVE_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2].u32RegAddr = IMX327_SLAVE_SHS1_ADDR + 2; + pstI2c_data[LINEAR_GAIN].u32RegAddr = IMX327_SLAVE_GAIN_ADDR; + pstI2c_data[LINEAR_HCG].u32RegAddr = IMX327_SLAVE_HCG_ADDR; + pstI2c_data[LINEAR_HCG].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VMAX_0].u32RegAddr = IMX327_SLAVE_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1].u32RegAddr = IMX327_SLAVE_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_2].u32RegAddr = IMX327_SLAVE_VMAX_ADDR + 2; + pstI2c_data[LINEAR_REL].u32RegAddr = IMX327_SLAVE_HOLD_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[DOL2_REL].u32Data = 0; + pstI2c_data[DOL2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX327_SLAVE_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_SLAVE_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX327_SLAVE_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_SLAVE_MODE_1080P30_WDR; + g_astImx327_Slave_State[ViPipe].u32BRL = 1109; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx327_Slave_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx327_slave_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx327_Slave_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = IMX327_SLAVE_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = IMX327_SLAVE_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[0] = IMX327_SLAVE_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[1] = IMX327_SLAVE_VMAX_1080P30_LINEAR; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx327_slave_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx327_slave_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx327_slave_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx327_slave_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx327_slave_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx327_Slave_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX327_SLAVE_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX327_SLAVE_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX327_SLAVE_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX327_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX327_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX327_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx327_Slave_UseHwSync[ViPipe] = pstInitAttr->u16UseHwSync; + g_au16Imx327_Slave_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return imx327_slave_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsImx327_Slave_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx327_slave_standby, + .pfnRestart = imx327_slave_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx327_slave_write_register, + .pfnReadReg = imx327_slave_read_register, + .pfnSetBusInfo = imx327_slave_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_slave/imx327_slave_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_slave/imx327_slave_cmos_ex.h new file mode 100644 index 000000000..c561542b5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_slave/imx327_slave_cmos_ex.h @@ -0,0 +1,116 @@ +#ifndef __IMX327_SLAVE_CMOS_EX_H_ +#define __IMX327_SLAVE_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +enum imx327_slave_linear_regs_e { + LINEAR_HOLD = 0, + LINEAR_SHS1_0, + LINEAR_SHS1_1, + LINEAR_SHS1_2, + LINEAR_GAIN, + LINEAR_HCG, + LINEAR_VMAX_0, + LINEAR_VMAX_1, + LINEAR_VMAX_2, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum imx327_slave_dol2_regs_e { + DOL2_HOLD = 0, + DOL2_SHS1_0, + DOL2_SHS1_1, + DOL2_SHS1_2, + DOL2_GAIN, + DOL2_HCG, + DOL2_GAIN1, + DOL2_RHS1_0, + DOL2_RHS1_1, + DOL2_RHS1_2, + DOL2_SHS2_0, + DOL2_SHS2_1, + DOL2_SHS2_2, + DOL2_VMAX_0, + DOL2_VMAX_1, + DOL2_VMAX_2, + DOL2_YOUT_SIZE_0, + DOL2_YOUT_SIZE_1, + DOL2_REL, + DOL2_REGS_NUM +}; + +typedef enum _IMX327_SLAVE_MODE_E { + IMX327_SLAVE_MODE_1080P30 = 0, + IMX327_SLAVE_MODE_LINEAR_NUM, + IMX327_SLAVE_MODE_1080P30_WDR = IMX327_SLAVE_MODE_LINEAR_NUM, + IMX327_SLAVE_MODE_NUM +} IMX327_SLAVE_MODE_E; + +typedef struct _IMX327_SLAVE_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX327_SLAVE_STATE_S; + +typedef struct _IMX327_SLAVE_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX327_SLAVE_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx327_Slave[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx327_Slave_BusInfo[]; +extern CVI_U16 g_au16Imx327_Slave_GainMode[]; +extern CVI_U16 g_au16Imx327_Slave_UseHwSync[]; +extern const CVI_U8 imx327_slave_i2c_addr; +extern const CVI_U32 imx327_slave_addr_byte; +extern const CVI_U32 imx327_slave_data_byte; +extern void imx327_slave_init(VI_PIPE ViPipe); +extern void imx327_slave_exit(VI_PIPE ViPipe); +extern void imx327_slave_standby(VI_PIPE ViPipe); +extern void imx327_slave_restart(VI_PIPE ViPipe); +extern int imx327_slave_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx327_slave_read_register(VI_PIPE ViPipe, int addr); +extern void imx327_slave_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int imx327_slave_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_SLAVE_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_slave/imx327_slave_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_slave/imx327_slave_cmos_param.h new file mode 100644 index 000000000..5977e6755 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_slave/imx327_slave_cmos_param.h @@ -0,0 +1,417 @@ +#ifndef __IMX327_SLAVE_CMOS_PARAM_H_ +#define __IMX327_SLAVE_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_slave_cmos_ex.h" + +static const IMX327_SLAVE_MODE_S g_astImx327_Slave_mode[IMX327_SLAVE_MODE_NUM] = { + [IMX327_SLAVE_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x1130, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX327_SLAVE_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 8, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 2236, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 7, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, +}; + +// F1.8 Lens +#ifdef F18 +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = { + /*************Calibration LUT Table*************/ + .CalibrationCoef = { + { //iso 100 + {0.03243722766637802, 3.855583906173706}, //B: slope, intercept + {0.024103811010718346, 3.9538209438323975}, //Gb: slope, intercept + {0.022307759150862694, 4.970882892608643}, //Gr: slope, intercept + {0.02794046327471733, 3.1342978477478027}, //R: slope, intercept + }, + { //iso 200 + {0.03799639642238617, 5.526010990142822}, //B: slope, intercept + {0.02662081830203533, 7.61380672454834}, //Gb: slope, intercept + {0.025447502732276917, 8.231551170349121}, //Gr: slope, intercept + {0.032776281237602234, 5.149646282196045}, //R: slope, intercept + }, + { //iso 400 + {0.050715841352939606, 7.763713836669922}, //B: slope, intercept + {0.032093651592731476, 12.182195663452148}, //Gb: slope, intercept + {0.030688125640153885, 12.43420696258545}, //Gr: slope, intercept + {0.040235333144664764, 8.544824600219727}, //R: slope, intercept + }, + { //iso 800 + {0.06888508796691895, 10.970534324645996}, //B: slope, intercept + {0.03813415393233299, 19.28471565246582}, //Gb: slope, intercept + {0.03805641457438469, 19.625152587890625}, //Gr: slope, intercept + {0.04966627061367035, 12.69924545288086}, //R: slope, intercept + }, + { //iso 1600 + {0.08884920179843903, 15.890214920043945}, //B: slope, intercept + {0.046779610216617584, 30.772066116333008}, //Gb: slope, intercept + {0.045214589685201645, 31.489530563354492}, //Gr: slope, intercept + {0.06512749195098877, 20.34792137145996}, //R: slope, intercept + }, + { //iso 3200 + {0.1241341084241867, 20.70075225830078}, //B: slope, intercept + {0.05977431312203407, 45.98811721801758}, //Gb: slope, intercept + {0.05858884006738663, 47.11114501953125}, //Gr: slope, intercept + {0.08636551350355148, 30.561227798461914}, //R: slope, intercept + }, + { //iso 6400 + {0.1791478991508484, 30.803356170654297}, //B: slope, intercept + {0.09205856174230576, 65.60118103027344}, //Gb: slope, intercept + {0.08692053705453873, 69.85540771484375}, //Gr: slope, intercept + {0.12406758964061737, 45.617835998535156}, //R: slope, intercept + }, + { //iso 12800 + {0.2464703917503357, 44.136966705322266}, //B: slope, intercept + {0.11594483256340027, 97.8382797241211}, //Gb: slope, intercept + {0.11075824499130249, 101.47943115234375}, //Gr: slope, intercept + {0.17024046182632446, 66.47021484375}, //R: slope, intercept + }, + { //iso 25600 + {0.3376912772655487, 68.80254364013672}, //B: slope, intercept + {0.15025299787521362, 145.10032653808594}, //Gb: slope, intercept + {0.14386454224586487, 148.1698455810547}, //Gr: slope, intercept + {0.23965470492839813, 96.42337036132812}, //R: slope, intercept + }, + { //iso 51200 + {0.4279725253582001, 117.4070816040039}, //B: slope, intercept + {0.17134547233581543, 243.6494598388672}, //Gb: slope, intercept + {0.16668814420700073, 241.21603393554688}, //Gr: slope, intercept + {0.29862311482429504, 156.05364990234375}, //R: slope, intercept + }, + { //iso 102400 + {0.534967303276062, 181.45118713378906}, //B: slope, intercept + {0.2024478018283844, 365.00177001953125}, //Gb: slope, intercept + {0.20520392060279846, 362.1013488769531}, //Gr: slope, intercept + {0.40533769130706787, 241.33485412597656}, //R: slope, intercept + }, + { //iso 204800 + {0.6578512191772461, 286.16363525390625}, //B: slope, intercept + {0.223756805062294, 551.998779296875}, //Gb: slope, intercept + {0.22110669314861298, 562.9724731445312}, //Gr: slope, intercept + {0.4937806725502014, 371.5768737792969}, //R: slope, intercept + }, + { //iso 409600 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + //------------------------------------------------------------- + { //iso 819200 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + { //iso 1638400 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + { //iso 3276800 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + } + /*********************************************/ +}; +#endif + +// F1.0 Lens +#ifdef F10 +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.038478557020425796517, 2.14561891555786132813}, //B: slope, intercept + {0.03633839637041091919, 0.17788629233837127686}, //Gb: slope, intercept + {0.03592018783092498779, 0.21645727753639221191}, //Gr: slope, intercept + {0.03592239692807197571, 1.48806631565093994141}, //R: slope, intercept + }, + { //iso 200 + {0.04168356582522392273, 4.38879251480102539063}, //B: slope, intercept + {0.03754633292555809021, 3.21502065658569335938}, //Gb: slope, intercept + {0.03759334236383438110, 3.48370814323425292969}, //Gr: slope, intercept + {0.03719408065080642700, 4.63629007339477539063}, //R: slope, intercept + }, + { //iso 400 + {0.05050259083509445190, 6.85188436508178710938}, //B: slope, intercept + {0.04007886722683906555, 8.49916744232177734375}, //Gb: slope, intercept + {0.03934165090322494507, 8.68585968017578125000}, //Gr: slope, intercept + {0.04134147986769676208, 8.89877605438232421875}, //R: slope, intercept + }, + { //iso 800 + {0.04306267201900482178, 15.41853904724121093750}, //B: slope, intercept + {0.03570587188005447388, 18.56583213806152343750}, //Gb: slope, intercept + {0.03533876314759254456, 19.57685661315917968750}, //Gr: slope, intercept + {0.03832129389047622681, 17.90320968627929687500}, //R: slope, intercept + }, + { //iso 1600 + {0.06225715205073356628, 21.87150573730468750000}, //B: slope, intercept + {0.04437549784779548645, 30.87298965454101562500}, //Gb: slope, intercept + {0.04517432302236557007, 29.32084465026855468750}, //Gr: slope, intercept + {0.05255207046866416931, 26.26001358032226562500}, //R: slope, intercept + }, + { //iso 3200 + {0.07859147340059280396, 32.48978424072265625000}, //B: slope, intercept + {0.05918205901980400085, 45.08999633789062500000}, //Gb: slope, intercept + {0.05711782723665237427, 48.86173248291015625000}, //Gr: slope, intercept + {0.07310666143894195557, 36.88227081298828125000}, //R: slope, intercept + }, + { //iso 6400 + {0.11759266257286071777, 45.81345367431640625000}, //B: slope, intercept + {0.07679814100265502930, 69.04325866699218750000}, //Gb: slope, intercept + {0.07774948328733444214, 66.52905273437500000000}, //Gr: slope, intercept + {0.10286796092987060547, 51.73817443847656250000}, //R: slope, intercept + }, + { //iso 12800 + {0.15860086679458618164, 64.15329742431640625000}, //B: slope, intercept + {0.10511043667793273926, 91.36695098876953125000}, //Gb: slope, intercept + {0.10040879994630813599, 92.05632781982421875000}, //Gr: slope, intercept + {0.13499946892261505127, 73.36162567138671875000}, //R: slope, intercept + }, + { //iso 25600 + {0.22810073196887969971, 100.01741027832031250000}, //B: slope, intercept + {0.14736327528953552246, 146.62678527832031250000}, //Gb: slope, intercept + {0.15503610670566558838, 136.06079101562500000000}, //Gr: slope, intercept + {0.20250190794467926025, 112.74269104003906250000}, //R: slope, intercept + }, + { //iso 51200 + {0.29010805487632751465, 155.05882263183593750000}, //B: slope, intercept + {0.20221179723739624023, 210.97210693359375000000}, //Gb: slope, intercept + {0.21603405475616455078, 201.40393066406250000000}, //Gr: slope, intercept + {0.27819159626960754395, 165.48959350585937500000}, //R: slope, intercept + }, + { //iso 102400 + {0.40437409281730651855, 245.11883544921875000000}, //B: slope, intercept + {0.26703724265098571777, 345.62698364257812500000}, //Gb: slope, intercept + {0.27536261081695556641, 318.75701904296875000000}, //Gr: slope, intercept + {0.44441288709640502930, 222.47651672363281250000}, //R: slope, intercept + }, + { //iso 204800 + {0.48959052562713623047, 383.21560668945312500000}, //B: slope, intercept + {0.37694901227951049805, 442.55813598632812500000}, //Gb: slope, intercept + {0.38724529743194580078, 449.72384643554687500000}, //Gr: slope, intercept + {0.60220617055892944336, 318.92291259765625000000}, //R: slope, intercept + }, + { //iso 409600 + {0.59899300336837768555, 580.43414306640625000000}, //B: slope, intercept + {0.43681395053863525391, 700.22204589843750000000}, //Gb: slope, intercept + {0.50216537714004516602, 633.89794921875000000000}, //Gr: slope, intercept + {0.77917146682739257813, 453.13076782226562500000}, //R: slope, intercept + }, + { //iso 819200 + {0.54956322908401489258, 871.06585693359375000000}, //B: slope, intercept + {0.38088488578796386719, 1040.72192382812500000000}, //Gb: slope, intercept + {0.47245877981185913086, 937.37445068359375000000}, //Gr: slope, intercept + {0.70387065410614013672, 730.45373535156250000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.67512661218643188477, 797.11108398437500000000}, //B: slope, intercept + {0.50457936525344848633, 962.40740966796875000000}, //Gb: slope, intercept + {0.59857457876205444336, 856.90533447265625000000}, //Gr: slope, intercept + {0.74725526571273803711, 740.04290771484375000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.79927802085876464844, 687.07183837890625000000}, //B: slope, intercept + {0.81719654798507690430, 687.01580810546875000000}, //Gb: slope, intercept + {0.83395677804946899414, 658.91857910156250000000}, //Gr: slope, intercept + {0.72803622484207153320, 746.19427490234375000000}, //R: slope, intercept + }, +} }; +#endif + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {240, 240, 240, 240, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1088, 1088, 1088, 1088 +#endif + }, + .stAuto = { + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, +#endif + }, + }, +}; + +struct combo_dev_attr_s imx327_slave_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {4, 3, 5, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_DOL, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 1, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_SLAVE_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_slave/imx327_slave_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_slave/imx327_slave_sensor_ctl.c new file mode 100644 index 000000000..54d461abf --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_slave/imx327_slave_sensor_ctl.c @@ -0,0 +1,421 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_slave_cmos_ex.h" + +static void imx327_slave_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void imx327_slave_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 imx327_slave_i2c_addr = 0x1A; +const CVI_U32 imx327_slave_addr_byte = 2; +const CVI_U32 imx327_slave_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx327_slave_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx327_Slave_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx327_slave_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int imx327_slave_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx327_slave_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (imx327_slave_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, imx327_slave_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, imx327_slave_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (imx327_slave_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int imx327_slave_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx327_slave_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx327_slave_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx327_slave_addr_byte + imx327_slave_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx327_slave_standby(VI_PIPE ViPipe) +{ + imx327_slave_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ +} + +void imx327_slave_restart(VI_PIPE ViPipe) +{ + imx327_slave_write_register(ViPipe, 0x3000, 0x00); /* standby */ +} + +void imx327_slave_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx327_Slave[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx327_slave_write_register(ViPipe, + g_pastImx327_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx327_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define IMX327_CHIP_ID_ADDR 0x31dc +#define IMX327_CHIP_ID 0x6 +#define IMX327_CHIP_ID_MASK 0x6 + +void imx327_slave_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = imx327_slave_read_register(ViPipe, 0x3007) & ~0x3; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + imx327_slave_write_register(ViPipe, 0x3007, val); +} + +int imx327_slave_probe(VI_PIPE ViPipe) +{ + int nVal; + + usleep(100); + if (imx327_slave_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = imx327_slave_read_register(ViPipe, IMX327_CHIP_ID_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((nVal & IMX327_CHIP_ID_MASK) != IMX327_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void imx327_slave_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastImx327_Slave[ViPipe]->enWDRMode; + u8ImgMode = g_pastImx327_Slave[ViPipe]->u8ImgMode; + + imx327_slave_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == IMX327_SLAVE_MODE_1080P30_WDR) { + imx327_slave_wdr_1080p30_2to1_init(ViPipe); + } + } else { + imx327_slave_linear_1080p30_init(ViPipe); + } + g_pastImx327_Slave[ViPipe]->bInit = CVI_TRUE; +} + +void imx327_slave_exit(VI_PIPE ViPipe) +{ + imx327_slave_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void imx327_slave_linear_1080p30_init(VI_PIPE ViPipe) +{ + imx327_slave_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_slave_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_slave_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx327_slave_write_register(ViPipe, 0x3005, 0x01); /* ADBIT 10bit*/ + imx327_slave_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx327_slave_write_register(ViPipe, 0x3009, 0x02); /**/ + imx327_slave_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx327_slave_write_register(ViPipe, 0x3010, 0x21); + imx327_slave_write_register(ViPipe, 0x3011, 0x02); + imx327_slave_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx327_slave_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx327_slave_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx327_slave_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx327_slave_write_register(ViPipe, 0x301C, 0x30); /* HMAX[7:0], TBD*/ + imx327_slave_write_register(ViPipe, 0x301D, 0x11); /* HMAX[15:8]*/ + imx327_slave_write_register(ViPipe, 0x3020, 0x8C); /* SHS[7:0], TBD*/ + imx327_slave_write_register(ViPipe, 0x3021, 0x01); /* SHS[15:8]*/ + imx327_slave_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx327_slave_write_register(ViPipe, 0x3046, 0x01); + imx327_slave_write_register(ViPipe, 0x304B, 0x00); + imx327_slave_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx327_slave_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx327_slave_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx327_slave_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx327_slave_write_register(ViPipe, 0x309E, 0x4A); + imx327_slave_write_register(ViPipe, 0x309F, 0x4A); + imx327_slave_write_register(ViPipe, 0x30D2, 0x19); + imx327_slave_write_register(ViPipe, 0x30D7, 0x03); + imx327_slave_write_register(ViPipe, 0x3129, 0x00); + imx327_slave_write_register(ViPipe, 0x313B, 0x61); + imx327_slave_write_register(ViPipe, 0x315E, 0x1A); + imx327_slave_write_register(ViPipe, 0x3164, 0x1A); + imx327_slave_write_register(ViPipe, 0x317C, 0x00); + imx327_slave_write_register(ViPipe, 0x31EC, 0x0E); + imx327_slave_write_register(ViPipe, 0x3405, 0x10); /* Repetition*/ + imx327_slave_write_register(ViPipe, 0x3407, 0x01); /* physical_lane_nl*/ + imx327_slave_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx327_slave_write_register(ViPipe, 0x3418, 0x49); /* y_out_size*/ + imx327_slave_write_register(ViPipe, 0x3419, 0x04); /* y_out_size*/ + imx327_slave_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx327_slave_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx327_slave_write_register(ViPipe, 0x3443, 0x01); /* csi_lane_mode*/ + imx327_slave_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx327_slave_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx327_slave_write_register(ViPipe, 0x3446, 0x57); /* tclkpost*/ + imx327_slave_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + //imx327_slave_write_register(ViPipe, 0x3448, 0x37); /* thszero*/ + imx327_slave_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx327_slave_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx327_slave_write_register(ViPipe, 0x344A, 0x1F); /* thsprepare*/ + imx327_slave_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx327_slave_write_register(ViPipe, 0x344C, 0x1F); /* tclktrail*/ + imx327_slave_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + //imx327_slave_write_register(ViPipe, 0x344E, 0x1F); /* thstrail*/ + imx327_slave_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx327_slave_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx327_slave_write_register(ViPipe, 0x3450, 0x77); /* tclkzero*/ + imx327_slave_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx327_slave_write_register(ViPipe, 0x3452, 0x1F); /* tclkprepare*/ + imx327_slave_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx327_slave_write_register(ViPipe, 0x3454, 0x17); /* tlpx*/ + imx327_slave_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx327_slave_write_register(ViPipe, 0x3472, 0x9C); /* x_out_size*/ + imx327_slave_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx327_slave_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx327_slave_default_reg_init(ViPipe); + + imx327_slave_write_register(ViPipe, 0x3000, 0x00); /* standby */ + + if (!g_au16Imx327_Slave_UseHwSync[ViPipe]) { + delay_ms(20); + imx327_slave_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_slave_write_register(ViPipe, 0x304b, 0x0a); + } + + printf("ViPipe:%d,===IMX327 1080P 30fps 12bit LINE Slave Init OK!===\n", ViPipe); +} + +static void imx327_slave_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + imx327_slave_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_slave_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_slave_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx327_slave_write_register(ViPipe, 0x3005, 0x01); /* ADBIT*/ + imx327_slave_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx327_slave_write_register(ViPipe, 0x3009, 0x01); /**/ + imx327_slave_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx327_slave_write_register(ViPipe, 0x300C, 0x11); /* WDMODE [0] 0:Normal, 1:DOL, WDSEL [5:4] 1:DOL 2 frames*/ + imx327_slave_write_register(ViPipe, 0x3011, 0x02); + imx327_slave_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx327_slave_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx327_slave_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx327_slave_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx327_slave_write_register(ViPipe, 0x301C, 0x98); /* HMAX[7:0], TBD*/ + imx327_slave_write_register(ViPipe, 0x301D, 0x08); /* HMAX[15:8]*/ + imx327_slave_write_register(ViPipe, 0x3020, 0x02); /* SHS[7:0], TBD*/ + imx327_slave_write_register(ViPipe, 0x3021, 0x00); /* SHS[15:8]*/ + imx327_slave_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx327_slave_write_register(ViPipe, 0x3024, 0xC9); /* SHS2[7:0], TBD*/ + imx327_slave_write_register(ViPipe, 0x3025, 0x07); /* SHS2[15:8]*/ + imx327_slave_write_register(ViPipe, 0x3026, 0x00); /* SHS2[19:16]*/ + imx327_slave_write_register(ViPipe, 0x3030, 0x0B); /* RHS1[7:0], TBD*/ + imx327_slave_write_register(ViPipe, 0x3031, 0x00); /* RHS1[15:8]*/ + imx327_slave_write_register(ViPipe, 0x3032, 0x00); /* RHS1[19:16]*/ + imx327_slave_write_register(ViPipe, 0x3045, 0x05); /* DOLSCDEN [0] 1: pattern1 0: pattern2*/ + imx327_slave_write_register(ViPipe, 0x3046, 0x01); + imx327_slave_write_register(ViPipe, 0x304B, 0x0A); + imx327_slave_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx327_slave_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx327_slave_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx327_slave_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx327_slave_write_register(ViPipe, 0x309E, 0x4A); + imx327_slave_write_register(ViPipe, 0x309F, 0x4A); + imx327_slave_write_register(ViPipe, 0x30D2, 0x19); + imx327_slave_write_register(ViPipe, 0x30D7, 0x03); + imx327_slave_write_register(ViPipe, 0x3106, 0x11); /*DOLHBFIXEN[7] 0: pattern1 1: pattern2*/ + imx327_slave_write_register(ViPipe, 0x3129, 0x00); + imx327_slave_write_register(ViPipe, 0x313B, 0x61); + imx327_slave_write_register(ViPipe, 0x315E, 0x1A); + imx327_slave_write_register(ViPipe, 0x3164, 0x1A); + imx327_slave_write_register(ViPipe, 0x317C, 0x00); + imx327_slave_write_register(ViPipe, 0x31EC, 0x0E); + imx327_slave_write_register(ViPipe, 0x3405, 0x00); /* Repetition*/ + imx327_slave_write_register(ViPipe, 0x3407, 0x01); /* physical_lane_nl*/ + imx327_slave_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx327_slave_write_register(ViPipe, 0x3415, 0x00); /* NULL0_SIZE_V, set to 00h when DOL*/ + imx327_slave_write_register(ViPipe, 0x3418, 0xB4); /* y_out_size*/ + imx327_slave_write_register(ViPipe, 0x3419, 0x08); /* y_out_size*/ + imx327_slave_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx327_slave_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx327_slave_write_register(ViPipe, 0x3443, 0x01); /* csi_lane_mode*/ + imx327_slave_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx327_slave_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx327_slave_write_register(ViPipe, 0x3446, 0x77); /* tclkpost*/ + imx327_slave_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx327_slave_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx327_slave_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx327_slave_write_register(ViPipe, 0x344A, 0x47); /* thsprepare*/ + imx327_slave_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx327_slave_write_register(ViPipe, 0x344C, 0x37); /* tclktrail*/ + imx327_slave_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx327_slave_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx327_slave_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx327_slave_write_register(ViPipe, 0x3450, 0xFF); /* tclkzero*/ + imx327_slave_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx327_slave_write_register(ViPipe, 0x3452, 0x3F); /* tclkprepare*/ + imx327_slave_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx327_slave_write_register(ViPipe, 0x3454, 0x37); /* tlpx*/ + imx327_slave_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx327_slave_write_register(ViPipe, 0x3472, 0xA0); /* x_out_size*/ + imx327_slave_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx327_slave_write_register(ViPipe, 0x347B, 0x23); /**/ + imx327_slave_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx327_slave_default_reg_init(ViPipe); + + if (g_au16Imx327_Slave_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + imx327_slave_write_register(ViPipe, 0x30F0, 0xF0); + imx327_slave_write_register(ViPipe, 0x3010, 0x21); + } else { + imx327_slave_write_register(ViPipe, 0x30F0, 0x64); + imx327_slave_write_register(ViPipe, 0x3010, 0x61); + } + + imx327_slave_write_register(ViPipe, 0x3000, 0x00); /* standby */ + + if (!g_au16Imx327_Slave_UseHwSync[ViPipe]) { + delay_ms(20); + imx327_slave_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_slave_write_register(ViPipe, 0x304b, 0x0a); + } else + imx327_slave_write_register(ViPipe, 0x3106, 0x40); /* XVS/XHS sub-sampling */ + + printf("===Imx327 sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) Slave init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_sublvds/Makefile b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_sublvds/Makefile new file mode 100644 index 000000000..db74d8c90 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_sublvds/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx327_sublvds.a +TARGET_SO = $(MW_LIB)/libsns_imx327_sublvds.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_sublvds/imx327_sublvds_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_sublvds/imx327_sublvds_cmos.c new file mode 100644 index 000000000..cd32f0c61 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_sublvds/imx327_sublvds_cmos.c @@ -0,0 +1,1137 @@ +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "imx327_sublvds_cmos_ex.h" +#include "imx327_sublvds_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX327_SUBLVDS_ID 327 +#define SENSOR_IMX327_SUBLVDS_WIDTH 1920 +#define SENSOR_IMX327_SUBLVDS_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx327_sublvds[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX327_SUBLVDS_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx327_sublvds[dev]) +#define IMX327_SUBLVDS_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx327_sublvds[dev] = pstCtx) +#define IMX327_SUBLVDS_SENSOR_RESET_CTX(dev) (g_pastImx327_sublvds[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunImx327_sublvds_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx327_sublvds_GainMode[VI_MAX_PIPE_NUM] = {0}; + +IMX327_SUBLVDS_STATE_S g_astImx327_sublvds_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx327_sublvds_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx327_sublvds Lines Range*****/ +#define IMX327_SUBLVDS_FULL_LINES_MAX (0x3FFFF) +#define IMX327_SUBLVDS_FULL_LINES_MAX_2TO1_WDR (0x3FFFF) // considering the YOUT_SIZE and bad frame +#define IMX327_SUBLVDS_VMAX_1080P30_LINEAR 1125 + +/*****Imx327_sublvds Register Address*****/ +#define IMX327_SUBLVDS_HOLD_ADDR 0x3001 +#define IMX327_SUBLVDS_SHS1_ADDR 0x3020 +#define IMX327_SUBLVDS_SHS2_ADDR 0x3024 +#define IMX327_SUBLVDS_GAIN_ADDR 0x3014 +#define IMX327_SUBLVDS_GAIN1_ADDR 0x30F2 +#define IMX327_SUBLVDS_HCG_ADDR 0x3009 +#define IMX327_SUBLVDS_VMAX_ADDR 0x3018 +#define IMX327_SUBLVDS_HMAX_ADDR 0x301C +#define IMX327_SUBLVDS_YOUT_ADDR 0x3418 +#define IMX327_SUBLVDS_RHS1_ADDR 0x3030 +#define IMX327_SUBLVDS_TABLE_END 0xffff + +#define IMX327_SUBLVDS_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX327_SUBLVDS_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astImx327_sublvds_mode[IMX327_SUBLVDS_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_sublvds_mode[IMX327_SUBLVDS_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astImx327_sublvds_mode[IMX327_SUBLVDS_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_sublvds_mode[IMX327_SUBLVDS_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX, u32HMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32VMAX = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].u32VtsDef; + u32HMAX = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].u32HtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].f32MinFps; + + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32HMAX = u32HMAX * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor fps: %f\n", f32Fps); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_HMAX_0].u32Data = (u32HMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HMAX_1].u32Data = ((u32HMAX & 0xFF00) >> 8); + } else { + pstSnsRegsInfo->astI2cData[DOL2_HMAX_0].u32Data = (u32HMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HMAX_1].u32Data = ((u32HMAX & 0xFF00) >> 8); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx327_sublvds_State[ViPipe].u32RHS1_MAX = + (u32VMAX - g_astImx327_sublvds_State[ViPipe].u32BRL) * 2 - 21; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHS1 = 0; + CVI_U32 u32SHS2 = 0; + CVI_U32 u32YOUTSIZE; + CVI_U32 u16BRL = 0; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u16BRL = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].u16BRL; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[1] < u32LongIntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[1], u32LongIntTime - 1); + return CVI_FAILURE; + } + u32SHS2 = pstSnsState->au32FL[1] - u32LongIntTime - 1; + + u32SHS1 = (u32ShortIntTime % 2) + 2; + u32RHS1 = u32ShortIntTime + u32SHS1 + 1; + g_astImx327_sublvds_State[ViPipe].u32RHS1 = u32RHS1; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - (u32SHS1 + 1); + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[1] - (u32SHS2 + 1); + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + u32YOUTSIZE = (u16BRL + (u32RHS1 - 1) / 2) * 2; + u32YOUTSIZE = (u32YOUTSIZE >= 0x1FFF) ? 0x1FFF : u32YOUTSIZE; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHS1 = %d\n", u32ShortIntTime, u32SHS1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d u32YOUTSIZE = %d\n", ViPipe, u32RHS1, u32YOUTSIZE); + + pstSnsRegsInfo->astI2cData[DOL2_SHS1_0].u32Data = (u32SHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_1].u32Data = ((u32SHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_2].u32Data = ((u32SHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHS2_0].u32Data = (u32SHS2 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_1].u32Data = ((u32SHS2 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_2].u32Data = ((u32SHS2 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_0].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_1].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_2].u32Data = ((u32RHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_0].u32Data = (u32YOUTSIZE & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_1].u32Data = ((u32YOUTSIZE & 0x1F00) >> 8); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if (pstSnsState->au32FL[0] < *u32IntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], *u32IntTime - 1); + return CVI_FAILURE; + } + u32Value = pstSnsState->au32FL[0] - *u32IntTime - 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2].u32Data = ((u32Value & 0x30000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 327567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32HCG = g_astImx327_sublvds_State[ViPipe].u8Hcg; + CVI_U32 u16Mode = g_au16Imx327_sublvds_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = (u32HCG & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + CVI_U8 bEnableHCG = 0; + + if (pu32Again[0] >= 20 && pu32Again[1] >= 20) { + /* hcg bit[4]*/ + u32HCG |= 0x10; + bEnableHCG = 1; + } + + u32Again = pu32Again[1] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + + u32Again = pu32Again[0] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN1].u32Data = (u32Tmp & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = 2; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 10; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx327_sublvds_State[ViPipe].u32RHS1_MAX - 3)) ? + (g_astImx327_sublvds_State[ViPipe].u32RHS1_MAX - 3) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX327_SUBLVDS_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx327_sublvds_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX327_SUBLVDS_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = IMX327_SUBLVDS_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].u32VtsDef; + g_astImx327_sublvds_State[ViPipe].u8Hcg = 0x2; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX327_SUBLVDS_MODE_1080P30) + pstSnsState->u8ImgMode = IMX327_SUBLVDS_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + g_astImx327_sublvds_State[ViPipe].u8Hcg = 0x1; + if (pstSnsState->u8ImgMode == IMX327_SUBLVDS_MODE_1080P30_WDR) { + pstSnsState->u32FLStd = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx327_sublvds_State[ViPipe].u32BRL = + g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1080p\n"); + } + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx327_sublvds_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 2; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx327_sublvds_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx327_sublvds_addr_byte; + pstI2c_data[i].u32DataByteNum = imx327_sublvds_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_HOLD].u32RegAddr = IMX327_SUBLVDS_HOLD_ADDR; + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_SHS1_0].u32RegAddr = IMX327_SUBLVDS_SHS1_ADDR; + pstI2c_data[DOL2_SHS1_1].u32RegAddr = IMX327_SUBLVDS_SHS1_ADDR + 1; + pstI2c_data[DOL2_SHS1_2].u32RegAddr = IMX327_SUBLVDS_SHS1_ADDR + 2; + + pstI2c_data[DOL2_GAIN].u32RegAddr = IMX327_SUBLVDS_GAIN_ADDR; + pstI2c_data[DOL2_HCG].u32RegAddr = IMX327_SUBLVDS_HCG_ADDR; + pstI2c_data[DOL2_HCG].u8DelayFrmNum = 1; + pstI2c_data[DOL2_GAIN1].u32RegAddr = IMX327_SUBLVDS_GAIN1_ADDR; + pstI2c_data[DOL2_RHS1_0].u32RegAddr = IMX327_SUBLVDS_RHS1_ADDR; + pstI2c_data[DOL2_RHS1_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_1].u32RegAddr = IMX327_SUBLVDS_RHS1_ADDR + 1; + pstI2c_data[DOL2_RHS1_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_2].u32RegAddr = IMX327_SUBLVDS_RHS1_ADDR + 2; + pstI2c_data[DOL2_RHS1_2].u8DelayFrmNum = 1; + pstI2c_data[DOL2_SHS2_0].u32RegAddr = IMX327_SUBLVDS_SHS2_ADDR; + pstI2c_data[DOL2_SHS2_1].u32RegAddr = IMX327_SUBLVDS_SHS2_ADDR + 1; + pstI2c_data[DOL2_SHS2_2].u32RegAddr = IMX327_SUBLVDS_SHS2_ADDR + 2; + pstI2c_data[DOL2_HMAX_0].u32RegAddr = IMX327_SUBLVDS_HMAX_ADDR; + pstI2c_data[DOL2_HMAX_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_HMAX_1].u32RegAddr = IMX327_SUBLVDS_HMAX_ADDR + 1; + pstI2c_data[DOL2_HMAX_1].u8DelayFrmNum = 1; + + pstI2c_data[DOL2_YOUT_SIZE_0].u32RegAddr = IMX327_SUBLVDS_YOUT_ADDR; + pstI2c_data[DOL2_YOUT_SIZE_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u32RegAddr = IMX327_SUBLVDS_YOUT_ADDR + 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_REL].u32RegAddr = IMX327_SUBLVDS_HOLD_ADDR; + pstI2c_data[DOL2_REL].u32Data = 0; + break; + default: + pstI2c_data[LINEAR_HOLD].u32RegAddr = IMX327_SUBLVDS_HOLD_ADDR; + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_SHS1_0].u32RegAddr = IMX327_SUBLVDS_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1].u32RegAddr = IMX327_SUBLVDS_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2].u32RegAddr = IMX327_SUBLVDS_SHS1_ADDR + 2; + pstI2c_data[LINEAR_GAIN].u32RegAddr = IMX327_SUBLVDS_GAIN_ADDR; + pstI2c_data[LINEAR_HCG].u32RegAddr = IMX327_SUBLVDS_HCG_ADDR; + pstI2c_data[LINEAR_HCG].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_HMAX_0].u32RegAddr = IMX327_SUBLVDS_HMAX_ADDR; + pstI2c_data[LINEAR_HMAX_1].u32RegAddr = IMX327_SUBLVDS_HMAX_ADDR + 1; + pstI2c_data[LINEAR_REL].u32RegAddr = IMX327_SUBLVDS_HOLD_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[DOL2_REL].u32Data = 0; + pstI2c_data[DOL2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + pstCfg0->ispCfg.need_update = CVI_FALSE; + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX327_SUBLVDS_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_SUBLVDS_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX327_SUBLVDS_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_SUBLVDS_MODE_1080P30_WDR; + g_astImx327_sublvds_State[ViPipe].u32BRL = 1109; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx327_sublvds_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx327_sublvds_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx327_sublvds_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = IMX327_SUBLVDS_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = IMX327_SUBLVDS_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[0] = IMX327_SUBLVDS_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[1] = IMX327_SUBLVDS_VMAX_1080P30_LINEAR; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx327_sublvds_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->lvds_attr.wdr_mode = CVI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx327_sublvds_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx327_sublvds_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx327_sublvds_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx327_sublvds_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx327_sublvds_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX327_SUBLVDS_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX327_SUBLVDS_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX327_SUBLVDS_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX327_SUBLVDS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX327_SUBLVDS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX327_SUBLVDS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx327_sublvds_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return imx327_sublvds_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsImx327_Sublvds_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx327_sublvds_standby, + .pfnRestart = imx327_sublvds_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx327_sublvds_write_register, + .pfnReadReg = imx327_sublvds_read_register, + .pfnSetBusInfo = imx327_sublvds_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_sublvds/imx327_sublvds_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_sublvds/imx327_sublvds_cmos_ex.h new file mode 100644 index 000000000..493a18f00 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_sublvds/imx327_sublvds_cmos_ex.h @@ -0,0 +1,113 @@ +#ifndef __IMX327_SUBLVDS_CMOS_EX_H_ +#define __IMX327_SUBLVDS_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +enum imx327_sublvds_linear_regs_e { + LINEAR_HOLD = 0, + LINEAR_SHS1_0, + LINEAR_SHS1_1, + LINEAR_SHS1_2, + LINEAR_GAIN, + LINEAR_HCG, + LINEAR_HMAX_0, + LINEAR_HMAX_1, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum imx327_sublvds_dol2_regs_e { + DOL2_HOLD = 0, + DOL2_SHS1_0, + DOL2_SHS1_1, + DOL2_SHS1_2, + DOL2_GAIN, + DOL2_HCG, + DOL2_GAIN1, + DOL2_RHS1_0, + DOL2_RHS1_1, + DOL2_RHS1_2, + DOL2_SHS2_0, + DOL2_SHS2_1, + DOL2_SHS2_2, + DOL2_HMAX_0, + DOL2_HMAX_1, + DOL2_YOUT_SIZE_0, + DOL2_YOUT_SIZE_1, + DOL2_REL, + DOL2_REGS_NUM +}; + +typedef enum _IMX327_SUBLVDS_MODE_E { + IMX327_SUBLVDS_MODE_1080P30 = 0, + IMX327_SUBLVDS_MODE_LINEAR_NUM, + IMX327_SUBLVDS_MODE_1080P30_WDR = IMX327_SUBLVDS_MODE_LINEAR_NUM, + IMX327_SUBLVDS_MODE_NUM +} IMX327_SUBLVDS_MODE_E; + +typedef struct _IMX327_SUBLVDS_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX327_SUBLVDS_STATE_S; + +typedef struct _IMX327_SUBLVDS_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX327_SUBLVDS_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx327_sublvds[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx327_sublvds_BusInfo[]; +extern CVI_U16 g_au16Imx327_sublvds_GainMode[]; +extern const CVI_U8 imx327_sublvds_i2c_addr; +extern const CVI_U32 imx327_sublvds_addr_byte; +extern const CVI_U32 imx327_sublvds_data_byte; +extern void imx327_sublvds_init(VI_PIPE ViPipe); +extern void imx327_sublvds_exit(VI_PIPE ViPipe); +extern void imx327_sublvds_standby(VI_PIPE ViPipe); +extern void imx327_sublvds_restart(VI_PIPE ViPipe); +extern int imx327_sublvds_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx327_sublvds_read_register(VI_PIPE ViPipe, int addr); +extern void imx327_sublvds_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int imx327_sublvds_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_SUBLVDS_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_sublvds/imx327_sublvds_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_sublvds/imx327_sublvds_cmos_param.h new file mode 100644 index 000000000..8d39343f7 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_sublvds/imx327_sublvds_cmos_param.h @@ -0,0 +1,321 @@ +#ifndef __IMX327_SUBLVDS_CMOS_PARAM_H_ +#define __IMX327_SUBLVDS_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_sublvds_cmos_ex.h" + +static const IMX327_SUBLVDS_MODE_S g_astImx327_sublvds_mode[IMX327_SUBLVDS_MODE_NUM] = { + [IMX327_SUBLVDS_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1110, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 21, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1110, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x1130, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX327_SUBLVDS_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1110, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 21, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1110, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1110, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 21, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1110, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 8, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 2236, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.038478557020425796517, 2.14561891555786132813}, //B: slope, intercept + {0.03633839637041091919, 0.17788629233837127686}, //Gb: slope, intercept + {0.03592018783092498779, 0.21645727753639221191}, //Gr: slope, intercept + {0.03592239692807197571, 1.48806631565093994141}, //R: slope, intercept + }, + { //iso 200 + {0.04168356582522392273, 4.38879251480102539063}, //B: slope, intercept + {0.03754633292555809021, 3.21502065658569335938}, //Gb: slope, intercept + {0.03759334236383438110, 3.48370814323425292969}, //Gr: slope, intercept + {0.03719408065080642700, 4.63629007339477539063}, //R: slope, intercept + }, + { //iso 400 + {0.05050259083509445190, 6.85188436508178710938}, //B: slope, intercept + {0.04007886722683906555, 8.49916744232177734375}, //Gb: slope, intercept + {0.03934165090322494507, 8.68585968017578125000}, //Gr: slope, intercept + {0.04134147986769676208, 8.89877605438232421875}, //R: slope, intercept + }, + { //iso 800 + {0.04306267201900482178, 15.41853904724121093750}, //B: slope, intercept + {0.03570587188005447388, 18.56583213806152343750}, //Gb: slope, intercept + {0.03533876314759254456, 19.57685661315917968750}, //Gr: slope, intercept + {0.03832129389047622681, 17.90320968627929687500}, //R: slope, intercept + }, + { //iso 1600 + {0.06225715205073356628, 21.87150573730468750000}, //B: slope, intercept + {0.04437549784779548645, 30.87298965454101562500}, //Gb: slope, intercept + {0.04517432302236557007, 29.32084465026855468750}, //Gr: slope, intercept + {0.05255207046866416931, 26.26001358032226562500}, //R: slope, intercept + }, + { //iso 3200 + {0.07859147340059280396, 32.48978424072265625000}, //B: slope, intercept + {0.05918205901980400085, 45.08999633789062500000}, //Gb: slope, intercept + {0.05711782723665237427, 48.86173248291015625000}, //Gr: slope, intercept + {0.07310666143894195557, 36.88227081298828125000}, //R: slope, intercept + }, + { //iso 6400 + {0.11759266257286071777, 45.81345367431640625000}, //B: slope, intercept + {0.07679814100265502930, 69.04325866699218750000}, //Gb: slope, intercept + {0.07774948328733444214, 66.52905273437500000000}, //Gr: slope, intercept + {0.10286796092987060547, 51.73817443847656250000}, //R: slope, intercept + }, + { //iso 12800 + {0.15860086679458618164, 64.15329742431640625000}, //B: slope, intercept + {0.10511043667793273926, 91.36695098876953125000}, //Gb: slope, intercept + {0.10040879994630813599, 92.05632781982421875000}, //Gr: slope, intercept + {0.13499946892261505127, 73.36162567138671875000}, //R: slope, intercept + }, + { //iso 25600 + {0.22810073196887969971, 100.01741027832031250000}, //B: slope, intercept + {0.14736327528953552246, 146.62678527832031250000}, //Gb: slope, intercept + {0.15503610670566558838, 136.06079101562500000000}, //Gr: slope, intercept + {0.20250190794467926025, 112.74269104003906250000}, //R: slope, intercept + }, + { //iso 51200 + {0.29010805487632751465, 155.05882263183593750000}, //B: slope, intercept + {0.20221179723739624023, 210.97210693359375000000}, //Gb: slope, intercept + {0.21603405475616455078, 201.40393066406250000000}, //Gr: slope, intercept + {0.27819159626960754395, 165.48959350585937500000}, //R: slope, intercept + }, + { //iso 102400 + {0.40437409281730651855, 245.11883544921875000000}, //B: slope, intercept + {0.26703724265098571777, 345.62698364257812500000}, //Gb: slope, intercept + {0.27536261081695556641, 318.75701904296875000000}, //Gr: slope, intercept + {0.44441288709640502930, 222.47651672363281250000}, //R: slope, intercept + }, + { //iso 204800 + {0.48959052562713623047, 383.21560668945312500000}, //B: slope, intercept + {0.37694901227951049805, 442.55813598632812500000}, //Gb: slope, intercept + {0.38724529743194580078, 449.72384643554687500000}, //Gr: slope, intercept + {0.60220617055892944336, 318.92291259765625000000}, //R: slope, intercept + }, + { //iso 409600 + {0.59899300336837768555, 580.43414306640625000000}, //B: slope, intercept + {0.43681395053863525391, 700.22204589843750000000}, //Gb: slope, intercept + {0.50216537714004516602, 633.89794921875000000000}, //Gr: slope, intercept + {0.77917146682739257813, 453.13076782226562500000}, //R: slope, intercept + }, + { //iso 819200 + {0.54956322908401489258, 871.06585693359375000000}, //B: slope, intercept + {0.38088488578796386719, 1040.72192382812500000000}, //Gb: slope, intercept + {0.47245877981185913086, 937.37445068359375000000}, //Gr: slope, intercept + {0.70387065410614013672, 730.45373535156250000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.67512661218643188477, 797.11108398437500000000}, //B: slope, intercept + {0.50457936525344848633, 962.40740966796875000000}, //Gb: slope, intercept + {0.59857457876205444336, 856.90533447265625000000}, //Gr: slope, intercept + {0.74725526571273803711, 740.04290771484375000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.79927802085876464844, 687.07183837890625000000}, //B: slope, intercept + {0.81719654798507690430, 687.01580810546875000000}, //Gb: slope, intercept + {0.83395677804946899414, 658.91857910156250000000}, //Gr: slope, intercept + {0.72803622484207153320, 746.19427490234375000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {240, 240, 240, 240, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1088, 1088, 1088, 1088 +#endif + }, + .stAuto = { + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, +#endif + }, + }, +}; + +struct combo_dev_attr_s imx327_sublvds_rx_attr = { + .input_mode = INPUT_MODE_SUBLVDS, + .mac_clk = RX_MAC_CLK_200M, + .lvds_attr = { + .wdr_mode = CVI_WDR_MODE_DOL_2F, + .sync_mode = LVDS_SYNC_MODE_SAV, + .raw_data_type = RAW_DATA_12BIT, + .data_endian = LVDS_ENDIAN_BIG, + .sync_code_endian = LVDS_ENDIAN_BIG, + .lane_id = {2, 3, 1, 4, 0}, + .pn_swap = {1, 1, 1, 1, 1}, + .sync_code = { + { + {0x801, 0x9D1, 0xC01, 0xDD1}, + {0x802, 0x9D2, 0xC02, 0xDD2}, + {0x803, 0x9D3, 0xC03, 0xDD3}, + }, + }, + .vsync_type = { + .sync_type = LVDS_VSYNC_NORMAL, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_SUBLVDS_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx327_sublvds/imx327_sublvds_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_sublvds/imx327_sublvds_sensor_ctl.c new file mode 100644 index 000000000..48704c34b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx327_sublvds/imx327_sublvds_sensor_ctl.c @@ -0,0 +1,358 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_sublvds_cmos_ex.h" + +static void imx327_sublvds_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void imx327_sublvds_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 imx327_sublvds_i2c_addr = 0x1A; +const CVI_U32 imx327_sublvds_addr_byte = 2; +const CVI_U32 imx327_sublvds_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx327_sublvds_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx327_sublvds_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx327_sublvds_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int imx327_sublvds_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx327_sublvds_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (imx327_sublvds_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, imx327_sublvds_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, imx327_sublvds_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (imx327_sublvds_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int imx327_sublvds_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx327_sublvds_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx327_sublvds_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx327_sublvds_addr_byte + imx327_sublvds_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx327_sublvds_standby(VI_PIPE ViPipe) +{ + imx327_sublvds_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_sublvds_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ +} + +void imx327_sublvds_restart(VI_PIPE ViPipe) +{ + imx327_sublvds_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_sublvds_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_sublvds_write_register(ViPipe, 0x304b, 0x0a); +} + +void imx327_sublvds_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx327_sublvds[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx327_sublvds_write_register(ViPipe, + g_pastImx327_sublvds[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx327_sublvds[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define IMX327_CHIP_ID_ADDR 0x31dc +#define IMX327_CHIP_ID 0x6 +#define IMX327_CHIP_ID_MASK 0x6 + +void imx327_sublvds_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = imx327_sublvds_read_register(ViPipe, 0x3007) & ~0x3; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + imx327_sublvds_write_register(ViPipe, 0x3007, val); +} + +int imx327_sublvds_probe(VI_PIPE ViPipe) +{ + int nVal; + + usleep(100); + if (imx327_sublvds_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = imx327_sublvds_read_register(ViPipe, IMX327_CHIP_ID_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((nVal & IMX327_CHIP_ID_MASK) != IMX327_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void imx327_sublvds_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastImx327_sublvds[ViPipe]->enWDRMode; + u8ImgMode = g_pastImx327_sublvds[ViPipe]->u8ImgMode; + + imx327_sublvds_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == IMX327_SUBLVDS_MODE_1080P30_WDR) { + imx327_sublvds_wdr_1080p30_2to1_init(ViPipe); + } + } else { + imx327_sublvds_linear_1080p30_init(ViPipe); + } + g_pastImx327_sublvds[ViPipe]->bInit = CVI_TRUE; +} + +void imx327_sublvds_exit(VI_PIPE ViPipe) +{ + imx327_sublvds_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void imx327_sublvds_linear_1080p30_init(VI_PIPE ViPipe) +{ + imx327_sublvds_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_sublvds_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_sublvds_write_register(ViPipe, 0x3002, 0x00); /* XMSTA */ + imx327_sublvds_write_register(ViPipe, 0x3005, 0x01); /* ADBIT 10bit */ + imx327_sublvds_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ... */ + imx327_sublvds_write_register(ViPipe, 0x3009, 0x02); + imx327_sublvds_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL */ + imx327_sublvds_write_register(ViPipe, 0x3011, 0x02); + imx327_sublvds_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD */ + imx327_sublvds_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0] */ + imx327_sublvds_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8] */ + imx327_sublvds_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0] */ + imx327_sublvds_write_register(ViPipe, 0x301C, 0x30); /* HMAX[7:0], TBD */ + imx327_sublvds_write_register(ViPipe, 0x301D, 0x11); /* HMAX[15:8] */ + imx327_sublvds_write_register(ViPipe, 0x3020, 0x8C); /* SHS[7:0], TBD */ + imx327_sublvds_write_register(ViPipe, 0x3021, 0x01); /* SHS[15:8] */ + imx327_sublvds_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16] */ + imx327_sublvds_write_register(ViPipe, 0x3046, 0xE1); + imx327_sublvds_write_register(ViPipe, 0x304B, 0x0A); + imx327_sublvds_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1 */ + imx327_sublvds_write_register(ViPipe, 0x305D, 0x00); /* INCKSEL2 */ + imx327_sublvds_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3 */ + imx327_sublvds_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4 */ + imx327_sublvds_write_register(ViPipe, 0x309E, 0x4A); + imx327_sublvds_write_register(ViPipe, 0x309F, 0x4A); + imx327_sublvds_write_register(ViPipe, 0x30D2, 0x19); + imx327_sublvds_write_register(ViPipe, 0x30D7, 0x03); + imx327_sublvds_write_register(ViPipe, 0x3129, 0x00); + imx327_sublvds_write_register(ViPipe, 0x313B, 0x61); + imx327_sublvds_write_register(ViPipe, 0x315E, 0x1A); + imx327_sublvds_write_register(ViPipe, 0x3164, 0x1A); + imx327_sublvds_write_register(ViPipe, 0x317C, 0x00); + imx327_sublvds_write_register(ViPipe, 0x31EC, 0x0E); + imx327_sublvds_write_register(ViPipe, 0x3480, 0x49); /* incksel7 */ + + imx327_sublvds_default_reg_init(ViPipe); + + imx327_sublvds_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_sublvds_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_sublvds_write_register(ViPipe, 0x304b, 0x0a); + + printf("ViPipe:%d,===IMX327 1080P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void imx327_sublvds_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + imx327_sublvds_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_sublvds_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_sublvds_write_register(ViPipe, 0x3002, 0x00); /* XMSTA */ + imx327_sublvds_write_register(ViPipe, 0x3005, 0x01); /* ADBIT */ + imx327_sublvds_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ... */ + imx327_sublvds_write_register(ViPipe, 0x3009, 0x01); + imx327_sublvds_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL */ + imx327_sublvds_write_register(ViPipe, 0x300C, 0x11); /* WDMODE */ + imx327_sublvds_write_register(ViPipe, 0x3011, 0x02); + imx327_sublvds_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD */ + imx327_sublvds_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0] */ + imx327_sublvds_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8] */ + imx327_sublvds_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0] */ + imx327_sublvds_write_register(ViPipe, 0x301C, 0x98); /* HMAX[7:0], TBD */ + imx327_sublvds_write_register(ViPipe, 0x301D, 0x08); /* HMAX[15:8] */ + imx327_sublvds_write_register(ViPipe, 0x3020, 0x02); /* SHS[7:0], TBD */ + imx327_sublvds_write_register(ViPipe, 0x3021, 0x00); /* SHS[15:8] */ + imx327_sublvds_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16] */ + imx327_sublvds_write_register(ViPipe, 0x3024, 0xC9); /* SHS2[7:0], TBD */ + imx327_sublvds_write_register(ViPipe, 0x3025, 0x07); /* SHS2[15:8] */ + imx327_sublvds_write_register(ViPipe, 0x3026, 0x00); /* SHS2[19:16] */ + imx327_sublvds_write_register(ViPipe, 0x3030, 0x0B); /* RHS1[7:0], TBD */ + imx327_sublvds_write_register(ViPipe, 0x3031, 0x00); /* RHS1[15:8] */ + imx327_sublvds_write_register(ViPipe, 0x3032, 0x00); /* RHS1[19:16] */ + imx327_sublvds_write_register(ViPipe, 0x3045, 0x03); /* DOLSCDEN [0] 1: pattern1 0: pattern2 */ + imx327_sublvds_write_register(ViPipe, 0x3046, 0xE1); + imx327_sublvds_write_register(ViPipe, 0x304B, 0x0A); + imx327_sublvds_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1 */ + imx327_sublvds_write_register(ViPipe, 0x305D, 0x00); /* INCKSEL2 */ + imx327_sublvds_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3 */ + imx327_sublvds_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4 */ + imx327_sublvds_write_register(ViPipe, 0x309E, 0x4A); + imx327_sublvds_write_register(ViPipe, 0x309F, 0x4A); + imx327_sublvds_write_register(ViPipe, 0x30D2, 0x19); + imx327_sublvds_write_register(ViPipe, 0x30D7, 0x03); + imx327_sublvds_write_register(ViPipe, 0x3106, 0x11); /*DOLHBFIXEN[7] 0: pattern1 1: pattern2 */ + imx327_sublvds_write_register(ViPipe, 0x3129, 0x00); + imx327_sublvds_write_register(ViPipe, 0x313B, 0x61); + imx327_sublvds_write_register(ViPipe, 0x315E, 0x1A); + imx327_sublvds_write_register(ViPipe, 0x3164, 0x1A); + imx327_sublvds_write_register(ViPipe, 0x317C, 0x00); + imx327_sublvds_write_register(ViPipe, 0x31EC, 0x0E); + imx327_sublvds_write_register(ViPipe, 0x3415, 0x00); /* NULL0_SIZE_V, set to 00h when DOL */ + imx327_sublvds_write_register(ViPipe, 0x3480, 0x49); + + imx327_sublvds_default_reg_init(ViPipe); + + if (g_au16Imx327_sublvds_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + imx327_sublvds_write_register(ViPipe, 0x30F0, 0xF0); + imx327_sublvds_write_register(ViPipe, 0x3010, 0x21); + } else { + imx327_sublvds_write_register(ViPipe, 0x30F0, 0x64); + imx327_sublvds_write_register(ViPipe, 0x3010, 0x61); + } + + imx327_sublvds_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_sublvds_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_sublvds_write_register(ViPipe, 0x304b, 0x0a); + + printf("===Imx327_sublvds sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx335/Makefile b/middleware/v2/component/isp/sensor/cv180x/sony_imx335/Makefile new file mode 100644 index 000000000..f2aa51872 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx335/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx335.a +TARGET_SO = $(MW_LIB)/libsns_imx335.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx335/imx335_cmos.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx335/imx335_cmos.c new file mode 100644 index 000000000..a1f50c2b7 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx335/imx335_cmos.c @@ -0,0 +1,1255 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "imx335_cmos_ex.h" +#include "imx335_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX335_ID 335 + +#define SENSOR_IMX335_4M_WIDTH 2560 +#define SENSOR_IMX335_4M_HEIGHT 1440 + +#define SENSOR_IMX335_4M_1600P_WIDTH 2560 +#define SENSOR_IMX335_4M_1600P_HEIGHT 1600 + +#define SENSOR_IMX335_5M_WIDTH 2592 +#define SENSOR_IMX335_5M_HEIGHT 1944 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx335[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX335_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx335[dev]) +#define IMX335_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx335[dev] = pstCtx) +#define IMX335_SENSOR_RESET_CTX(dev) (g_pastImx335[dev] = CVI_NULL) + +#define IMX335_SNNSOR_IS_2L() (imx335_rx_attr.mipi_attr.lane_id[3] == -1 && imx335_rx_attr.mipi_attr.lane_id[4] == -1) +#define IMX335_SNNSOR_IS_4L() (imx335_rx_attr.mipi_attr.lane_id[3] != -1 && imx335_rx_attr.mipi_attr.lane_id[4] != -1) + +ISP_SNS_COMMBUS_U g_aunImx335_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx335_GainMode[VI_MAX_PIPE_NUM] = {0}; + +IMX335_STATE_S g_astImx335_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx335_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx335 Lines Range*****/ +#define IMX335_FULL_LINES_MAX (0xFFFFF) +#define IMX335_VMAX_5M30_LINEAR 0x1194 + +/*****Imx335 Register Address*****/ +#define IMX335_HOLD_ADDR 0x3001 + +#define IMX335_SHR0_L_ADDR 0x3058 //shutter time +#define IMX335_SHR0_M_ADDR 0x3059 +#define IMX335_SHR0_H_ADDR 0x305A //bit[19:16] +#define IMX335_SHR1_L_ADDR 0x305C +#define IMX335_SHR1_M_ADDR 0x305D +#define IMX335_SHR1_H_ADDR 0x305E + +#define IMX335_GAIN_L_ADDR 0x30E8 //gain +#define IMX335_GAIN_H_ADDR 0x30E9 //bit[10:8] +#define IMX335_GAIN_SHORT_L 0x30EA +#define IMX335_GAIN_SHORT_H 0x30EB + +#define IMX335_VMAX_L_ADDR 0x3030 //vmax +#define IMX335_VMAX_M_ADDR 0x3031 +#define IMX335_VMAX_H_ADDR 0x3032 //bit[19:16] + +#define IMX335_YOUT_L_ADDR 0x3056 //window, the number of effective pixel lines +#define IMX335_YOUT_H_ADDR 0x3057 //bit[12:8] + +#define IMX335_RHS1_L_ADDR 0x3068 +#define IMX335_RHS1_M_ADDR 0x3069 +#define IMX335_RHS1_H_ADDR 0x306A +#define IMX335_TABLE_END 0xffff + +#define IMX335_RES_IS_5M(w, h) ((w) == SENSOR_IMX335_5M_WIDTH && (h) == SENSOR_IMX335_5M_HEIGHT) +#define IMX335_RES_IS_4M(w, h) ((w) == SENSOR_IMX335_4M_WIDTH && (h) == SENSOR_IMX335_4M_HEIGHT) +#define IMX335_RES_IS_4M_1600P(w, h) ((w) == SENSOR_IMX335_4M_1600P_WIDTH && (h) == SENSOR_IMX335_4M_1600P_HEIGHT) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;//???print + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX335_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astImx335_mode[pstSnsState->u8ImgMode].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx335_mode[pstSnsState->u8ImgMode].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 32381; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + //shutter time [9 to (number of lines perframe -1)] + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 1; + pstAeSnsDft->u32MinIntTime = 9; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astImx335_mode[pstSnsState->u8ImgMode].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx335_mode[pstSnsState->u8ImgMode].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 32381; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = IMX335_VMAX_5M30_LINEAR; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0, u32Tmp = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astImx335_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx335_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx335_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case IMX335_MODE_5M30_WDR: + case IMX335_MODE_4M30_WDR: + case IMX335_MODE_4M30_1600P_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + /* FSC shall be multiple of 8 */ + if (u32VMAX % 4) { + u32VMAX = u32VMAX - (u32VMAX % 4) + 4; + } + u32VMAX = (u32VMAX > IMX335_FULL_LINES_MAX) ? IMX335_FULL_LINES_MAX : u32VMAX; + break; + + case IMX335_MODE_5M30: + case IMX335_MODE_4M30: + case IMX335_MODE_4M30_2L: + case IMX335_MODE_4M30_1600P: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX335_FULL_LINES_MAX) ? IMX335_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_M].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H].u32Data = ((u32VMAX & 0xF0000) >> 16); + } else { + pstSnsRegsInfo->astI2cData[DOL2_VMAX_L].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_M].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_H].u32Data = ((u32VMAX & 0xF0000) >> 16); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + /* In within FSC mode, RHS1 < 2 * (VMAX - BRL - 1), RHS1 = 8*n+2. */ + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx335_State[ViPipe].u32RHS1_MAX = 2 * (u32VMAX - g_astImx335_State[ViPipe].u32BRL - 1) - 1; + u32Tmp = ((g_astImx335_State[ViPipe].u32RHS1_MAX >> 3) << 3) + 2; + g_astImx335_State[ViPipe].u32RHS1_MAX = (u32Tmp > g_astImx335_State[ViPipe].u32RHS1_MAX) ? + (u32Tmp - 8) : u32Tmp; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* + * DOL mode + * SHR1 : 18 <= SHR1 <= (RHS1 - 4), 4n + 2 + * RHS1 : (SHR1 + 4) <= RHS1 <= (SHR0 - 18), 8n + 2, within FSC mode, RHS1 < 2 * (VMAX - BRL - 1) + * SHR0 : (RHS1 + 18 ) <= SHR0 <= (FSC - 4), 4n + * Max Sexp = RHS1 - SHR1 = RHS1 - 18 + * Max Lexp = FSC - SHR0 = FSC - RHS1 - 18 + * Max Sexp + Lexp = FSC - 36 + * Sexp = (FSC - 36) / (1 + Ratio) + * Depending on the Sexp, we use 22 as the minimum SHR1 rather than 18. + * Thus: + * Sexp = (FSC - 40) / (1 + Ratio). + * Update: The adjustment of SHR0(and RHS1) which reflects at N+2 frame could be less than the minimum + * SHR0 at N+1. This causes the N+1 SEF abnormal. Reserve more blank lines between the end of SEF + * and the beginning of the LEF exposure. + * Thus: + * Sexp = (FSC - 280) / (1 + Ratio). + */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHR1 = 0; + CVI_U32 u32SHR0 = 0; + CVI_U32 module8 = 0, module4 = 0; + + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[1] < u32LongIntTime + 4) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[1], u32LongIntTime + 4); + return CVI_FAILURE; + } + u32SHR0 = pstSnsState->au32FL[1] - u32LongIntTime + (u32LongIntTime % 4); + + module8 = u32ShortIntTime % 8; + module4 = u32ShortIntTime % 4; + + /* SHS1 is 18 or 22. + * when tSef is multiple of 8, SHS1 = 18, RHS1 = 18 + tSEF = 8*n+2. + * otherwise, when mod(tSef, 8) = 5~7, SHS1 = 22, RHS1 = 22 + tSEF - mod(tSef, 4) = 8*n+2. + * when mod(tSef,8) = 0~3, SHS1 = 18, RHS1 = 18 + tSEF - mod(tSef, 4) = 8*n+2 + */ + if (!module8) { + u32SHR1 = 18; + u32RHS1 = u32ShortIntTime + u32SHR1; + } else { + if (module8 == module4) { + u32SHR1 = 18; + u32RHS1 = u32ShortIntTime + u32SHR1 - module4; + } else { + u32SHR1 = 22; + u32RHS1 = u32ShortIntTime + u32SHR1 - module4; + } + } + g_astImx335_State[ViPipe].u32RHS1 = u32RHS1; + g_astImx335_State[ViPipe].u32SHR1 = u32SHR1; + if (u32SHR0 < (u32RHS1 + u32SHR1)) { + u32SHR0 = u32RHS1 + u32SHR1; + } + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - u32SHR1; + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[1] - u32SHR0; + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHR1 = %d\n", u32ShortIntTime, u32SHR1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d\n", ViPipe, u32RHS1); + + + pstSnsRegsInfo->astI2cData[DOL2_SHR0_L].u32Data = (u32SHR0 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHR0_M].u32Data = ((u32SHR0 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHR0_H].u32Data = ((u32SHR0 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHR1_L].u32Data = (u32SHR1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHR1_M].u32Data = ((u32SHR1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHR1_H].u32Data = ((u32SHR1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_L].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_M].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_H].u32Data = ((u32RHS1 & 0xF0000) >> 16); + } else { + u32Value = pstSnsState->au32FL[0] - *u32IntTime; + u32Value = (u32Value > (pstSnsState->au32FL[0] - 1)) ? (pstSnsState->au32FL[0] - 1) : + ((u32Value < 9) ? 9 : u32Value); + pstSnsRegsInfo->astI2cData[LINEAR_SHR_L].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHR_M].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHR_H].u32Data = ((u32Value & 0xF0000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 335567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u16Mode = g_au16Imx335_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_L].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_H].u32Data = ((u32Tmp & 0x700) >> 8); + + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + /* don't support gain conversion in this mode. */ + u32Again = pu32Again[1]; + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0x7FF) { + u32Tmp = 0x7FF; + } + + pstSnsRegsInfo->astI2cData[DOL2_GAIN_L].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_GAIN_H].u32Data = ((u32Tmp & 0x700) >> 8); + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0x7FF) { + u32Tmp = 0x7FF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN_SHORT_L].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_GAIN_SHORT_L].u32Data = ((u32Tmp & 0x700) >> 8); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0x7FF) { + u32Tmp = 0x7FF; + } + + pstSnsRegsInfo->astI2cData[DOL2_GAIN_L].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_GAIN_H].u32Data = ((u32Tmp & 0x700) >> 8); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 4; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 280; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 280 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 280) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx335_State[ViPipe].u32RHS1_MAX - 22)) ? + (g_astImx335_State[ViPipe].u32RHS1_MAX - 22) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX335_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx335_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX335_MODE_5M30_WDR) + pstSnsState->u8ImgMode = IMX335_MODE_5M30; + else if (pstSnsState->u8ImgMode == IMX335_MODE_4M30_WDR) { + if (IMX335_SNNSOR_IS_4L()) + pstSnsState->u8ImgMode = IMX335_MODE_4M30; + else if (IMX335_SNNSOR_IS_2L()) + pstSnsState->u8ImgMode = IMX335_MODE_4M30_2L; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "lane_id is invalid\n"); + return CVI_FAILURE; + } + } else if (pstSnsState->u8ImgMode == IMX335_MODE_4M30_1600P_WDR) + pstSnsState->u8ImgMode = IMX335_MODE_4M30_1600P; + else { + } + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx335_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX335_MODE_5M30) + pstSnsState->u8ImgMode = IMX335_MODE_5M30_WDR; + else if (pstSnsState->u8ImgMode == IMX335_MODE_4M30) + pstSnsState->u8ImgMode = IMX335_MODE_4M30_WDR; + else if (pstSnsState->u8ImgMode == IMX335_MODE_4M30_1600P) + pstSnsState->u8ImgMode = IMX335_MODE_4M30_1600P_WDR; + else { + } + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astImx335_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx335_State[ViPipe].u32BRL = g_astImx335_mode[pstSnsState->u8ImgMode].u16BRL; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx335_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 2; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx335_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx335_addr_byte; + pstI2c_data[i].u32DataByteNum = imx335_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_SHR0_L].u32RegAddr = IMX335_SHR0_L_ADDR; + pstI2c_data[DOL2_SHR0_M].u32RegAddr = IMX335_SHR0_M_ADDR; + pstI2c_data[DOL2_SHR0_H].u32RegAddr = IMX335_SHR0_H_ADDR; + + pstI2c_data[DOL2_GAIN_L].u32RegAddr = IMX335_GAIN_L_ADDR; + pstI2c_data[DOL2_GAIN_L].u8DelayFrmNum = 0; + pstI2c_data[DOL2_GAIN_H].u32RegAddr = IMX335_GAIN_H_ADDR; + pstI2c_data[DOL2_GAIN_H].u8DelayFrmNum = 0; + + pstI2c_data[DOL2_GAIN_SHORT_L].u32RegAddr = IMX335_GAIN_SHORT_L; + pstI2c_data[DOL2_GAIN_SHORT_L].u8DelayFrmNum = 0; + pstI2c_data[DOL2_GAIN_SHORT_H].u32RegAddr = IMX335_GAIN_SHORT_H; + pstI2c_data[DOL2_GAIN_SHORT_H].u8DelayFrmNum = 0; + + pstI2c_data[DOL2_RHS1_L].u32RegAddr = IMX335_RHS1_L_ADDR; + pstI2c_data[DOL2_RHS1_L].u8DelayFrmNum = 0; + pstI2c_data[DOL2_RHS1_M].u32RegAddr = IMX335_RHS1_M_ADDR; + pstI2c_data[DOL2_RHS1_M].u8DelayFrmNum = 0; + pstI2c_data[DOL2_RHS1_H].u32RegAddr = IMX335_RHS1_H_ADDR; + pstI2c_data[DOL2_RHS1_H].u8DelayFrmNum = 0; + + pstI2c_data[DOL2_SHR1_L].u32RegAddr = IMX335_SHR1_L_ADDR; + pstI2c_data[DOL2_SHR1_M].u32RegAddr = IMX335_SHR1_M_ADDR; + pstI2c_data[DOL2_SHR1_H].u32RegAddr = IMX335_SHR1_H_ADDR; + + pstI2c_data[DOL2_VMAX_L].u32RegAddr = IMX335_VMAX_L_ADDR; + pstI2c_data[DOL2_VMAX_L].u8DelayFrmNum = 0; + pstI2c_data[DOL2_VMAX_M].u32RegAddr = IMX335_VMAX_M_ADDR; + pstI2c_data[DOL2_VMAX_M].u8DelayFrmNum = 0; + pstI2c_data[DOL2_VMAX_H].u32RegAddr = IMX335_VMAX_H_ADDR; + pstI2c_data[DOL2_VMAX_H].u8DelayFrmNum = 0; + + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + default: + pstI2c_data[LINEAR_SHR_L].u32RegAddr = IMX335_SHR0_L_ADDR; + pstI2c_data[LINEAR_SHR_M].u32RegAddr = IMX335_SHR0_M_ADDR; + pstI2c_data[LINEAR_SHR_H].u32RegAddr = IMX335_SHR0_H_ADDR; + + pstI2c_data[LINEAR_GAIN_L].u32RegAddr = IMX335_GAIN_L_ADDR; + pstI2c_data[LINEAR_GAIN_H].u32RegAddr = IMX335_GAIN_H_ADDR; + + pstI2c_data[LINEAR_VMAX_L].u32RegAddr = IMX335_VMAX_L_ADDR; + pstI2c_data[LINEAR_VMAX_M].u32RegAddr = IMX335_VMAX_M_ADDR; + pstI2c_data[LINEAR_VMAX_H].u32RegAddr = IMX335_VMAX_H_ADDR; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX335_RES_IS_5M(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = IMX335_MODE_5M30; + else if (IMX335_RES_IS_4M(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + if (IMX335_SNNSOR_IS_4L()) + u8SensorImageMode = IMX335_MODE_4M30; //4 lane + else if (IMX335_SNNSOR_IS_2L()) + u8SensorImageMode = IMX335_MODE_4M30_2L; //2 lane + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "lane_id is invalid\n"); + return CVI_FAILURE; + } + } else if (IMX335_RES_IS_4M_1600P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = IMX335_MODE_4M30_1600P; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX335_RES_IS_5M(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = IMX335_MODE_5M30_WDR; + else if (IMX335_RES_IS_4M(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = IMX335_MODE_4M30_WDR; + else if (IMX335_RES_IS_4M_1600P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = IMX335_MODE_4M30_1600P_WDR; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx335_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx335_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx335_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = IMX335_MODE_4M30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx335_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astImx335_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astImx335_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx335_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx335_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx335_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + + if (pstSnsState->u8ImgMode == IMX335_MODE_4M30_2L) + pstRxAttr->mipi_attr.raw_data_type = RAW_DATA_10BIT; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstRxAttr->mac_clk = RX_MAC_CLK_600M; + pstRxAttr->mipi_attr.raw_data_type = RAW_DATA_10BIT; + } else { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx335_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx335_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx335_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx335_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx335_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX335_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX335_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX335_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX335_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX335_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx335_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return imx335_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsImx335_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx335_standby, + .pfnRestart = imx335_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx335_write_register, + .pfnReadReg = imx335_read_register, + .pfnSetBusInfo = imx335_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx335/imx335_cmos_ex.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx335/imx335_cmos_ex.h new file mode 100644 index 000000000..d0fdd46f2 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx335/imx335_cmos_ex.h @@ -0,0 +1,115 @@ +#ifndef __IMX335_CMOS_EX_H_ +#define __IMX335_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +enum imx335_linear_regs_e { + LINEAR_SHR_L = 0, + LINEAR_SHR_M, + LINEAR_SHR_H, + LINEAR_GAIN_H, + LINEAR_GAIN_L, + LINEAR_VMAX_L, + LINEAR_VMAX_M, + LINEAR_VMAX_H, + LINEAR_REGS_NUM +}; + +enum imx335_dol2_regs_e { + DOL2_SHR0_L = 0, + DOL2_SHR0_M, + DOL2_SHR0_H, + DOL2_GAIN_L, + DOL2_GAIN_H, + DOL2_GAIN_SHORT_L, + DOL2_GAIN_SHORT_H, + DOL2_RHS1_L, + DOL2_RHS1_M, + DOL2_RHS1_H, + DOL2_SHR1_L, + DOL2_SHR1_M, + DOL2_SHR1_H, + DOL2_VMAX_L, + DOL2_VMAX_M, + DOL2_VMAX_H, + DOL2_REGS_NUM +}; + +typedef enum _IMX335_MODE_E { + IMX335_MODE_5M30 = 0, + IMX335_MODE_4M30, + IMX335_MODE_4M30_2L, + IMX335_MODE_4M30_1600P, + IMX335_MODE_LINEAR_NUM, + IMX335_MODE_5M30_WDR = IMX335_MODE_LINEAR_NUM, + IMX335_MODE_4M30_WDR, + IMX335_MODE_4M30_1600P_WDR, + IMX335_MODE_NUM +} IMX335_MODE_E; + +typedef struct _IMX335_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32SHR1; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX335_STATE_S; + +typedef struct _IMX335_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX335_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx335[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx335_BusInfo[]; +extern CVI_U16 g_au16Imx335_GainMode[]; +extern const CVI_U8 imx335_i2c_addr; +extern const CVI_U32 imx335_addr_byte; +extern const CVI_U32 imx335_data_byte; +extern void imx335_init(VI_PIPE ViPipe); +extern void imx335_exit(VI_PIPE ViPipe); +extern void imx335_standby(VI_PIPE ViPipe); +extern void imx335_restart(VI_PIPE ViPipe); +extern int imx335_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx335_read_register(VI_PIPE ViPipe, int addr); +extern void imx335_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int imx335_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + +#endif /* __IMX335_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx335/imx335_cmos_param.h b/middleware/v2/component/isp/sensor/cv180x/sony_imx335/imx335_cmos_param.h new file mode 100644 index 000000000..791a6698c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx335/imx335_cmos_param.h @@ -0,0 +1,577 @@ +#ifndef __IMX335_CMOS_PARAM_H_ +#define __IMX335_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx335_cmos_ex.h" + +static const IMX335_MODE_S g_astImx335_mode[IMX335_MODE_NUM] = { + [IMX335_MODE_4M30_1600P] = { + .name = "4M30_1600P", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2592, + .u32Height = 1620, + }, + .stWndRect = { + .s32X = 16, + .s32Y = 10, + .u32Width = 2560, + .u32Height = 1600, + }, + .stMaxSize = { + .u32Width = 2592, + .u32Height = 1620, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 0x1194 * 30 / 0xFFFFF */ + .u32HtsDef = 0x226, //hmax + .u32VtsDef = 0x1194, //vmax + .stExp[0] = { + .u16Min = 9, + .u16Max = 0x1194 - 1, + .u16Def = 9, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 32381, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 128914, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [IMX335_MODE_4M30] = { + .name = "4M30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2592, + .u32Height = 1460, + }, + .stWndRect = { + .s32X = 16, + .s32Y = 10, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2592, + .u32Height = 1460, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 0x1194 * 30 / 0xFFFFF */ + .u32HtsDef = 0x226, //hmax + .u32VtsDef = 0x1194, //vmax + .stExp[0] = { + .u16Min = 9, + .u16Max = 0x1194 - 1, + .u16Def = 9, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 32381, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 128914, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [IMX335_MODE_4M30_2L] = { + .name = "4M30_2L", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2568, + .u32Height = 1444, + }, + .stWndRect = { + .s32X = 4, + .s32Y = 2, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2568, + .u32Height = 1444, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 0x1194 * 30 / 0xFFFFF */ + .u32HtsDef = 0xA08, //hmax + .u32VtsDef = 0x1194, //vmax + .stExp[0] = { + .u16Min = 9, + .u16Max = 0x1194 - 1, + .u16Def = 9, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 32381, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 128914, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [IMX335_MODE_5M30] = { + .name = "5M30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2616, + .u32Height = 1964, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 12, + .u32Width = 2592, + .u32Height = 1944, + }, + .stMaxSize = { + .u32Width = 2616, + .u32Height = 1964, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 0x1194 * 30 / 0xFFFFF */ + .u32HtsDef = 0x226, //hmax + .u32VtsDef = 0x1194, //vmax + .stExp[0] = { + .u16Min = 9, + .u16Max = 0x1194 - 1, + .u16Def = 9, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 32381, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 128914, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [IMX335_MODE_5M30_WDR] = { + .name = "5M30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 2616, + .u32Height = 1964, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 12, + .u32Width = 2592, + .u32Height = 1944, + }, + .stMaxSize = { + .u32Width = 2616, + .u32Height = 1964, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 2616, + .u32Height = 1964, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 12, + .u32Width = 2592, + .u32Height = 1944, + }, + .stMaxSize = { + .u32Width = 2616, + .u32Height = 1964, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 0x1194 * 30 / 0xFFFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 0x1194, + .stExp[0] = { + .u16Min = 8, + .u16Max = 481, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 128, + .u16Max = 7696, + .u16Def = 128, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 62416, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 62416, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 38485, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 38485, + .u32Def = 1024, + .u32Step = 1, + }, + .u16BRL = 3968, + }, + [IMX335_MODE_4M30_WDR] = { + .name = "4M30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 2616, + .u32Height = 1460, + }, + .stWndRect = { + .s32X = 28, + .s32Y = 10, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2616, + .u32Height = 1460, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 2616, + .u32Height = 1460, + }, + .stWndRect = { + .s32X = 28, + .s32Y = 10, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2616, + .u32Height = 1460, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 0x1194 * 30 / 0xFFFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 0x1194, + .stExp[0] = { + .u16Min = 8, + .u16Max = 481, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 128, + .u16Max = 7696, + .u16Def = 128, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 62416, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 62416, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 38485, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 38485, + .u32Def = 1024, + .u32Step = 1, + }, + .u16BRL = (1440 + 20) * 2, + }, + [IMX335_MODE_4M30_1600P_WDR] = { + .name = "4M30_1600P_wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 2592, + .u32Height = 1620, + }, + .stWndRect = { + .s32X = 16, + .s32Y = 10, + .u32Width = 2560, + .u32Height = 1600, + }, + .stMaxSize = { + .u32Width = 2592, + .u32Height = 1620, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 2592, + .u32Height = 1620, + }, + .stWndRect = { + .s32X = 16, + .s32Y = 10, + .u32Width = 2560, + .u32Height = 1600, + }, + .stMaxSize = { + .u32Width = 2592, + .u32Height = 1620, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 0x1194 * 30 / 0xFFFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 0x1194, + .stExp[0] = { + .u16Min = 8, + .u16Max = 481, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 128, + .u16Max = 7696, + .u16Def = 128, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 62416, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 62416, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 38485, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 38485, + .u32Def = 1024, + .u32Step = 1, + }, + .u16BRL = (1440 + 20) * 2, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.02535128779709339142, 1.61768496036529541016}, //B: slope, intercept + {0.00795035623013973236, 15.21613883972167968750}, //Gb: slope, intercept + {0.01330664381384849548, 10.40423774719238281250}, //Gr: slope, intercept + {0.02679967880249023438, 1.82649695873260498047}, //R: slope, intercept + }, + { //iso 200 + {0.02753821015357971191, 6.47844934463500976563}, //B: slope, intercept + {0.00463790073990821838, 25.24199485778808593750}, //Gb: slope, intercept + {0.00451094703748822212, 25.23709869384765625000}, //Gr: slope, intercept + {0.02894908934831619263, 6.20713567733764648438}, //R: slope, intercept + }, + { //iso 400 + {0.03178063780069351196, 12.60536384582519531250}, //B: slope, intercept + {0.00517552718520164490, 35.03299713134765625000}, //Gb: slope, intercept + {0.00502182589843869209, 35.23723602294921875000}, //Gr: slope, intercept + {0.03328817337751388550, 12.19208049774169921875}, //R: slope, intercept + }, + { //iso 800 + {0.03747911751270294189, 21.80648422241210937500}, //B: slope, intercept + {0.00625439779832959175, 49.06682205200195312500}, //Gb: slope, intercept + {0.00620671268552541733, 49.14254379272460937500}, //Gr: slope, intercept + {0.03955777361989021301, 20.63272857666015625000}, //R: slope, intercept + }, + { //iso 1600 + {0.04763090237975120544, 34.16785049438476562500}, //B: slope, intercept + {0.00715198600664734840, 70.35113525390625000000}, //Gb: slope, intercept + {0.00717207882553339005, 70.42241668701171875000}, //Gr: slope, intercept + {0.05030791088938713074, 32.31000518798828125000}, //R: slope, intercept + }, + { //iso 3200 + {0.06291828304529190063, 51.79273986816406250000}, //B: slope, intercept + {0.00942948460578918457, 99.58425903320312500000}, //Gb: slope, intercept + {0.00938474666327238083, 99.87895202636718750000}, //Gr: slope, intercept + {0.06596329063177108765, 49.59438705444335937500}, //R: slope, intercept + }, + { //iso 6400 + {0.08704897761344909668, 76.54403686523437500000}, //B: slope, intercept + {0.02136226370930671692, 135.76541137695312500000}, //Gb: slope, intercept + {0.02061788551509380341, 136.24209594726562500000}, //Gr: slope, intercept + {0.09058564901351928711, 73.56949615478515625000}, //R: slope, intercept + }, + { //iso 12800 + {0.11864978075027465820, 116.15978240966796875000}, //B: slope, intercept + {0.03285352513194084167, 193.26387023925781250000}, //Gb: slope, intercept + {0.03131035342812538147, 194.77830505371093750000}, //Gr: slope, intercept + {0.12536112964153289795, 110.30144500732421875000}, //R: slope, intercept + }, + { //iso 25600 + {0.16936406493186950684, 172.24114990234375000000}, //B: slope, intercept + {0.05775514617562294006, 267.55535888671875000000}, //Gb: slope, intercept + {0.05725358799099922180, 268.19198608398437500000}, //Gr: slope, intercept + {0.17778857052326202393, 166.38156127929687500000}, //R: slope, intercept + }, + { //iso 51200 + {0.23955665528774261475, 255.52276611328125000000}, //B: slope, intercept + {0.09076436609029769897, 378.79702758789062500000}, //Gb: slope, intercept + {0.08728235960006713867, 384.05020141601562500000}, //Gr: slope, intercept + {0.25822344422340393066, 249.06506347656250000000}, //R: slope, intercept + }, + { //iso 102400 + {0.36010745167732238770, 362.82952880859375000000}, //B: slope, intercept + {0.15752448141574859619, 513.11077880859375000000}, //Gb: slope, intercept + {0.15595595538616180420, 518.77105712890625000000}, //Gr: slope, intercept + {0.38190475106239318848, 360.52606201171875000000}, //R: slope, intercept + }, + { //iso 204800 + {0.44082218408584594727, 536.35937500000000000000}, //B: slope, intercept + {0.22994761168956756592, 701.87817382812500000000}, //Gb: slope, intercept + {0.22570468485355377197, 707.03558349609375000000}, //Gr: slope, intercept + {0.46145606040954589844, 543.70227050781250000000}, //R: slope, intercept + }, + { //iso 409600 + {0.24378113448619842529, 865.24688720703125000000}, //B: slope, intercept + {0.06541594862937927246, 1050.97998046875000000000}, //Gb: slope, intercept + {0.06018084660172462463, 1068.13745117187500000000}, //Gr: slope, intercept + {0.25154441595077514648, 904.18511962890625000000}, //R: slope, intercept + }, + { //iso 819200 + {0.24305926263332366943, 867.16644287109375000000}, //B: slope, intercept + {0.06559922546148300171, 1050.18383789062500000000}, //Gb: slope, intercept + {0.06018084660172462463, 1068.13745117187500000000}, //Gr: slope, intercept + {0.25154441595077514648, 904.18511962890625000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.24378113448619842529, 865.24688720703125000000}, //B: slope, intercept + {0.06582942605018615723, 1048.96228027343750000000}, //Gb: slope, intercept + {0.06089610978960990906, 1064.75537109375000000000}, //Gr: slope, intercept + {0.25244551897048950195, 901.38049316406250000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.24428291618824005127, 863.30468750000000000000}, //B: slope, intercept + {0.06582942605018615723, 1048.96228027343750000000}, //Gb: slope, intercept + {0.06080029532313346863, 1065.15185546875000000000}, //Gr: slope, intercept + {0.25226309895515441895, 901.83532714843750000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {200, 200, 200, 200, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1076, 1076, 1076, 1076 +#endif + }, + .stAuto = { + {199, 201, 201, 200, 202, 202, 203, 206, /*8*/219, 270, 409, 679, 1023, 1023, 1023, 1023}, + {200, 201, 201, 200, 201, 199, 199, 197, /*8*/201, 242, 357, 588, 974, 974, 982, 981}, + {200, 201, 201, 200, 201, 200, 200, 199, /*8*/205, 248, 370, 609, 1007, 1009, 1012, 1012}, + {199, 201, 201, 200, 202, 202, 203, 207, /*8*/219, 270, 408, 674, 1023, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1076, 1077, 1077, 1077, 1077, 1077, 1077, 1078, + /*8*/1082, 1096, 1138, 1228, 1365, 1365, 1365, 1365}, + {1077, 1077, 1077, 1077, 1077, 1076, 1076, 1076, + /*8*/1077, 1088, 1122, 1196, 1344, 1344, 1347, 1347}, + {1077, 1077, 1077, 1077, 1077, 1077, 1077, 1076, + /*8*/1078, 1090, 1126, 1203, 1358, 1359, 1360, 1360}, + {1076, 1077, 1077, 1077, 1077, 1077, 1077, 1079, + /*8*/1082, 1096, 1137, 1226, 1365, 1365, 1365, 1365}, +#endif + }, + }, +}; + +struct combo_dev_attr_s imx335_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_400M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {2, 0, 1, 3, 4}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + +#endif /* __IMX335_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv180x/sony_imx335/imx335_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv180x/sony_imx335/imx335_sensor_ctl.c new file mode 100644 index 000000000..4c69dd20f --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv180x/sony_imx335/imx335_sensor_ctl.c @@ -0,0 +1,1000 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx335_cmos_ex.h" +static void imx335_wdr_5M30_2to1_init(VI_PIPE ViPipe); +static void imx335_wdr_4M30_2to1_init(VI_PIPE ViPipe); +static void imx335_wdr_4M30_1600p_2to1_init(VI_PIPE ViPipe); + +static void imx335_linear_5M30_init(VI_PIPE ViPipe); +static void imx335_linear_4M30_init(VI_PIPE ViPipe); +static void imx335_linear_4M30_2l_init(VI_PIPE ViPipe); +static void imx335_linear_4M30_1600p_init(VI_PIPE ViPipe); + +const CVI_U8 imx335_i2c_addr = 0x1A; + +const CVI_U32 imx335_addr_byte = 2; +const CVI_U32 imx335_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx335_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx335_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx335_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int imx335_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx335_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (imx335_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, imx335_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, imx335_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (imx335_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int imx335_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx335_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx335_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx335_addr_byte + imx335_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx335_standby(VI_PIPE ViPipe) +{ + imx335_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx335_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ +} + +void imx335_restart(VI_PIPE ViPipe) +{ + imx335_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx335_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + //imx335_write_register(ViPipe, 0x304b, 0x0a); +} + +void imx335_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx335[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx335_write_register(ViPipe, + g_pastImx335[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx335[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void imx335_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 u8Filp = 0; + CVI_U8 u8Mirror = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + u8Mirror = 1; + break; + case ISP_SNS_FLIP: + u8Filp = 1; + break; + case ISP_SNS_MIRROR_FLIP: + u8Filp = 1; + u8Mirror = 1; + break; + default: + return; + } + + imx335_write_register(ViPipe, 0x304e, u8Mirror); + imx335_write_register(ViPipe, 0x304f, u8Filp); + if (u8Filp != 0) { + imx335_write_register(ViPipe, 0x3074, 0x10); + imx335_write_register(ViPipe, 0x3075, 0x10); + imx335_write_register(ViPipe, 0x3081, 0xfe); + imx335_write_register(ViPipe, 0x3083, 0xfe); + imx335_write_register(ViPipe, 0x30b6, 0xfa); + imx335_write_register(ViPipe, 0x30b7, 0x01); + imx335_write_register(ViPipe, 0x3116, 0x02); + imx335_write_register(ViPipe, 0x3117, 0x00); + } else { + imx335_write_register(ViPipe, 0x3074, 0xb0); + imx335_write_register(ViPipe, 0x3075, 0x00); + imx335_write_register(ViPipe, 0x3081, 0x02); + imx335_write_register(ViPipe, 0x3083, 0x02); + imx335_write_register(ViPipe, 0x30b6, 0x00); + imx335_write_register(ViPipe, 0x30b7, 0x00); + imx335_write_register(ViPipe, 0x3116, 0x08); + imx335_write_register(ViPipe, 0x3117, 0x00); + } +} + +int imx335_probe(VI_PIPE ViPipe) +{ + int nVal; + + usleep(100); + if (imx335_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = imx335_read_register(ViPipe, 0x3000); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + return CVI_SUCCESS; +} + +void imx335_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastImx335[ViPipe]->enWDRMode; + u8ImgMode = g_pastImx335[ViPipe]->u8ImgMode; + + imx335_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == IMX335_MODE_5M30_WDR) + imx335_wdr_5M30_2to1_init(ViPipe); + else if (u8ImgMode == IMX335_MODE_4M30_WDR) + imx335_wdr_4M30_2to1_init(ViPipe); + else if (u8ImgMode == IMX335_MODE_4M30_1600P_WDR) + imx335_wdr_4M30_1600p_2to1_init(ViPipe); + else{ + } + } else { + if (u8ImgMode == IMX335_MODE_5M30) + imx335_linear_5M30_init(ViPipe); + else if (u8ImgMode == IMX335_MODE_4M30) + imx335_linear_4M30_init(ViPipe); + else if (u8ImgMode == IMX335_MODE_4M30_2L) + imx335_linear_4M30_2l_init(ViPipe); + else if (u8ImgMode == IMX335_MODE_4M30_1600P) + imx335_linear_4M30_1600p_init(ViPipe); + else { + } + } + g_pastImx335[ViPipe]->bInit = CVI_TRUE; +} + +void imx335_exit(VI_PIPE ViPipe) +{ + imx335_i2c_exit(ViPipe); +} +static void imx335_linear_4M30_init(VI_PIPE ViPipe) +{ + delay_ms(4); + imx335_write_register(ViPipe, 0x3000, 0x01); // STANDBY + imx335_write_register(ViPipe, 0x3002, 0x01); // XTMSTA + + imx335_write_register(ViPipe, 0x300C, 0x5B); + imx335_write_register(ViPipe, 0x300D, 0x40); + imx335_write_register(ViPipe, 0x3018, 0x04);// WINMODE[3:0] croping mode + imx335_write_register(ViPipe, 0x302C, 0x3C); + imx335_write_register(ViPipe, 0x302E, 0x20); + imx335_write_register(ViPipe, 0x3056, 0xB4);//Y_OUT_SIZE[12:0] + imx335_write_register(ViPipe, 0x3057, 0x05); + imx335_write_register(ViPipe, 0x3074, 0xA8); + imx335_write_register(ViPipe, 0x3075, 0x02); + imx335_write_register(ViPipe, 0x3076, 0x68); + imx335_write_register(ViPipe, 0x3077, 0x0B); + imx335_write_register(ViPipe, 0x30C6, 0x12); + imx335_write_register(ViPipe, 0x30CE, 0x64); + imx335_write_register(ViPipe, 0x30D8, 0xE0); + imx335_write_register(ViPipe, 0x30D9, 0x0E); + imx335_write_register(ViPipe, 0x314C, 0xC0); + imx335_write_register(ViPipe, 0x315A, 0x06); + imx335_write_register(ViPipe, 0x316A, 0x7E); + imx335_write_register(ViPipe, 0x319E, 0x02); + imx335_write_register(ViPipe, 0x31A1, 0x00); + imx335_write_register(ViPipe, 0x3288, 0x21); + imx335_write_register(ViPipe, 0x328A, 0x02); + imx335_write_register(ViPipe, 0x3414, 0x05); + imx335_write_register(ViPipe, 0x3416, 0x18); + imx335_write_register(ViPipe, 0x3648, 0x01); + imx335_write_register(ViPipe, 0x364A, 0x04); + imx335_write_register(ViPipe, 0x364C, 0x04); + imx335_write_register(ViPipe, 0x3678, 0x01); + imx335_write_register(ViPipe, 0x367C, 0x31); + imx335_write_register(ViPipe, 0x367E, 0x31); + imx335_write_register(ViPipe, 0x3706, 0x10); + imx335_write_register(ViPipe, 0x3708, 0x03); + imx335_write_register(ViPipe, 0x3714, 0x02); + imx335_write_register(ViPipe, 0x3715, 0x02); + imx335_write_register(ViPipe, 0x3716, 0x01); + imx335_write_register(ViPipe, 0x3717, 0x03); + imx335_write_register(ViPipe, 0x371C, 0x3D); + imx335_write_register(ViPipe, 0x371D, 0x3F); + imx335_write_register(ViPipe, 0x372C, 0x00); + imx335_write_register(ViPipe, 0x372D, 0x00); + imx335_write_register(ViPipe, 0x372E, 0x46); + imx335_write_register(ViPipe, 0x372F, 0x00); + imx335_write_register(ViPipe, 0x3730, 0x89); + imx335_write_register(ViPipe, 0x3731, 0x00); + imx335_write_register(ViPipe, 0x3732, 0x08); + imx335_write_register(ViPipe, 0x3733, 0x01); + imx335_write_register(ViPipe, 0x3734, 0xFE); + imx335_write_register(ViPipe, 0x3735, 0x05); + imx335_write_register(ViPipe, 0x3740, 0x02); + imx335_write_register(ViPipe, 0x375D, 0x00); + imx335_write_register(ViPipe, 0x375E, 0x00); + imx335_write_register(ViPipe, 0x375F, 0x11); + imx335_write_register(ViPipe, 0x3760, 0x01); + imx335_write_register(ViPipe, 0x3768, 0x1B); + imx335_write_register(ViPipe, 0x3769, 0x1B); + imx335_write_register(ViPipe, 0x376A, 0x1B); + imx335_write_register(ViPipe, 0x376B, 0x1B); + imx335_write_register(ViPipe, 0x376C, 0x1A); + imx335_write_register(ViPipe, 0x376D, 0x17); + imx335_write_register(ViPipe, 0x376E, 0x0F); + imx335_write_register(ViPipe, 0x3776, 0x00); + imx335_write_register(ViPipe, 0x3777, 0x00); + imx335_write_register(ViPipe, 0x3778, 0x46); + imx335_write_register(ViPipe, 0x3779, 0x00); + imx335_write_register(ViPipe, 0x377A, 0x89); + imx335_write_register(ViPipe, 0x377B, 0x00); + imx335_write_register(ViPipe, 0x377C, 0x08); + imx335_write_register(ViPipe, 0x377D, 0x01); + imx335_write_register(ViPipe, 0x377E, 0x23); + imx335_write_register(ViPipe, 0x377F, 0x02); + imx335_write_register(ViPipe, 0x3780, 0xD9); + imx335_write_register(ViPipe, 0x3781, 0x03); + imx335_write_register(ViPipe, 0x3782, 0xF5); + imx335_write_register(ViPipe, 0x3783, 0x06); + imx335_write_register(ViPipe, 0x3784, 0xA5); + imx335_write_register(ViPipe, 0x3788, 0x0F); + imx335_write_register(ViPipe, 0x378A, 0xD9); + imx335_write_register(ViPipe, 0x378B, 0x03); + imx335_write_register(ViPipe, 0x378C, 0xEB); + imx335_write_register(ViPipe, 0x378D, 0x05); + imx335_write_register(ViPipe, 0x378E, 0x87); + imx335_write_register(ViPipe, 0x378F, 0x06); + imx335_write_register(ViPipe, 0x3790, 0xF5); + imx335_write_register(ViPipe, 0x3792, 0x43); + imx335_write_register(ViPipe, 0x3794, 0x7A); + imx335_write_register(ViPipe, 0x3796, 0xA1); + imx335_write_register(ViPipe, 0x3A18, 0x7F); + imx335_write_register(ViPipe, 0x3A1A, 0x37); + imx335_write_register(ViPipe, 0x3A1C, 0x37); + imx335_write_register(ViPipe, 0x3A1E, 0xF7); + imx335_write_register(ViPipe, 0x3A1F, 0x00); + imx335_write_register(ViPipe, 0x3A20, 0x3F); + imx335_write_register(ViPipe, 0x3A22, 0x6F); + imx335_write_register(ViPipe, 0x3A24, 0x3F); + imx335_write_register(ViPipe, 0x3A26, 0x5F); + imx335_write_register(ViPipe, 0x3A28, 0x2F); + imx335_default_reg_init(ViPipe); + + imx335_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx335_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe:%d,===IMX335 4M 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void imx335_linear_4M30_2l_init(VI_PIPE ViPipe) +{ + delay_ms(4); + imx335_write_register(ViPipe, 0x3000, 0x01); // STANDBY + imx335_write_register(ViPipe, 0x3002, 0x01); // XTMSTA + + imx335_write_register(ViPipe, 0x300C, 0x5B); // BCWAIT_TIME[7:0] + imx335_write_register(ViPipe, 0x300D, 0x40); // CPWAIT_TIME[7:0] + imx335_write_register(ViPipe, 0x3018, 0x04); // WINMODE[3:0] + imx335_write_register(ViPipe, 0x302C, 0x48); // HTRIMMING_START[11:0] + imx335_write_register(ViPipe, 0x302E, 0x08); // HNUM[11:0] + imx335_write_register(ViPipe, 0x3050, 0x00); // ADBIT[0] + imx335_write_register(ViPipe, 0x3056, 0xA4); // Y_OUT_SIZE[12:0] + imx335_write_register(ViPipe, 0x3057, 0x05); // + imx335_write_register(ViPipe, 0x3074, 0xB8); // AREA3_ST_ADR_1[12:0] + imx335_write_register(ViPipe, 0x3075, 0x02); // + imx335_write_register(ViPipe, 0x3076, 0x48); // AREA3_WIDTH_1[12:0] + imx335_write_register(ViPipe, 0x3077, 0x0B); // + imx335_write_register(ViPipe, 0x30C6, 0x12); // BLACK_OFSET_ADR[12:0] + imx335_write_register(ViPipe, 0x30CE, 0x64); // UNRD_LINE_MAX[12:0] + imx335_write_register(ViPipe, 0x30D8, 0xD0); // UNREAD_ED_ADR[12:0] + imx335_write_register(ViPipe, 0x30D9, 0x0E); // + imx335_write_register(ViPipe, 0x315A, 0x02); // INCKSEL2[1:0] + imx335_write_register(ViPipe, 0x316A, 0x7E); // INCKSEL4[1:0] + imx335_write_register(ViPipe, 0x319D, 0x00); // MDBIT + imx335_write_register(ViPipe, 0x31A1, 0x00); // XVS_DRV[1:0] + imx335_write_register(ViPipe, 0x3288, 0x21); // - + imx335_write_register(ViPipe, 0x328A, 0x02); // - + imx335_write_register(ViPipe, 0x3414, 0x05); // - + imx335_write_register(ViPipe, 0x3416, 0x18); // - + imx335_write_register(ViPipe, 0x341C, 0xFF); // ADBIT1[8:0] + imx335_write_register(ViPipe, 0x341D, 0x01); // + imx335_write_register(ViPipe, 0x3648, 0x01); // - + imx335_write_register(ViPipe, 0x364A, 0x04); // - + imx335_write_register(ViPipe, 0x364C, 0x04); // - + imx335_write_register(ViPipe, 0x3678, 0x01); // - + imx335_write_register(ViPipe, 0x367C, 0x31); // - + imx335_write_register(ViPipe, 0x367E, 0x31); // - + imx335_write_register(ViPipe, 0x3706, 0x10); // - + imx335_write_register(ViPipe, 0x3708, 0x03); // - + imx335_write_register(ViPipe, 0x3714, 0x02); // - + imx335_write_register(ViPipe, 0x3715, 0x02); // - + imx335_write_register(ViPipe, 0x3716, 0x01); // - + imx335_write_register(ViPipe, 0x3717, 0x03); // - + imx335_write_register(ViPipe, 0x371C, 0x3D); // - + imx335_write_register(ViPipe, 0x371D, 0x3F); // - + imx335_write_register(ViPipe, 0x372C, 0x00); // - + imx335_write_register(ViPipe, 0x372D, 0x00); // - + imx335_write_register(ViPipe, 0x372E, 0x46); // - + imx335_write_register(ViPipe, 0x372F, 0x00); // - + imx335_write_register(ViPipe, 0x3730, 0x89); // - + imx335_write_register(ViPipe, 0x3731, 0x00); // - + imx335_write_register(ViPipe, 0x3732, 0x08); // - + imx335_write_register(ViPipe, 0x3733, 0x01); // - + imx335_write_register(ViPipe, 0x3734, 0xFE); // - + imx335_write_register(ViPipe, 0x3735, 0x05); // - + imx335_write_register(ViPipe, 0x3740, 0x02); // - + imx335_write_register(ViPipe, 0x375D, 0x00); // - + imx335_write_register(ViPipe, 0x375E, 0x00); // - + imx335_write_register(ViPipe, 0x375F, 0x11); // - + imx335_write_register(ViPipe, 0x3760, 0x01); // - + imx335_write_register(ViPipe, 0x3768, 0x1A); // - + imx335_write_register(ViPipe, 0x3769, 0x1A); // - + imx335_write_register(ViPipe, 0x376A, 0x1A); // - + imx335_write_register(ViPipe, 0x376B, 0x1A); // - + imx335_write_register(ViPipe, 0x376C, 0x1A); // - + imx335_write_register(ViPipe, 0x376D, 0x17); // - + imx335_write_register(ViPipe, 0x376E, 0x0F); // - + imx335_write_register(ViPipe, 0x3776, 0x00); // - + imx335_write_register(ViPipe, 0x3777, 0x00); // - + imx335_write_register(ViPipe, 0x3778, 0x46); // - + imx335_write_register(ViPipe, 0x3779, 0x00); // - + imx335_write_register(ViPipe, 0x377A, 0x89); // - + imx335_write_register(ViPipe, 0x377B, 0x00); // - + imx335_write_register(ViPipe, 0x377C, 0x08); // - + imx335_write_register(ViPipe, 0x377D, 0x01); // - + imx335_write_register(ViPipe, 0x377E, 0x23); // - + imx335_write_register(ViPipe, 0x377F, 0x02); // - + imx335_write_register(ViPipe, 0x3780, 0xD9); // - + imx335_write_register(ViPipe, 0x3781, 0x03); // - + imx335_write_register(ViPipe, 0x3782, 0xF5); // - + imx335_write_register(ViPipe, 0x3783, 0x06); // - + imx335_write_register(ViPipe, 0x3784, 0xA5); // - + imx335_write_register(ViPipe, 0x3788, 0x0F); // - + imx335_write_register(ViPipe, 0x378A, 0xD9); // - + imx335_write_register(ViPipe, 0x378B, 0x03); // - + imx335_write_register(ViPipe, 0x378C, 0xEB); // - + imx335_write_register(ViPipe, 0x378D, 0x05); // - + imx335_write_register(ViPipe, 0x378E, 0x87); // - + imx335_write_register(ViPipe, 0x378F, 0x06); // - + imx335_write_register(ViPipe, 0x3790, 0xF5); // - + imx335_write_register(ViPipe, 0x3792, 0x43); // - + imx335_write_register(ViPipe, 0x3794, 0x7A); // - + imx335_write_register(ViPipe, 0x3796, 0xA1); // - + imx335_write_register(ViPipe, 0x3A01, 0x01); // LANEMODE[2:0] + imx335_default_reg_init(ViPipe); + + imx335_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx335_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe:%d,===IMX335 4M 30fps 2L 10bit LINE Init OK!===\n", ViPipe); +} + +static void imx335_linear_4M30_1600p_init(VI_PIPE ViPipe) +{ + delay_ms(4); + imx335_write_register(ViPipe, 0x3000, 0x01); // STANDBY + imx335_write_register(ViPipe, 0x3002, 0x01); // XTMSTA + + imx335_write_register(ViPipe, 0x300C, 0x5B); + imx335_write_register(ViPipe, 0x300D, 0x40); + imx335_write_register(ViPipe, 0x3018, 0x04);// WINMODE[3:0] croping mode + imx335_write_register(ViPipe, 0x302C, 0x3C); + imx335_write_register(ViPipe, 0x302E, 0x20); + imx335_write_register(ViPipe, 0x3056, 0x54);//Y_OUT_SIZE[12:0] + imx335_write_register(ViPipe, 0x3057, 0x06); + imx335_write_register(ViPipe, 0x3074, 0x08); + imx335_write_register(ViPipe, 0x3075, 0x02); + imx335_write_register(ViPipe, 0x3076, 0xA8); + imx335_write_register(ViPipe, 0x3077, 0x0C); + imx335_write_register(ViPipe, 0x30C6, 0x12); + imx335_write_register(ViPipe, 0x30CE, 0x64); + imx335_write_register(ViPipe, 0x30D8, 0x80); + imx335_write_register(ViPipe, 0x30D9, 0x0F); + imx335_write_register(ViPipe, 0x315A, 0x02); + imx335_write_register(ViPipe, 0x316A, 0x7E); + imx335_write_register(ViPipe, 0x31A1, 0x00); + imx335_write_register(ViPipe, 0x3288, 0x21); + imx335_write_register(ViPipe, 0x328A, 0x02); + imx335_write_register(ViPipe, 0x3414, 0x05); + imx335_write_register(ViPipe, 0x3416, 0x18); + imx335_write_register(ViPipe, 0x3648, 0x01); + imx335_write_register(ViPipe, 0x364A, 0x04); + imx335_write_register(ViPipe, 0x364C, 0x04); + imx335_write_register(ViPipe, 0x3678, 0x01); + imx335_write_register(ViPipe, 0x367C, 0x31); + imx335_write_register(ViPipe, 0x367E, 0x31); + imx335_write_register(ViPipe, 0x3706, 0x10); + imx335_write_register(ViPipe, 0x3708, 0x03); + imx335_write_register(ViPipe, 0x3714, 0x02); + imx335_write_register(ViPipe, 0x3715, 0x02); + imx335_write_register(ViPipe, 0x3716, 0x01); + imx335_write_register(ViPipe, 0x3717, 0x03); + imx335_write_register(ViPipe, 0x371C, 0x3D); + imx335_write_register(ViPipe, 0x371D, 0x3F); + imx335_write_register(ViPipe, 0x372C, 0x00); + imx335_write_register(ViPipe, 0x372D, 0x00); + imx335_write_register(ViPipe, 0x372E, 0x46); + imx335_write_register(ViPipe, 0x372F, 0x00); + imx335_write_register(ViPipe, 0x3730, 0x89); + imx335_write_register(ViPipe, 0x3731, 0x00); + imx335_write_register(ViPipe, 0x3732, 0x08); + imx335_write_register(ViPipe, 0x3733, 0x01); + imx335_write_register(ViPipe, 0x3734, 0xFE); + imx335_write_register(ViPipe, 0x3735, 0x05); + imx335_write_register(ViPipe, 0x3740, 0x02); + imx335_write_register(ViPipe, 0x375D, 0x00); + imx335_write_register(ViPipe, 0x375E, 0x00); + imx335_write_register(ViPipe, 0x375F, 0x11); + imx335_write_register(ViPipe, 0x3760, 0x01); + imx335_write_register(ViPipe, 0x3768, 0x1B); + imx335_write_register(ViPipe, 0x3769, 0x1B); + imx335_write_register(ViPipe, 0x376A, 0x1B); + imx335_write_register(ViPipe, 0x376B, 0x1B); + imx335_write_register(ViPipe, 0x376C, 0x1A); + imx335_write_register(ViPipe, 0x376D, 0x17); + imx335_write_register(ViPipe, 0x376E, 0x0F); + imx335_write_register(ViPipe, 0x3776, 0x00); + imx335_write_register(ViPipe, 0x3777, 0x00); + imx335_write_register(ViPipe, 0x3778, 0x46); + imx335_write_register(ViPipe, 0x3779, 0x00); + imx335_write_register(ViPipe, 0x377A, 0x89); + imx335_write_register(ViPipe, 0x377B, 0x00); + imx335_write_register(ViPipe, 0x377C, 0x08); + imx335_write_register(ViPipe, 0x377D, 0x01); + imx335_write_register(ViPipe, 0x377E, 0x23); + imx335_write_register(ViPipe, 0x377F, 0x02); + imx335_write_register(ViPipe, 0x3780, 0xD9); + imx335_write_register(ViPipe, 0x3781, 0x03); + imx335_write_register(ViPipe, 0x3782, 0xF5); + imx335_write_register(ViPipe, 0x3783, 0x06); + imx335_write_register(ViPipe, 0x3784, 0xA5); + imx335_write_register(ViPipe, 0x3788, 0x0F); + imx335_write_register(ViPipe, 0x378A, 0xD9); + imx335_write_register(ViPipe, 0x378B, 0x03); + imx335_write_register(ViPipe, 0x378C, 0xEB); + imx335_write_register(ViPipe, 0x378D, 0x05); + imx335_write_register(ViPipe, 0x378E, 0x87); + imx335_write_register(ViPipe, 0x378F, 0x06); + imx335_write_register(ViPipe, 0x3790, 0xF5); + imx335_write_register(ViPipe, 0x3792, 0x43); + imx335_write_register(ViPipe, 0x3794, 0x7A); + imx335_write_register(ViPipe, 0x3796, 0xA1); + imx335_default_reg_init(ViPipe); + + imx335_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx335_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe:%d,===IMX335 4M 1660P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void imx335_linear_5M30_init(VI_PIPE ViPipe) +{ + delay_ms(4); + imx335_write_register(ViPipe, 0x3000, 0x01); // STANDBY + imx335_write_register(ViPipe, 0x3002, 0x01); // XTMSTA + + imx335_write_register(ViPipe, 0x300C, 0x5B); + imx335_write_register(ViPipe, 0x300D, 0x40); + imx335_write_register(ViPipe, 0x315A, 0x02); + imx335_write_register(ViPipe, 0x316A, 0x7E); + imx335_write_register(ViPipe, 0x31A1, 0x00); + imx335_write_register(ViPipe, 0x3288, 0x21); + imx335_write_register(ViPipe, 0x328A, 0x02); + imx335_write_register(ViPipe, 0x3414, 0x05); + imx335_write_register(ViPipe, 0x3416, 0x18); + imx335_write_register(ViPipe, 0x3648, 0x01); + imx335_write_register(ViPipe, 0x364A, 0x04); + imx335_write_register(ViPipe, 0x364C, 0x04); + imx335_write_register(ViPipe, 0x3678, 0x01); + imx335_write_register(ViPipe, 0x367C, 0x31); + imx335_write_register(ViPipe, 0x367E, 0x31); + imx335_write_register(ViPipe, 0x3706, 0x10); + imx335_write_register(ViPipe, 0x3708, 0x03); + imx335_write_register(ViPipe, 0x3714, 0x02); + imx335_write_register(ViPipe, 0x3715, 0x02); + imx335_write_register(ViPipe, 0x3716, 0x01); + imx335_write_register(ViPipe, 0x3717, 0x03); + imx335_write_register(ViPipe, 0x371C, 0x3D); + imx335_write_register(ViPipe, 0x371D, 0x3F); + imx335_write_register(ViPipe, 0x372C, 0x00); + imx335_write_register(ViPipe, 0x372D, 0x00); + imx335_write_register(ViPipe, 0x372E, 0x46); + imx335_write_register(ViPipe, 0x372F, 0x00); + imx335_write_register(ViPipe, 0x3730, 0x89); + imx335_write_register(ViPipe, 0x3731, 0x00); + imx335_write_register(ViPipe, 0x3732, 0x08); + imx335_write_register(ViPipe, 0x3733, 0x01); + imx335_write_register(ViPipe, 0x3734, 0xFE); + imx335_write_register(ViPipe, 0x3735, 0x05); + imx335_write_register(ViPipe, 0x3740, 0x02); + imx335_write_register(ViPipe, 0x375D, 0x00); + imx335_write_register(ViPipe, 0x375E, 0x00); + imx335_write_register(ViPipe, 0x375F, 0x11); + imx335_write_register(ViPipe, 0x3760, 0x01); + imx335_write_register(ViPipe, 0x3768, 0x1B); + imx335_write_register(ViPipe, 0x3769, 0x1B); + imx335_write_register(ViPipe, 0x376A, 0x1B); + imx335_write_register(ViPipe, 0x376B, 0x1B); + imx335_write_register(ViPipe, 0x376C, 0x1A); + imx335_write_register(ViPipe, 0x376D, 0x17); + imx335_write_register(ViPipe, 0x376E, 0x0F); + imx335_write_register(ViPipe, 0x3776, 0x00); + imx335_write_register(ViPipe, 0x3777, 0x00); + imx335_write_register(ViPipe, 0x3778, 0x46); + imx335_write_register(ViPipe, 0x3779, 0x00); + imx335_write_register(ViPipe, 0x377A, 0x89); + imx335_write_register(ViPipe, 0x377B, 0x00); + imx335_write_register(ViPipe, 0x377C, 0x08); + imx335_write_register(ViPipe, 0x377D, 0x01); + imx335_write_register(ViPipe, 0x377E, 0x23); + imx335_write_register(ViPipe, 0x377F, 0x02); + imx335_write_register(ViPipe, 0x3780, 0xD9); + imx335_write_register(ViPipe, 0x3781, 0x03); + imx335_write_register(ViPipe, 0x3782, 0xF5); + imx335_write_register(ViPipe, 0x3783, 0x06); + imx335_write_register(ViPipe, 0x3784, 0xA5); + imx335_write_register(ViPipe, 0x3788, 0x0F); + imx335_write_register(ViPipe, 0x378A, 0xD9); + imx335_write_register(ViPipe, 0x378B, 0x03); + imx335_write_register(ViPipe, 0x378C, 0xEB); + imx335_write_register(ViPipe, 0x378D, 0x05); + imx335_write_register(ViPipe, 0x378E, 0x87); + imx335_write_register(ViPipe, 0x378F, 0x06); + imx335_write_register(ViPipe, 0x3790, 0xF5); + imx335_write_register(ViPipe, 0x3792, 0x43); + imx335_write_register(ViPipe, 0x3794, 0x7A); + imx335_write_register(ViPipe, 0x3796, 0xA1); + imx335_default_reg_init(ViPipe); + + imx335_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx335_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe:%d,===IMX335 5M 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void imx335_wdr_5M30_2to1_init(VI_PIPE ViPipe) +{ + delay_ms(4); + imx335_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx335_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx335_write_register(ViPipe, 0x3003, 0x00); + imx335_write_register(ViPipe, 0x3004, 0x00); + imx335_write_register(ViPipe, 0x300C, 0x5B); // BCWAIT_TIME[7:0] + imx335_write_register(ViPipe, 0x300D, 0x40); // CPWAIT_TIME[7:0] + imx335_write_register(ViPipe, 0x3034, 0x13); // HMAX[15:0] + imx335_write_register(ViPipe, 0x3035, 0x01); // + imx335_write_register(ViPipe, 0x3048, 0x01); // WDMODE[0] + imx335_write_register(ViPipe, 0x3049, 0x01); // WDSEL[1:0] + imx335_write_register(ViPipe, 0x304A, 0x04); // WD_SET1[2:0] + imx335_write_register(ViPipe, 0x304B, 0x03); // WD_SET2[3:0] + imx335_write_register(ViPipe, 0x304C, 0x13); // OPB_SIZE_V[5:0] + imx335_write_register(ViPipe, 0x3050, 0x00); // ADBIT[0] + imx335_write_register(ViPipe, 0x3058, 0x68); // SHR0[19:0] + imx335_write_register(ViPipe, 0x3059, 0x01); // + imx335_write_register(ViPipe, 0x3068, 0x4A); // RHS1[19:0] + imx335_write_register(ViPipe, 0x315A, 0x02); // INCKSEL2[1:0] + imx335_write_register(ViPipe, 0x316A, 0x7E); // INCKSEL4[1:0] + imx335_write_register(ViPipe, 0x319D, 0x00); // MDBIT + imx335_write_register(ViPipe, 0x31A1, 0x00); // XVS_DRV[1:0] + imx335_write_register(ViPipe, 0x31D7, 0x01); // XVSMSKCNT_INT[1:0] + imx335_write_register(ViPipe, 0x3288, 0x21); // - + imx335_write_register(ViPipe, 0x328A, 0x02); // - + imx335_write_register(ViPipe, 0x3414, 0x05); // - + imx335_write_register(ViPipe, 0x3416, 0x18); // - + imx335_write_register(ViPipe, 0x341C, 0xFF); // ADBIT1[8:0] + imx335_write_register(ViPipe, 0x341D, 0x01); // + imx335_write_register(ViPipe, 0x3648, 0x01); // - + imx335_write_register(ViPipe, 0x364A, 0x04); // - + imx335_write_register(ViPipe, 0x364C, 0x04); // - + imx335_write_register(ViPipe, 0x3678, 0x01); // - + imx335_write_register(ViPipe, 0x367C, 0x31); // - + imx335_write_register(ViPipe, 0x367E, 0x31); // - + imx335_write_register(ViPipe, 0x3706, 0x10); // - + imx335_write_register(ViPipe, 0x3708, 0x03); // - + imx335_write_register(ViPipe, 0x3714, 0x02); // - + imx335_write_register(ViPipe, 0x3715, 0x02); // - + imx335_write_register(ViPipe, 0x3716, 0x01); // - + imx335_write_register(ViPipe, 0x3717, 0x03); // - + imx335_write_register(ViPipe, 0x371C, 0x3D); // - + imx335_write_register(ViPipe, 0x371D, 0x3F); // - + imx335_write_register(ViPipe, 0x372C, 0x00); // - + imx335_write_register(ViPipe, 0x372D, 0x00); // - + imx335_write_register(ViPipe, 0x372E, 0x46); // - + imx335_write_register(ViPipe, 0x372F, 0x00); // - + imx335_write_register(ViPipe, 0x3730, 0x89); // - + imx335_write_register(ViPipe, 0x3731, 0x00); // - + imx335_write_register(ViPipe, 0x3732, 0x08); // - + imx335_write_register(ViPipe, 0x3733, 0x01); // - + imx335_write_register(ViPipe, 0x3734, 0xFE); // - + imx335_write_register(ViPipe, 0x3735, 0x05); // - + imx335_write_register(ViPipe, 0x3740, 0x02); // - + imx335_write_register(ViPipe, 0x375D, 0x00); // - + imx335_write_register(ViPipe, 0x375E, 0x00); // - + imx335_write_register(ViPipe, 0x375F, 0x11); // - + imx335_write_register(ViPipe, 0x3760, 0x01); // - + imx335_write_register(ViPipe, 0x3768, 0x1B); // - + imx335_write_register(ViPipe, 0x3769, 0x1B); // - + imx335_write_register(ViPipe, 0x376A, 0x1B); // - + imx335_write_register(ViPipe, 0x376B, 0x1B); // - + imx335_write_register(ViPipe, 0x376C, 0x1A); // - + imx335_write_register(ViPipe, 0x376D, 0x17); // - + imx335_write_register(ViPipe, 0x376E, 0x0F); // - + imx335_write_register(ViPipe, 0x3776, 0x00); // - + imx335_write_register(ViPipe, 0x3777, 0x00); // - + imx335_write_register(ViPipe, 0x3778, 0x46); // - + imx335_write_register(ViPipe, 0x3779, 0x00); // - + imx335_write_register(ViPipe, 0x377A, 0x89); // - + imx335_write_register(ViPipe, 0x377B, 0x00); // - + imx335_write_register(ViPipe, 0x377C, 0x08); // - + imx335_write_register(ViPipe, 0x377D, 0x01); // - + imx335_write_register(ViPipe, 0x377E, 0x23); // - + imx335_write_register(ViPipe, 0x377F, 0x02); // - + imx335_write_register(ViPipe, 0x3780, 0xD9); // - + imx335_write_register(ViPipe, 0x3781, 0x03); // - + imx335_write_register(ViPipe, 0x3782, 0xF5); // - + imx335_write_register(ViPipe, 0x3783, 0x06); // - + imx335_write_register(ViPipe, 0x3784, 0xA5); // - + imx335_write_register(ViPipe, 0x3788, 0x0F); // - + imx335_write_register(ViPipe, 0x378A, 0xD9); // - + imx335_write_register(ViPipe, 0x378B, 0x03); // - + imx335_write_register(ViPipe, 0x378C, 0xEB); // - + imx335_write_register(ViPipe, 0x378D, 0x05); // - + imx335_write_register(ViPipe, 0x378E, 0x87); // - + imx335_write_register(ViPipe, 0x378F, 0x06); // - + imx335_write_register(ViPipe, 0x3790, 0xF5); // - + imx335_write_register(ViPipe, 0x3792, 0x43); // - + imx335_write_register(ViPipe, 0x3794, 0x7A); // - + imx335_write_register(ViPipe, 0x3796, 0xA1); // - + + imx335_default_reg_init(ViPipe); + + imx335_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx335_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + + CVI_TRACE_SNS(CVI_DBG_INFO, "===Imx335 sensor 5M30fps 10bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} +static void imx335_wdr_4M30_2to1_init(VI_PIPE ViPipe) +{ + delay_ms(4); + imx335_write_register(ViPipe, 0x3000, 0x01);/* STANDBY */ + imx335_write_register(ViPipe, 0x3002, 0x01);/* XTMSTA */ + + imx335_write_register(ViPipe, 0x300C, 0x5B);// BCWAIT_TIME[CWAIT_TIME[7:0] + imx335_write_register(ViPipe, 0x300D, 0x40);// CPWAIT_TIME[PWAIT_TIME[7:0] + imx335_write_register(ViPipe, 0x3018, 0x04);// WINMODE[3:0]INMODE[3:0] + imx335_write_register(ViPipe, 0x3034, 0x13);// HMAX[15:0]MAX[15:0] + imx335_write_register(ViPipe, 0x3035, 0x01);// - + imx335_write_register(ViPipe, 0x3048, 0x01);// WDMODE[0]DMODE[0] + imx335_write_register(ViPipe, 0x3049, 0x01);// WDSEL[1:0]DSEL[1:0] + imx335_write_register(ViPipe, 0x304A, 0x04);// WD_SET1[2:0]D_SET1[2:0] + imx335_write_register(ViPipe, 0x304B, 0x03);// WD_SET2[3:0]D_SET2[3:0] + imx335_write_register(ViPipe, 0x304C, 0x13);// OPB_SIZE_V[5PB_SIZE_V[5:0] + imx335_write_register(ViPipe, 0x3050, 0x00);// ADBIT[0]DBIT[0] + imx335_write_register(ViPipe, 0x3056, 0xB4);// Y_OUT_SIZE[1_OUT_SIZE[12:0] + imx335_write_register(ViPipe, 0x3057, 0x05);// - + imx335_write_register(ViPipe, 0x3058, 0x68);// SHR0[19:0]HR0[19:0] + imx335_write_register(ViPipe, 0x3059, 0x01);// - + imx335_write_register(ViPipe, 0x3068, 0x4A);// RHS1[19:0]HS1[19:0] + imx335_write_register(ViPipe, 0x3074, 0xA8);// AREA3_ST_ADRREA3_ST_ADR_1[12:0] + imx335_write_register(ViPipe, 0x3075, 0x02);// - + imx335_write_register(ViPipe, 0x3076, 0x68);// AREA3_WIDTH_REA3_WIDTH_1[12:0] + imx335_write_register(ViPipe, 0x3077, 0x0B);// - + imx335_write_register(ViPipe, 0x30C6, 0x12);// BLACK_OFSET_LACK_OFSET_ADR[12:0] + imx335_write_register(ViPipe, 0x30CE, 0x64);// UNRD_LINE_MANRD_LINE_MAX[12:0] + imx335_write_register(ViPipe, 0x30D8, 0xE0);// UNREAD_ED_ADNREAD_ED_ADR[12:0] + imx335_write_register(ViPipe, 0x30D9, 0x0E);// - + imx335_write_register(ViPipe, 0x315A, 0x02);// INCKSEL2[1:0NCKSEL2[1:0] + imx335_write_register(ViPipe, 0x316A, 0x7E);// INCKSEL4[1:0NCKSEL4[1:0] + imx335_write_register(ViPipe, 0x319D, 0x00);// MDBITDBIT + imx335_write_register(ViPipe, 0x31A1, 0x00);// XVS_DRV[1:0]CEN + imx335_write_register(ViPipe, 0x31D7, 0x01);// XVSMSKCNT_INVS_DRV[1:0] + imx335_write_register(ViPipe, 0x3288, 0x21);// -VSMSKCNT_INT[1:0] + imx335_write_register(ViPipe, 0x328A, 0x02);// - + imx335_write_register(ViPipe, 0x3414, 0x05);// - + imx335_write_register(ViPipe, 0x3416, 0x18);// - + imx335_write_register(ViPipe, 0x341C, 0xFF);// ADBIT1[8:0] + imx335_write_register(ViPipe, 0x341D, 0x01);// DBIT1[8:0] + imx335_write_register(ViPipe, 0x3648, 0x01);// - + imx335_write_register(ViPipe, 0x364A, 0x04);// - + imx335_write_register(ViPipe, 0x364C, 0x04);// - + imx335_write_register(ViPipe, 0x3678, 0x01);// - + imx335_write_register(ViPipe, 0x367C, 0x31);// - + imx335_write_register(ViPipe, 0x367E, 0x31);// - + imx335_write_register(ViPipe, 0x3706, 0x10);// - + imx335_write_register(ViPipe, 0x3708, 0x03);// - + imx335_write_register(ViPipe, 0x3714, 0x02);// - + imx335_write_register(ViPipe, 0x3715, 0x02);// - + imx335_write_register(ViPipe, 0x3716, 0x01);// - + imx335_write_register(ViPipe, 0x3717, 0x03);// - + imx335_write_register(ViPipe, 0x371C, 0x3D);// - + imx335_write_register(ViPipe, 0x371D, 0x3F);// - + imx335_write_register(ViPipe, 0x372C, 0x00);// - + imx335_write_register(ViPipe, 0x372D, 0x00);// - + imx335_write_register(ViPipe, 0x372E, 0x46);// - + imx335_write_register(ViPipe, 0x372F, 0x00);// - + imx335_write_register(ViPipe, 0x3730, 0x89);// - + imx335_write_register(ViPipe, 0x3731, 0x00);// - + imx335_write_register(ViPipe, 0x3732, 0x08);// - + imx335_write_register(ViPipe, 0x3733, 0x01);// - + imx335_write_register(ViPipe, 0x3734, 0xFE);// - + imx335_write_register(ViPipe, 0x3735, 0x05);// - + imx335_write_register(ViPipe, 0x3740, 0x02);// - + imx335_write_register(ViPipe, 0x375D, 0x00);// - + imx335_write_register(ViPipe, 0x375E, 0x00);// - + imx335_write_register(ViPipe, 0x375F, 0x11);// - + imx335_write_register(ViPipe, 0x3760, 0x01);// - + imx335_write_register(ViPipe, 0x3768, 0x1B);// - + imx335_write_register(ViPipe, 0x3769, 0x1B);// - + imx335_write_register(ViPipe, 0x376A, 0x1B);// - + imx335_write_register(ViPipe, 0x376B, 0x1B);// - + imx335_write_register(ViPipe, 0x376C, 0x1A);// - + imx335_write_register(ViPipe, 0x376D, 0x17);// - + imx335_write_register(ViPipe, 0x376E, 0x0F);// - + imx335_write_register(ViPipe, 0x3776, 0x00);// - + imx335_write_register(ViPipe, 0x3777, 0x00);// - + imx335_write_register(ViPipe, 0x3778, 0x46);// - + imx335_write_register(ViPipe, 0x3779, 0x00);// - + imx335_write_register(ViPipe, 0x377A, 0x89);// - + imx335_write_register(ViPipe, 0x377B, 0x00);// - + imx335_write_register(ViPipe, 0x377C, 0x08);// - + imx335_write_register(ViPipe, 0x377D, 0x01);// - + imx335_write_register(ViPipe, 0x377E, 0x23);// - + imx335_write_register(ViPipe, 0x377F, 0x02);// - + imx335_write_register(ViPipe, 0x3780, 0xD9);// - + imx335_write_register(ViPipe, 0x3781, 0x03);// - + imx335_write_register(ViPipe, 0x3782, 0xF5);// - + imx335_write_register(ViPipe, 0x3783, 0x06);// - + imx335_write_register(ViPipe, 0x3784, 0xA5);// - + imx335_write_register(ViPipe, 0x3788, 0x0F);// - + imx335_write_register(ViPipe, 0x378A, 0xD9);// - + imx335_write_register(ViPipe, 0x378B, 0x03);// - + imx335_write_register(ViPipe, 0x378C, 0xEB);// - + imx335_write_register(ViPipe, 0x378D, 0x05);// - + imx335_write_register(ViPipe, 0x378E, 0x87);// - + imx335_write_register(ViPipe, 0x378F, 0x06);// - + imx335_write_register(ViPipe, 0x3790, 0xF5);// - + imx335_write_register(ViPipe, 0x3792, 0x43);// - + imx335_write_register(ViPipe, 0x3794, 0x7A);// - + imx335_write_register(ViPipe, 0x3796, 0xA1);// - + + imx335_default_reg_init(ViPipe); + + imx335_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx335_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + + CVI_TRACE_SNS(CVI_DBG_INFO, "===Imx335 sensor 4M30fps 10bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} +static void imx335_wdr_4M30_1600p_2to1_init(VI_PIPE ViPipe) +{ + delay_ms(4); + imx335_write_register(ViPipe, 0x3000, 0x01);/* STANDBY */ + imx335_write_register(ViPipe, 0x3002, 0x01);/* XTMSTA */ + + imx335_write_register(ViPipe, 0x300C, 0x5B);// BCWAIT_TIME[7:0] + imx335_write_register(ViPipe, 0x300D, 0x40);// CPWAIT_TIME[7:0] + imx335_write_register(ViPipe, 0x3018, 0x04);// WINMODE[3:0] + imx335_write_register(ViPipe, 0x302C, 0x3C);// HTRIMMING_START[11:0] + imx335_write_register(ViPipe, 0x302E, 0x20);// HNUM[11:0] + imx335_write_register(ViPipe, 0x3034, 0x13);// HMAX[15:0] + imx335_write_register(ViPipe, 0x3035, 0x01);// + imx335_write_register(ViPipe, 0x3048, 0x01);// WDMODE[0] + imx335_write_register(ViPipe, 0x3049, 0x01);// WDSEL[1:0] + imx335_write_register(ViPipe, 0x304A, 0x04);// WD_SET1[2:0] + imx335_write_register(ViPipe, 0x304B, 0x03);// WD_SET2[3:0] + imx335_write_register(ViPipe, 0x304C, 0x13);// OPB_SIZE_V[5:0] + imx335_write_register(ViPipe, 0x3050, 0x00);// ADBIT[0] + imx335_write_register(ViPipe, 0x3056, 0x54);// Y_OUT_SIZE[12:0] + imx335_write_register(ViPipe, 0x3057, 0x06);// + imx335_write_register(ViPipe, 0x3058, 0x68);// SHR0[19:0] + imx335_write_register(ViPipe, 0x3059, 0x01);// + imx335_write_register(ViPipe, 0x3068, 0x4A);// RHS1[19:0] + imx335_write_register(ViPipe, 0x3074, 0x08);// AREA3_ST_ADR_1[12:0] + imx335_write_register(ViPipe, 0x3075, 0x02);// + imx335_write_register(ViPipe, 0x3076, 0xA8);// AREA3_WIDTH_1[12:0] + imx335_write_register(ViPipe, 0x3077, 0x0C);// + imx335_write_register(ViPipe, 0x30C6, 0x12);// BLACK_OFSET_ADR[12:0] + imx335_write_register(ViPipe, 0x30CE, 0x64);// UNRD_LINE_MAX[12:0] + imx335_write_register(ViPipe, 0x30D8, 0x80);// UNREAD_ED_ADR[12:0] + imx335_write_register(ViPipe, 0x30D9, 0x0F);// + imx335_write_register(ViPipe, 0x315A, 0x02);// INCKSEL2[1:0] + imx335_write_register(ViPipe, 0x316A, 0x7E);// INCKSEL4[1:0] + imx335_write_register(ViPipe, 0x319D, 0x00);// MDBIT + imx335_write_register(ViPipe, 0x31A1, 0x00);// XVS_DRV[1:0] + imx335_write_register(ViPipe, 0x31D7, 0x01);// XVSMSKCNT_INT[1:0] + imx335_write_register(ViPipe, 0x3288, 0x21);// + imx335_write_register(ViPipe, 0x328A, 0x02);// + imx335_write_register(ViPipe, 0x3414, 0x05);// + imx335_write_register(ViPipe, 0x3416, 0x18);// + imx335_write_register(ViPipe, 0x341C, 0xFF);// ADBIT1[8:0] + imx335_write_register(ViPipe, 0x341D, 0x01);// + imx335_write_register(ViPipe, 0x3648, 0x01);// + imx335_write_register(ViPipe, 0x364A, 0x04);// + imx335_write_register(ViPipe, 0x364C, 0x04);// + imx335_write_register(ViPipe, 0x3678, 0x01);// + imx335_write_register(ViPipe, 0x367C, 0x31);// + imx335_write_register(ViPipe, 0x367E, 0x31);// + imx335_write_register(ViPipe, 0x3706, 0x10);// + imx335_write_register(ViPipe, 0x3708, 0x03);// + imx335_write_register(ViPipe, 0x3714, 0x02);// + imx335_write_register(ViPipe, 0x3715, 0x02);// + imx335_write_register(ViPipe, 0x3716, 0x01);// + imx335_write_register(ViPipe, 0x3717, 0x03);// + imx335_write_register(ViPipe, 0x371C, 0x3D);// + imx335_write_register(ViPipe, 0x371D, 0x3F);// + imx335_write_register(ViPipe, 0x372C, 0x00);// + imx335_write_register(ViPipe, 0x372D, 0x00);// + imx335_write_register(ViPipe, 0x372E, 0x46);// + imx335_write_register(ViPipe, 0x372F, 0x00);// + imx335_write_register(ViPipe, 0x3730, 0x89);// + imx335_write_register(ViPipe, 0x3731, 0x00);// + imx335_write_register(ViPipe, 0x3732, 0x08);// + imx335_write_register(ViPipe, 0x3733, 0x01);// + imx335_write_register(ViPipe, 0x3734, 0xFE);// + imx335_write_register(ViPipe, 0x3735, 0x05);// + imx335_write_register(ViPipe, 0x3740, 0x02);// + imx335_write_register(ViPipe, 0x375D, 0x00);// + imx335_write_register(ViPipe, 0x375E, 0x00);// + imx335_write_register(ViPipe, 0x375F, 0x11);// + imx335_write_register(ViPipe, 0x3760, 0x01);// + imx335_write_register(ViPipe, 0x3768, 0x1B);// + imx335_write_register(ViPipe, 0x3769, 0x1B);// + imx335_write_register(ViPipe, 0x376A, 0x1B);// + imx335_write_register(ViPipe, 0x376B, 0x1B);// + imx335_write_register(ViPipe, 0x376C, 0x1A);// + imx335_write_register(ViPipe, 0x376D, 0x17);// + imx335_write_register(ViPipe, 0x376E, 0x0F);// + imx335_write_register(ViPipe, 0x3776, 0x00);// + imx335_write_register(ViPipe, 0x3777, 0x00);// + imx335_write_register(ViPipe, 0x3778, 0x46);// + imx335_write_register(ViPipe, 0x3779, 0x00);// + imx335_write_register(ViPipe, 0x377A, 0x89);// + imx335_write_register(ViPipe, 0x377B, 0x00);// + imx335_write_register(ViPipe, 0x377C, 0x08);// + imx335_write_register(ViPipe, 0x377D, 0x01);// + imx335_write_register(ViPipe, 0x377E, 0x23);// + imx335_write_register(ViPipe, 0x377F, 0x02);// + imx335_write_register(ViPipe, 0x3780, 0xD9);// + imx335_write_register(ViPipe, 0x3781, 0x03);// + imx335_write_register(ViPipe, 0x3782, 0xF5);// + imx335_write_register(ViPipe, 0x3783, 0x06);// + imx335_write_register(ViPipe, 0x3784, 0xA5);// + imx335_write_register(ViPipe, 0x3788, 0x0F);// + imx335_write_register(ViPipe, 0x378A, 0xD9);// + imx335_write_register(ViPipe, 0x378B, 0x03);// + imx335_write_register(ViPipe, 0x378C, 0xEB);// + imx335_write_register(ViPipe, 0x378D, 0x05);// + imx335_write_register(ViPipe, 0x378E, 0x87);// + imx335_write_register(ViPipe, 0x378F, 0x06);// + imx335_write_register(ViPipe, 0x3790, 0xF5);// + imx335_write_register(ViPipe, 0x3792, 0x43);// + imx335_write_register(ViPipe, 0x3794, 0x7A);// + imx335_write_register(ViPipe, 0x3796, 0xA1);// + + imx335_default_reg_init(ViPipe); + + imx335_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx335_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + + CVI_TRACE_SNS(CVI_DBG_INFO, "===Imx335 sensor 4M1600P 30fps 10bit 2to1 WDR(60fps->30fps) init success!\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/Makefile b/middleware/v2/component/isp/sensor/cv181x/Makefile new file mode 100644 index 000000000..92302dc00 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/Makefile @@ -0,0 +1,180 @@ +SHELL = /bin/bash + +ifeq ($(PARAM_FILE), ) +PARAM_FILE=../../../../../$(shell echo $(MW_VER))/Makefile.param +include $(PARAM_FILE) +endif +include ../../../../../$(shell echo $(MW_VER))/component/isp/sensor.mk + +define MAKE_SENSOR + pushd $(1) && \ + $(MAKE) all && \ + popd +endef + +.PHONY : prepare clean $(sensor-y) +all: prepare $(sensor-y) all_sensor + +prepare: + @echo "#################################################" + @echo "#" + @echo "# Compiling 'component libs' Configs as below..." + @echo "# SENSOR_LIST=$(sensor-y)" + @echo "#" + @echo "#################################################" + +brigates_bg0808: + $(call MAKE_SENSOR, ${@}) + +gcore_gc02m1: + $(call MAKE_SENSOR, ${@}) + +gcore_gc1054: + $(call MAKE_SENSOR, ${@}) + +gcore_gc2053: + $(call MAKE_SENSOR, ${@}) + +gcore_gc2053_slave: + $(call MAKE_SENSOR, ${@}) + +gcore_gc2053_1L: + $(call MAKE_SENSOR, ${@}) + +gcore_gc2093: + $(call MAKE_SENSOR, ${@}) + +gcore_gc2145: + $(call MAKE_SENSOR, ${@}) + +gcore_gc4023: + $(call MAKE_SENSOR, ${@}) + +gcore_gc4653: + $(call MAKE_SENSOR, ${@}) + +nextchip_n5: + $(call MAKE_SENSOR, ${@}) + +nextchip_n6: + $(call MAKE_SENSOR, ${@}) + +ov_os04a10: + $(call MAKE_SENSOR, ${@}) + +ov_os04c10: + $(call MAKE_SENSOR, ${@}) + +ov_os08a20: + $(call MAKE_SENSOR, ${@}) + +ov_ov4689: + $(call MAKE_SENSOR, ${@}) + +ov_ov6211: + $(call MAKE_SENSOR, ${@}) + +ov_ov7251: + $(call MAKE_SENSOR, ${@}) + +pixelplus_pr2020: + $(call MAKE_SENSOR, ${@}) + +pixelplus_pr2100: + $(call MAKE_SENSOR, ${@}) + +sms_sc035gs: + $(call MAKE_SENSOR, ${@}) + +sms_sc035gs_1L: + $(call MAKE_SENSOR, ${@}) + +sms_sc035hgs: + $(call MAKE_SENSOR, ${@}) + +sms_sc200ai: + $(call MAKE_SENSOR, ${@}) + +sms_sc301iot: + $(call MAKE_SENSOR, ${@}) + +sms_sc401ai: + $(call MAKE_SENSOR, ${@}) + +sms_sc500ai: + $(call MAKE_SENSOR, ${@}) + +sms_sc501ai_2L: + $(call MAKE_SENSOR, ${@}) + +sms_sc3332: + $(call MAKE_SENSOR, ${@}) + +sms_sc531ai_2L: + $(call MAKE_SENSOR, ${@}) + +sms_sc3335: + $(call MAKE_SENSOR, ${@}) + +sms_sc3336: + $(call MAKE_SENSOR, ${@}) + +sms_sc2335: + $(call MAKE_SENSOR, ${@}) + +sms_sc2336: + $(call MAKE_SENSOR, ${@}) + +sms_sc4336: + $(call MAKE_SENSOR, ${@}) + +soi_f23: + $(call MAKE_SENSOR, ${@}) + +soi_f35: + $(call MAKE_SENSOR, ${@}) + +soi_f37p: + $(call MAKE_SENSOR, ${@}) + +soi_q03: + $(call MAKE_SENSOR, ${@}) + +soi_k06: + $(call MAKE_SENSOR, ${@}) + +sony_imx307: + $(call MAKE_SENSOR, ${@}) + +sony_imx307_slave: + $(call MAKE_SENSOR, ${@}) + +sony_imx307_2L: + $(call MAKE_SENSOR, ${@}) + +sony_imx327: + $(call MAKE_SENSOR, ${@}) + +sony_imx327_slave: + $(call MAKE_SENSOR, ${@}) + +sony_imx327_2L: + $(call MAKE_SENSOR, ${@}) + +sony_imx327_fpga: + $(call MAKE_SENSOR, ${@}) + +sony_imx327_sublvds: + $(call MAKE_SENSOR, ${@}) + +sony_imx335: + $(call MAKE_SENSOR, ${@}) + +all_sensor: + @$(MAKE) -f Makefile_full || exit 1; + +clean: + @for x in `find ./ -maxdepth 2 -mindepth 2 -name "Makefile" `; \ + do cd `dirname $$x`; if [ $$? ]; then $(MAKE) clean; cd -; fi; done + @echo "#" + @$(MAKE) clean -f Makefile_full || exit 1; diff --git a/middleware/v2/component/isp/sensor/cv181x/Makefile_full b/middleware/v2/component/isp/sensor/cv181x/Makefile_full new file mode 100644 index 000000000..db3da3c28 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/Makefile_full @@ -0,0 +1,29 @@ +SHELL = /bin/bash + +ifeq ($(PARAM_FILE), ) +PARAM_FILE=../../../../../$(shell echo $(MW_VER))/Makefile.param +include $(PARAM_FILE) +endif +include ../../sensor.mk + +SRCS = $(shell find $(sensor-y) -name '*.c') +OBJS = $(SRCS:.c=.o) + +TARGET_A = $(MW_LIB)/libsns_full.a +TARGET_SO = $(MW_LIB)/libsns_full.so + +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS_PATH) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(TARGET_A) $(TARGET_SO) diff --git a/middleware/v2/component/isp/sensor/cv181x/brigates_bg0808/Makefile b/middleware/v2/component/isp/sensor/cv181x/brigates_bg0808/Makefile new file mode 100644 index 000000000..8bc92e246 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/brigates_bg0808/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_bg0808.a +TARGET_SO = $(MW_LIB)/libsns_bg0808.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/brigates_bg0808/bg0808_cmos.c b/middleware/v2/component/isp/sensor/cv181x/brigates_bg0808/bg0808_cmos.c new file mode 100644 index 000000000..d367eeab1 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/brigates_bg0808/bg0808_cmos.c @@ -0,0 +1,1181 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "bg0808_cmos_ex.h" +#include "bg0808_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define BG0808_ID 0x0808 +#define BG0808_I2C_ADDR 0x32 +#define BG0808_I2C_ADDR_IS_VALID(addr) ((addr) == BG0808_I2C_ADDR) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastBG0808[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define BG0808_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastBG0808[dev]) +#define BG0808_SENSOR_SET_CTX(dev, pstCtx) (g_pastBG0808[dev] = pstCtx) +#define BG0808_SENSOR_RESET_CTX(dev) (g_pastBG0808[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunBG0808_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16BG0808_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16BG0808_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeBg0808_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_u32SexpOld; + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****BG0808 Lines Range*****/ +#define BG0808_FULL_LINES_MAX (0xFFFF) + +/*****BG0808 Register Address*****/ +#define BG0808_EXP_H_ADDR (0x000c) +#define BG0808_EXP_L_ADDR (0x000d) +#define BG0808_SEXP_H_ADDR (0x0022) +#define BG0808_SEXP_L_ADDR (0x0023) + +#define BG0808_AGAIN_ADDR (0x00a2) +#define BG0808_SAGAIN_ADDR (0x00a4) +#define BG0808_CLAMP_MODE_ADDR (0x0073) + +#define BG0808_DGAIN_H_ADDR (0x00c0) +#define BG0808_DGAIN_L_ADDR (0x00c1) +#define BG0808_SDGAIN_H_ADDR (0x00c2) +#define BG0808_SDGAIN_L_ADDR (0x00c3) + +#define BG0808_VMAX_H_ADDR (0x0010) +#define BG0808_VMAX_L_ADDR (0x0011) +#define BG0808_SHADOW_ADDR (0x001d) + +#define AGAIN_MAX_IDX (64) +#define DGAIN_MAX_IDX (83) + +#define BG0808_RES_IS_1080P(w, h) ((w) == 1920 && (h) == 1080) + +#define BG0808_EXPACCURACY (1) +#define BG0808_SEXP_ADDSPEED_MAX (264) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const BG0808_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astBG0808_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = BG0808_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = BG0808_EXPACCURACY; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = pstAeSnsDft->u32MaxIntTime; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + break; + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 3; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astBG0808_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astBG0808_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astBG0808_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case BG0808_MODE_1920X1080P30: + case BG0808_MODE_1920X1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > BG0808_FULL_LINES_MAX) ? BG0808_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + pstSnsRegsInfo->astI2cData[WDR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 1; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + CVI_U32 SexpAddSpeed = 0; + + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 1 + * max : vts - 1 + * step : 1 + */ + u32MinTime = 1; + u32MaxTime = pstSnsState->au32FL[0] - 1; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_ADDR].u32Data = ((u32TmpIntTime & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_ADDR].u32Data = (u32TmpIntTime & 0x00FF); + } else { + /* + * Long exp + Short exp < VTS + * sexp[N+1] - sexp[N] <= 264 + */ + /* sexp */ + pstSnsState->au32WDRIntTime[0] = u32IntTime[0]; + /* lexp */ + pstSnsState->au32WDRIntTime[1] = u32IntTime[1]; + SexpAddSpeed = pstSnsState->au32WDRIntTime[0] > g_u32SexpOld ? + (pstSnsState->au32WDRIntTime[0] - g_u32SexpOld) : 0; + pstSnsState->au32WDRIntTime[0] = SexpAddSpeed >= BG0808_SEXP_ADDSPEED_MAX ? + BG0808_SEXP_ADDSPEED_MAX : pstSnsState->au32WDRIntTime[0]; + pstSnsRegsInfo->astI2cData[WDR_EXP_H_ADDR].u32Data = ((pstSnsState->au32WDRIntTime[1] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR_EXP_L_ADDR].u32Data = (pstSnsState->au32WDRIntTime[1] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_SEXP_H_ADDR].u32Data = ((pstSnsState->au32WDRIntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR_SEXP_L_ADDR].u32Data = (pstSnsState->au32WDRIntTime[0] & 0xFF); + + g_u32SexpOld = pstSnsState->au32WDRIntTime[0]; + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } + + return CVI_SUCCESS; +} + +typedef struct again_tbl_info_s { + CVI_U32 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} again_tbl_info_s; + +static CVI_U32 Again_table[AGAIN_MAX_IDX + 1] = { + 1024, 1036, 1050, 1063, 1077, 1092, 1107, 1122, 1137, 1153, + 1170, 1187, 1204, 1222, 1241, 1260, 1280, 1300, 1321, 1342, + 1365, 1388, 1412, 1437, 1462, 1489, 1517, 1545, 1575, 1606, + 1638, 1671, 1706, 1742, 1780, 1820, 1861, 1905, 1950, 1998, + 2048, 2100, 2155, 2214, 2275, 2340, 2409, 2482, 2560, 2642, + 2730, 2824, 2925, 3034, 3150, 3276, 3413, 3561, 3723, 3900, + 4096, 4311, 4551, 4818, 5120 +}; + +static struct again_tbl_info_s AgainInfo = { + .gainMax = 5120, + .idxBase = 0, + .regGainFineBase = 0x7F, + .regGainFineStep = 1, +}; + +typedef struct dgain_tbl_info_s { + CVI_U8 regH[DGAIN_MAX_IDX + 1]; + CVI_U8 regL[DGAIN_MAX_IDX + 1]; +} dgain_tbl_info_s; + +static CVI_U32 Dgain_table[DGAIN_MAX_IDX + 1] = { + 1024, 1084, 1144, 1204, 1264, 1324, 1384, 1444, 1504, 1564, + 1624, 1684, 1744, 1804, 1864, 2004, 2144, 2284, 2424, 2564, + 2704, 2844, 2984, 3124, 3264, 3404, 3544, 3684, 3824, 3964, + 4104, 4244, 4384, 4524, 4664, 4804, 5044, 5284, 5524, 5764, + 6004, 6244, 6484, 6724, 6964, 7204, 7444, 7684, 7924, 8164, + 8404, 8644, 8884, 9124, 9364, 9604, 9844, 10084, 10324, 10564, + 10804, 11044, 11284, 11524, 11764, 12004, 12244, 12484, 12724, 12964, + 13204, 13444, 13684, 13924, 14164, 14404, 14644, 14884, 15124, 15364, + 15604, 15844, 16084, 16324 +}; + +static struct dgain_tbl_info_s DgainInfo = { + .regH = { + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x3, + 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x5, + 0x5, 0x5, 0x5, 0x6, 0x6, 0x6, 0x6, 0x7, 0x7, 0x7, + 0x8, 0x8, 0x8, 0x8, 0x9, 0x9, 0x9, 0xA, 0xA, 0xB, + 0xB, 0xC, 0xC, 0xD, 0xD, 0xE, 0xE, 0xF, 0xF, 0xF, + 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, + 0x15, 0x15, 0x16, 0x16, 0x16, 0x17, 0x17, 0x18, 0x18, 0x19, + 0x19, 0x1A, 0x1A, 0x1B, 0x1B, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, + 0x1E, 0x1E, 0x1F, 0x1F + }, + .regL = { + 0x0, 0x1E, 0x3C, 0x5A, 0x78, 0x96, 0xB4, 0xD2, 0xF0, 0xE, + 0x2C, 0x4A, 0x68, 0x86, 0xA4, 0xEA, 0x30, 0x76, 0xBC, 0x2, + 0x48, 0x8E, 0xD4, 0x1A, 0x60, 0xA6, 0xEC, 0x32, 0x78, 0xBE, + 0x4, 0x4A, 0x90, 0xD6, 0x1C, 0x62, 0xDA, 0x52, 0xCA, 0x42, + 0xBA, 0x32, 0xAA, 0x22, 0x9A, 0x12, 0x8A, 0x2, 0x7A, 0xF2, + 0x6A, 0xE2, 0x5A, 0xD2, 0x4A, 0xC2, 0x3A, 0xB2, 0x2A, 0xA2, + 0x1A, 0x92, 0xA, 0x82, 0xFA, 0x72, 0xEA, 0x62, 0xDA, 0x52, + 0xCA, 0x42, 0xBA, 0x32, 0xAA, 0x22, 0x9A, 0x12, 0x8A, 0x2, + 0x7A, 0xF2, 0x6A, 0xE2 + }, +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[AGAIN_MAX_IDX]) { + *pu32AgainLin = Again_table[AGAIN_MAX_IDX]; + *pu32AgainDb = AGAIN_MAX_IDX; + return CVI_SUCCESS; + } + + for (i = 1; i < AGAIN_MAX_IDX + 1; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[DGAIN_MAX_IDX]) { + *pu32DgainLin = Dgain_table[DGAIN_MAX_IDX]; + *pu32DgainDb = DGAIN_MAX_IDX; + return CVI_SUCCESS; + } + + for (i = 1; i < DGAIN_MAX_IDX + 1; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again, regAgain; + CVI_U32 u32Dgain; + struct again_tbl_info_s *again_info; + + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + again_info = &AgainInfo; + regAgain = again_info->regGainFineBase - u32Again; + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_ADDR].u32Data = (regAgain & 0xFF); + if (regAgain <= 0x4f) + pstSnsRegsInfo->astI2cData[LINEAR_CLAMP_MODE].u32Data = 0x02; + else + pstSnsRegsInfo->astI2cData[LINEAR_CLAMP_MODE].u32Data = 0x00; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H_ADDR].u32Data = (DgainInfo.regH[u32Dgain] & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L_ADDR].u32Data = (DgainInfo.regL[u32Dgain] & 0xFF); + } else { + if (g_au16BG0808_GainMode[ViPipe] == SNS_GAIN_MODE_WDR_2F) { + //SEF Again + again_info = &AgainInfo; + regAgain = again_info->regGainFineBase - u32Again; + pstSnsRegsInfo->astI2cData[WDR_SAGAIN_ADDR].u32Data = (regAgain & 0xFF); + if (regAgain <= 0x4f) + pstSnsRegsInfo->astI2cData[WDR_CLAMP_MODE].u32Data = 0x02; + else + pstSnsRegsInfo->astI2cData[WDR_CLAMP_MODE].u32Data = 0x00; + //SEF Dgain + pstSnsRegsInfo->astI2cData[WDR_SDGAIN_H_ADDR].u32Data = (DgainInfo.regH[u32Dgain] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_SDGAIN_L_ADDR].u32Data = (DgainInfo.regL[u32Dgain] & 0xFF); + + //LEF Again + u32Again = pu32Again[1]; + again_info = &AgainInfo; + regAgain = again_info->regGainFineBase - u32Again; + pstSnsRegsInfo->astI2cData[WDR_AGAIN_ADDR].u32Data = (regAgain & 0xFF); + if (regAgain <= 0x4f) + pstSnsRegsInfo->astI2cData[WDR_CLAMP_MODE].u32Data = 0x02; + else + pstSnsRegsInfo->astI2cData[WDR_CLAMP_MODE].u32Data = 0x00; + //LEF Dgain + u32Dgain = pu32Dgain[1]; + pstSnsRegsInfo->astI2cData[WDR_DGAIN_H_ADDR].u32Data = (DgainInfo.regH[u32Dgain] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_DGAIN_L_ADDR].u32Data = (DgainInfo.regL[u32Dgain] & 0xFF); + } else if (g_au16BG0808_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + //SEF Again + again_info = &AgainInfo; + regAgain = again_info->regGainFineBase - u32Again; + pstSnsRegsInfo->astI2cData[WDR_SAGAIN_ADDR].u32Data = (regAgain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_AGAIN_ADDR].u32Data = (regAgain & 0xFF); + if (regAgain <= 0x4f) + pstSnsRegsInfo->astI2cData[WDR_CLAMP_MODE].u32Data = 0x02; + else + pstSnsRegsInfo->astI2cData[WDR_CLAMP_MODE].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[WDR_SDGAIN_H_ADDR].u32Data = (DgainInfo.regH[u32Dgain] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_SDGAIN_L_ADDR].u32Data = (DgainInfo.regL[u32Dgain] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_DGAIN_H_ADDR].u32Data = (DgainInfo.regH[u32Dgain] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_DGAIN_L_ADDR].u32Data = (DgainInfo.regL[u32Dgain] & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = 1; + /* + * Long exp + Short exp < VTS + */ + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 1 - g_astBG0808_mode[pstSnsState->u8ImgMode].u32IspResTime - + pstSnsState->au32WDRIntTime[0]) * 0x40) / DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 1 - g_astBG0808_mode[pstSnsState->u8ImgMode].u32IspResTime) + * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? u32ShortTimeMinLimit : u32IntTimeMaxTmp; + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio is too large!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + CVI_TRACE_SNS(CVI_DBG_DEBUG, "sexp[%d, %d], lexp[%d, %d], ratio:%d\n", + au32IntTimeMin[0], au32IntTimeMax[0], au32IntTimeMin[1], au32IntTimeMax[1], au32Ratio[0]); + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + //memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + //&g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const BG0808_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astBG0808_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = BG0808_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astBG0808_mode[pstSnsState->u8ImgMode].u32VtsDef; + CVI_TRACE_SNS(CVI_DBG_DEBUG, "linear mode\n"); + break; + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == BG0808_MODE_1920X1080P30) + pstSnsState->u8ImgMode = BG0808_MODE_1920X1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astBG0808_mode[pstSnsState->u8ImgMode].u32VtsDef; + CVI_TRACE_SNS(CVI_DBG_DEBUG, "2to1 line WDR 1080p mode(60fps->30fps)\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunBG0808_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = bg0808_i2c_addr; + pstI2c_data[i].u32AddrByteNum = bg0808_addr_byte; + pstI2c_data[i].u32DataByteNum = bg0808_data_byte; + } + + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = BG0808_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = BG0808_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = BG0808_AGAIN_ADDR; + pstI2c_data[LINEAR_CLAMP_MODE].u32RegAddr = BG0808_CLAMP_MODE_ADDR; + pstI2c_data[LINEAR_CLAMP_MODE].u32Data = 0x00; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = BG0808_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = BG0808_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = BG0808_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = BG0808_VMAX_L_ADDR; + pstI2c_data[LINEAR_SHADOW_ADDR].u32RegAddr = BG0808_SHADOW_ADDR; + pstI2c_data[LINEAR_SHADOW_ADDR].u32Data = 0x02; + break; + case WDR_MODE_2To1_LINE: + pstI2c_data[WDR_EXP_H_ADDR].u32RegAddr = BG0808_EXP_H_ADDR; + pstI2c_data[WDR_EXP_L_ADDR].u32RegAddr = BG0808_EXP_L_ADDR; + pstI2c_data[WDR_SEXP_H_ADDR].u32RegAddr = BG0808_SEXP_H_ADDR; + pstI2c_data[WDR_SEXP_L_ADDR].u32RegAddr = BG0808_SEXP_L_ADDR; + pstI2c_data[WDR_AGAIN_ADDR].u32RegAddr = BG0808_AGAIN_ADDR; + pstI2c_data[WDR_SAGAIN_ADDR].u32RegAddr = BG0808_SAGAIN_ADDR; + pstI2c_data[WDR_CLAMP_MODE].u32RegAddr = BG0808_CLAMP_MODE_ADDR; + pstI2c_data[WDR_CLAMP_MODE].u32Data = 0x00; + pstI2c_data[WDR_DGAIN_H_ADDR].u32RegAddr = BG0808_DGAIN_H_ADDR; + pstI2c_data[WDR_DGAIN_L_ADDR].u32RegAddr = BG0808_DGAIN_L_ADDR; + pstI2c_data[WDR_SDGAIN_H_ADDR].u32RegAddr = BG0808_SDGAIN_H_ADDR; + pstI2c_data[WDR_SDGAIN_L_ADDR].u32RegAddr = BG0808_SDGAIN_L_ADDR; + pstI2c_data[WDR_VMAX_H_ADDR].u32RegAddr = BG0808_VMAX_H_ADDR; + pstI2c_data[WDR_VMAX_L_ADDR].u32RegAddr = BG0808_VMAX_L_ADDR; + pstI2c_data[WDR_SHADOW_ADDR].u32RegAddr = BG0808_SHADOW_ADDR; + pstI2c_data[WDR_SHADOW_ADDR].u32Data = 0x02; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.need_update = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + } + } + pstCfg0->snsCfg.astI2cData[pstCfg0->snsCfg.u32RegNum - 1].u32Data = 0x02; + pstCfg0->snsCfg.astI2cData[pstCfg0->snsCfg.u32RegNum - 1].bUpdate = CVI_TRUE; + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (BG0808_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = BG0808_MODE_1920X1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (BG0808_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = BG0808_MODE_1920X1080P30_WDR; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeBg0808_MirrorFip[ViPipe] != eSnsMirrorFlip) { + bg0808_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeBg0808_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const BG0808_MODE_S *pstMode = CVI_NULL; + + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = BG0808_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astBG0808_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + BG0808_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &bg0808_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astBG0808_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astBG0808_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstRxAttr->mclk.freq = CAMPLL_FREQ_27M; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &bg0808_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = bg0808_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = bg0808_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (BG0808_I2C_ADDR_IS_VALID(s32I2cAddr)) + bg0808_i2c_addr = s32I2cAddr; +} + +static CVI_S32 bg0808_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunBG0808_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + BG0808_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + BG0808_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + BG0808_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + BG0808_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = BG0808_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, BG0808_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, BG0808_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, BG0808_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16BG0808_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16BG0808_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsBG0808_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = bg0808_standby, + .pfnRestart = bg0808_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = bg0808_write_register, + .pfnReadReg = bg0808_read_register, + .pfnSetBusInfo = bg0808_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = bg0808_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/brigates_bg0808/bg0808_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/brigates_bg0808/bg0808_cmos_ex.h new file mode 100644 index 000000000..320272034 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/brigates_bg0808/bg0808_cmos_ex.h @@ -0,0 +1,99 @@ +#ifndef __BG0808_CMOS_EX_H_ +#define __BG0808_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum bg0808_linear_regs_e { + LINEAR_EXP_H_ADDR,//0x0c + LINEAR_EXP_L_ADDR,//0x0d + LINEAR_AGAIN_ADDR,//0x00a2 + LINEAR_CLAMP_MODE,//0x73 need change when again changed + LINEAR_DGAIN_H_ADDR,//0x00c0 + LINEAR_DGAIN_L_ADDR,//0x00c1 + LINEAR_VMAX_H_ADDR,//0x0010 + LINEAR_VMAX_L_ADDR,//0x0011 + LINEAR_SHADOW_ADDR,//0x001d + LINEAR_REGS_NUM +}; +enum bg0808_wdr_regs_e { + WDR_EXP_H_ADDR, + WDR_EXP_L_ADDR, + WDR_SEXP_H_ADDR,//0x22 + WDR_SEXP_L_ADDR,//0x23 + WDR_AGAIN_ADDR,//0x00a2 + WDR_SAGAIN_ADDR,//0x00a4 + WDR_CLAMP_MODE,//0x73 need change when again changed + WDR_DGAIN_H_ADDR, + WDR_DGAIN_L_ADDR, + WDR_SDGAIN_H_ADDR,//0x00c2 + WDR_SDGAIN_L_ADDR,//0x00c3 + WDR_VMAX_H_ADDR, + WDR_VMAX_L_ADDR, + WDR_SHADOW_ADDR, + WDR_REGS_NUM +}; + +typedef enum _BG0808_MODE_E { + BG0808_MODE_1920X1080P30 = 0, + BG0808_MODE_LINEAR_NUM, + BG0808_MODE_1920X1080P30_WDR = BG0808_MODE_LINEAR_NUM, + BG0808_MODE_NUM +} BG0808_MODE_E; + +typedef struct _BG0808_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + CVI_U32 u32IspResTime; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} BG0808_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastBG0808[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunBG0808_BusInfo[]; +extern CVI_U16 g_au16BG0808_GainMode[]; +extern CVI_U16 g_au16BG0808_L2SMode[]; +extern CVI_U8 bg0808_i2c_addr; +extern const CVI_U32 bg0808_addr_byte; +extern const CVI_U32 bg0808_data_byte; +extern void bg0808_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void bg0808_init(VI_PIPE ViPipe); +extern void bg0808_exit(VI_PIPE ViPipe); +extern void bg0808_standby(VI_PIPE ViPipe); +extern void bg0808_restart(VI_PIPE ViPipe); +extern int bg0808_write_register(VI_PIPE ViPipe, int addr, int data); +extern int bg0808_read_register(VI_PIPE ViPipe, int addr); +extern int bg0808_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __BG0808_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/brigates_bg0808/bg0808_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/brigates_bg0808/bg0808_cmos_param.h new file mode 100644 index 000000000..556578ce7 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/brigates_bg0808/bg0808_cmos_param.h @@ -0,0 +1,220 @@ +#ifndef __BG0808_CMOS_PARAM_H_ +#define __BG0808_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "bg0808_cmos_ex.h" + +static const BG0808_MODE_S g_astBG0808_mode[BG0808_MODE_NUM] = { + [BG0808_MODE_1920X1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1920, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.52, /* 1125(0x465) * 30 / 0xFFFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1124,//vts - 1 + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 5120, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16324, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [BG0808_MODE_1920X1080P30_WDR] = { + .name = "1080p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.52, /* 1125(0x465) * 30 / 0xFFFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp[0] = {//sexp + .u16Min = 1, + .u16Max = 1124,//vts - 1 + .u16Def = 400, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 1124,//vts - 1 + .u16Def = 400, + .u16Step = 1, + }, + .u32IspResTime = 34, /* ceil((u32Vts * f32MaxFps) / 1000); about 1ms*/ + .stAgain[0] = {//sagain + .u32Min = 1024, + .u32Max = 5120, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 5120, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = {//sagain + .u32Min = 1024, + .u32Max = 16324, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 16324, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + #if 0 + .stManual = {0, 0, 0, 0, 0, 0, 0, 0, 1024, 1024, 1024, 1024}, + .stAuto = { + {0, 0, 0, 0, 0, 0, 0, 0, /*8*/0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, /*8*/0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, /*8*/0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, /*8*/0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + /*8*/1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024}, + {1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + /*8*/1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024}, + {1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + /*8*/1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024}, + {1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + /*8*/1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024}, + }, + #endif + #if 1 //use test result as blc offset + .stManual = {28, 28, 28, 28, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1031, 1031, 1031, 1031 +#endif + }, + .stAuto = { + {28, 28, 28, 28, 28, 28, 28, 28, /*8*/28, 28, 28, 28, 28, 28, 28, 28}, + {28, 28, 28, 28, 28, 28, 28, 28, /*8*/28, 28, 28, 28, 28, 28, 28, 28}, + {28, 28, 28, 28, 28, 28, 28, 28, /*8*/28, 28, 28, 28, 28, 28, 28, 28}, + {28, 28, 28, 28, 28, 28, 28, 28, /*8*/28, 28, 28, 28, 28, 28, 28, 28}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, + /*8*/1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031}, + {1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, + /*8*/1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031}, + {1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, + /*8*/1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031}, + {1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, + /*8*/1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031}, +#endif + }, + #endif + }, +}; + +struct combo_dev_attr_s bg0808_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 0, 1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __BG0808_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/brigates_bg0808/bg0808_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/brigates_bg0808/bg0808_sensor_ctl.c new file mode 100644 index 000000000..00e23cd18 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/brigates_bg0808/bg0808_sensor_ctl.c @@ -0,0 +1,445 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "bg0808_cmos_ex.h" + +#define BG0808_CHIP_ID_HI_ADDR 0x0000 +#define BG0808_CHIP_ID_LO_ADDR 0x0001 +#define BG0808_CHIP_ID 0x0808 +static void bg0808_linear_1080P30_init(VI_PIPE ViPipe); +static void bg0808_wdr_1080P30_2to1_init(VI_PIPE ViPipe); +CVI_U8 bg0808_i2c_addr = 0x32; /* I2C Address of BG0808 */ +const CVI_U32 bg0808_addr_byte = 2; +const CVI_U32 bg0808_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int bg0808_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunBG0808_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, bg0808_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int bg0808_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +int bg0808_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (bg0808_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, bg0808_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, bg0808_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (bg0808_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int bg0808_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (bg0808_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (bg0808_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, bg0808_addr_byte + bg0808_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + + return CVI_SUCCESS; +} + +void bg0808_standby(VI_PIPE ViPipe) +{ + (void) ViPipe; + CVI_TRACE_SNS(CVI_DBG_NOTICE, "unsupport standby.\n"); +} + +void bg0808_restart(VI_PIPE ViPipe) +{ + (void) ViPipe; + CVI_TRACE_SNS(CVI_DBG_NOTICE, "unsupport restart.\n"); +} + +void bg0808_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastBG0808[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastBG0808[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + bg0808_write_register(ViPipe, + g_pastBG0808[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastBG0808[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void bg0808_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + bg0808_write_register(ViPipe, 0x0020, val); + bg0808_write_register(ViPipe, 0x001d, 0x02); +} + +int bg0808_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + delay_ms(4); + if (bg0808_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = bg0808_read_register(ViPipe, BG0808_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = bg0808_read_register(ViPipe, BG0808_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != BG0808_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void bg0808_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastBG0808[ViPipe]->enWDRMode; + u8ImgMode = g_pastBG0808[ViPipe]->u8ImgMode; + + if (g_fd[ViPipe] < 0) + bg0808_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == BG0808_MODE_1920X1080P30_WDR) { + bg0808_wdr_1080P30_2to1_init(ViPipe); + } else { + } + } else { + bg0808_linear_1080P30_init(ViPipe); + } + + g_pastBG0808[ViPipe]->bInit = CVI_TRUE; +} + +void bg0808_exit(VI_PIPE ViPipe) +{ + bg0808_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void bg0808_linear_1080P30_init(VI_PIPE ViPipe) +{ + delay_ms(20); + bg0808_write_register(ViPipe, 0x00b1, 0x55); + bg0808_write_register(ViPipe, 0x00cc, 0x07); + bg0808_write_register(ViPipe, 0x00e4, 0x14); + bg0808_write_register(ViPipe, 0x00fa, 0x7f); + bg0808_write_register(ViPipe, 0x0391, 0x84); + bg0808_write_register(ViPipe, 0x0390, 0x06); + bg0808_write_register(ViPipe, 0x0398, 0x15); + + bg0808_write_register(ViPipe, 0x03b2, 0x00);//hs trail, default 0x3c + bg0808_write_register(ViPipe, 0x03b3, 0x78); + + bg0808_write_register(ViPipe, 0x03c3, 0x10); + bg0808_write_register(ViPipe, 0x0392, 0x00); + bg0808_write_register(ViPipe, 0x0045, 0x01); + bg0808_write_register(ViPipe, 0x0046, 0x03); + bg0808_write_register(ViPipe, 0x0074, 0x00); + bg0808_write_register(ViPipe, 0x0075, 0x04); + bg0808_write_register(ViPipe, 0x00ae, 0x0a); + bg0808_write_register(ViPipe, 0x00d0, 0x02); + bg0808_write_register(ViPipe, 0x00b2, 0x05); + bg0808_write_register(ViPipe, 0x0120, 0x01); + bg0808_write_register(ViPipe, 0x01a5, 0x07); + bg0808_write_register(ViPipe, 0x007c, 0x04); + bg0808_write_register(ViPipe, 0x00a8, 0x0f); + bg0808_write_register(ViPipe, 0x0030, 0x30); + bg0808_write_register(ViPipe, 0x0032, 0x01); + bg0808_write_register(ViPipe, 0x0033, 0xed); + bg0808_write_register(ViPipe, 0x0034, 0x1e); + bg0808_write_register(ViPipe, 0x002c, 0x00); + bg0808_write_register(ViPipe, 0x002d, 0x2b); + bg0808_write_register(ViPipe, 0x002e, 0x02); + bg0808_write_register(ViPipe, 0x000e, 0x08); + bg0808_write_register(ViPipe, 0x000f, 0x98); + bg0808_write_register(ViPipe, 0x0010, 0x04); + bg0808_write_register(ViPipe, 0x0011, 0x65); + bg0808_write_register(ViPipe, 0x0070, 0x00); + bg0808_write_register(ViPipe, 0x0071, 0x01); + bg0808_write_register(ViPipe, 0x0069, 0x01); + bg0808_write_register(ViPipe, 0x004b, 0x02); + bg0808_write_register(ViPipe, 0x004c, 0x02); + bg0808_write_register(ViPipe, 0x0049, 0x00); + bg0808_write_register(ViPipe, 0x004a, 0x08); + bg0808_write_register(ViPipe, 0x004d, 0x0b); + bg0808_write_register(ViPipe, 0x004e, 0x01); + bg0808_write_register(ViPipe, 0x004f, 0x00); + bg0808_write_register(ViPipe, 0x0050, 0x2a); + bg0808_write_register(ViPipe, 0x0051, 0x00); + bg0808_write_register(ViPipe, 0x0052, 0x4a); + bg0808_write_register(ViPipe, 0x0055, 0x04); + bg0808_write_register(ViPipe, 0x0056, 0x00); + bg0808_write_register(ViPipe, 0x0057, 0x1e); + bg0808_write_register(ViPipe, 0x0084, 0x00); + bg0808_write_register(ViPipe, 0x0085, 0xb9); + bg0808_write_register(ViPipe, 0x0058, 0x02); + bg0808_write_register(ViPipe, 0x005a, 0x00); + bg0808_write_register(ViPipe, 0x005b, 0x4a); + bg0808_write_register(ViPipe, 0x005c, 0x00); + bg0808_write_register(ViPipe, 0x005d, 0x4a); + bg0808_write_register(ViPipe, 0x0086, 0x01); + bg0808_write_register(ViPipe, 0x0087, 0xda); + bg0808_write_register(ViPipe, 0x0088, 0x02); + bg0808_write_register(ViPipe, 0x006f, 0x02); + bg0808_write_register(ViPipe, 0x005e, 0x01); + bg0808_write_register(ViPipe, 0x0043, 0x02); + bg0808_write_register(ViPipe, 0x0044, 0x02); + bg0808_write_register(ViPipe, 0x0039, 0x00); + bg0808_write_register(ViPipe, 0x003a, 0xa0); + bg0808_write_register(ViPipe, 0x0037, 0x00); + bg0808_write_register(ViPipe, 0x0038, 0x80); + bg0808_write_register(ViPipe, 0x006d, 0x0d); + bg0808_write_register(ViPipe, 0x0064, 0x15); + bg0808_write_register(ViPipe, 0x00a1, 0x0c); + bg0808_write_register(ViPipe, 0x00aa, 0x0c); + bg0808_write_register(ViPipe, 0x00bc, 0x02); + bg0808_write_register(ViPipe, 0x0046, 0x00); + //blc + bg0808_write_register(ViPipe, 0x0130, 0x00);// blc, default 0x18 + bg0808_write_register(ViPipe, 0x0131, 0x18); + bg0808_write_register(ViPipe, 0x001d, 0x01); + + bg0808_default_reg_init(ViPipe); + delay_ms(20); + + printf("ViPipe:%d,===BG0808 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} +static void bg0808_wdr_1080P30_2to1_init(VI_PIPE ViPipe) +{ + delay_ms(20); + bg0808_write_register(ViPipe, 0x00b1, 0x55); + bg0808_write_register(ViPipe, 0x00cc, 0x07); + bg0808_write_register(ViPipe, 0x00e4, 0x14); + bg0808_write_register(ViPipe, 0x00fa, 0x7f); + bg0808_write_register(ViPipe, 0x0391, 0x84); + bg0808_write_register(ViPipe, 0x0390, 0x06); + bg0808_write_register(ViPipe, 0x03c3, 0x10); + bg0808_write_register(ViPipe, 0x0392, 0x00); + + bg0808_write_register(ViPipe, 0x03b2, 0x00);//hs trail, default 0x3c + bg0808_write_register(ViPipe, 0x03b3, 0x78); + + bg0808_write_register(ViPipe, 0x0045, 0x01); + bg0808_write_register(ViPipe, 0x0046, 0x03); + bg0808_write_register(ViPipe, 0x0074, 0x00); + bg0808_write_register(ViPipe, 0x0075, 0x04); + bg0808_write_register(ViPipe, 0x00ae, 0x0a); + bg0808_write_register(ViPipe, 0x00d0, 0x02); + bg0808_write_register(ViPipe, 0x00b2, 0x05); + bg0808_write_register(ViPipe, 0x0120, 0x01); + bg0808_write_register(ViPipe, 0x01a5, 0x07); + bg0808_write_register(ViPipe, 0x007c, 0x04); + bg0808_write_register(ViPipe, 0x00a8, 0x0f); + bg0808_write_register(ViPipe, 0x0032, 0x00); + bg0808_write_register(ViPipe, 0x0033, 0x35); + bg0808_write_register(ViPipe, 0x0034, 0x00); + bg0808_write_register(ViPipe, 0x002c, 0x00); + bg0808_write_register(ViPipe, 0x002d, 0x13); + bg0808_write_register(ViPipe, 0x002e, 0x00); + bg0808_write_register(ViPipe, 0x000e, 0x11); + bg0808_write_register(ViPipe, 0x000f, 0x30); + bg0808_write_register(ViPipe, 0x0010, 0x04); + bg0808_write_register(ViPipe, 0x0011, 0x65); + bg0808_write_register(ViPipe, 0x0070, 0x00); + bg0808_write_register(ViPipe, 0x0071, 0x01); + bg0808_write_register(ViPipe, 0x0069, 0x01); + bg0808_write_register(ViPipe, 0x004b, 0x04); + bg0808_write_register(ViPipe, 0x004c, 0x04); + bg0808_write_register(ViPipe, 0x0049, 0x00); + bg0808_write_register(ViPipe, 0x004a, 0x0f); + bg0808_write_register(ViPipe, 0x004d, 0x14); + bg0808_write_register(ViPipe, 0x004e, 0x01); + bg0808_write_register(ViPipe, 0x004f, 0x00); + bg0808_write_register(ViPipe, 0x0050, 0x53); + bg0808_write_register(ViPipe, 0x0051, 0x00); + bg0808_write_register(ViPipe, 0x0052, 0x93); + bg0808_write_register(ViPipe, 0x0055, 0x08); + bg0808_write_register(ViPipe, 0x0056, 0x00); + bg0808_write_register(ViPipe, 0x0057, 0x3b); + bg0808_write_register(ViPipe, 0x0084, 0x01); + bg0808_write_register(ViPipe, 0x0085, 0x72); + bg0808_write_register(ViPipe, 0x0058, 0x04); + bg0808_write_register(ViPipe, 0x005a, 0x00); + bg0808_write_register(ViPipe, 0x005b, 0x93); + bg0808_write_register(ViPipe, 0x005c, 0x00); + bg0808_write_register(ViPipe, 0x005d, 0x93); + bg0808_write_register(ViPipe, 0x0086, 0x03); + bg0808_write_register(ViPipe, 0x0087, 0x8e); + bg0808_write_register(ViPipe, 0x0088, 0x04); + bg0808_write_register(ViPipe, 0x006f, 0x04); + bg0808_write_register(ViPipe, 0x005e, 0x01); + bg0808_write_register(ViPipe, 0x0043, 0x04); + bg0808_write_register(ViPipe, 0x0044, 0x04); + bg0808_write_register(ViPipe, 0x0039, 0x01); + bg0808_write_register(ViPipe, 0x003a, 0x40); + bg0808_write_register(ViPipe, 0x0037, 0x01); + bg0808_write_register(ViPipe, 0x0038, 0x00); + bg0808_write_register(ViPipe, 0x006d, 0x0e); + bg0808_write_register(ViPipe, 0x0064, 0x16); + bg0808_write_register(ViPipe, 0x0021, 0x01); + bg0808_write_register(ViPipe, 0x0041, 0x01); + bg0808_write_register(ViPipe, 0x0042, 0x40); + bg0808_write_register(ViPipe, 0x003f, 0x01); + bg0808_write_register(ViPipe, 0x0040, 0x00); + bg0808_write_register(ViPipe, 0x0098, 0x00); + bg0808_write_register(ViPipe, 0x0099, 0x88); + bg0808_write_register(ViPipe, 0x009a, 0x01); + bg0808_write_register(ViPipe, 0x009b, 0x88); + bg0808_write_register(ViPipe, 0x009c, 0x01); + bg0808_write_register(ViPipe, 0x009d, 0x72); + bg0808_write_register(ViPipe, 0x009e, 0x03); + bg0808_write_register(ViPipe, 0x009f, 0x8e); + bg0808_write_register(ViPipe, 0x00a1, 0x0c); + bg0808_write_register(ViPipe, 0x00a3, 0x0c); + bg0808_write_register(ViPipe, 0x00aa, 0x0c); + bg0808_write_register(ViPipe, 0x00ab, 0x0c); + bg0808_write_register(ViPipe, 0x00bc, 0x02); + bg0808_write_register(ViPipe, 0x0046, 0x00); + //blc + bg0808_write_register(ViPipe, 0x0130, 0x00);// blc, default 0x18 + bg0808_write_register(ViPipe, 0x0131, 0x18); + bg0808_write_register(ViPipe, 0x001d, 0x01); + + bg0808_default_reg_init(ViPipe); + delay_ms(20); + + printf("ViPipe:%d,===BG0808 1080P 30fps 10bit WDR2TO1 Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc02m1/Makefile b/middleware/v2/component/isp/sensor/cv181x/gcore_gc02m1/Makefile new file mode 100644 index 000000000..33f4be44f --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc02m1/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc02m1.a +TARGET_SO = $(MW_LIB)/libsns_gc02m1.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc02m1/gc02m1_cmos.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc02m1/gc02m1_cmos.c new file mode 100644 index 000000000..3f2767e4b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc02m1/gc02m1_cmos.c @@ -0,0 +1,874 @@ +#include +#include +#include +#include +#include +#include +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" +#include "gc02m1_cmos_ex.h" +#include "gc02m1_cmos_param.h" +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#include "cvi_type.h" +#else +#include +#include +#include +#endif + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define GC02M1_ID 0x02e0 +#define GC02M1_I2C_ADDR_1 0x37 +#define GC02M1_I2C_ADDR_2 0x10 +#define GC02M1_I2C_ADDR_IS_VALID(addr) ((addr) == GC02M1_I2C_ADDR_1 || (addr) == GC02M1_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ***************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc02m1[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC02M1_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc02m1[dev]) +#define GC02M1_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc02m1[dev] = pstCtx) +#define GC02M1_SENSOR_RESET_CTX(dev) (g_pastGc02m1[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc02m1_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 3}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc02m1_MirrorFip[VI_MAX_PIPE_NUM] = {ISP_SNS_NORMAL}; + +CVI_U16 g_au16Gc02m1_GainMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ***************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Gc02m1 Lines Range*****/ +#define GC02M1_FULL_LINES_MAX (0x3fff) + +/*****Gc02m1 Register Address*****/ +#define GC02M1_PAGE_0_ADDR 0xfe +#define GC02M1_EXP_H_ADDR 0x03 //bit[13:8] +#define GC02M1_EXP_L_ADDR 0x04 + +#define GC02M1_AGAIN_ADDR 0xb6 //bit[4:0] + +#define GC02M1_VTS_H_ADDR 0x41 //bit[13:8] +#define GC02M1_VTS_L_ADDR 0x42 + +#define GC02M1_MIRROR_FLIP_ADDR 0x17 + +#define GC02M1_RES_IS_1200P(w, h) ((w) <= 1600 && (h) <= 1200) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC02M1_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astGc02m1_mode[GC02M1_MODE_1600X1200P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astGc02m1_mode[GC02M1_MODE_1600X1200P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 60880; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 1024; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? + g_au32InitExposure[ViPipe] : g_astGc02m1_mode[GC02M1_MODE_1600X1200P30].stExp[0].u16Def; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstAeSnsDft->u32MinIntTime = g_astGc02m1_mode[GC02M1_MODE_1600X1200P30].stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astGc02m1_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astGc02m1_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astGc02m1_mode[pstSnsState->u8ImgMode].f32MinFps; + + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + + u32VMAX = (u32VMAX > GC02M1_FULL_LINES_MAX) ? GC02M1_FULL_LINES_MAX : u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = ((u32IntTime[0] >> 8) & 0x3F); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_U32 regValTable[] = { + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, +}; + +static CVI_U32 gain_table[] = { + 16 * 64, + 16 * 96, + 16 * 127, + 16 * 157, + 16 * 197, + 16 * 226, + 16 * 259, + 16 * 287, + 16 * 318, + 16 * 356, + 16 * 391, + 16 * 419, + 16 * 450, + 16 * 480, + 16 * 513, + 16 * 646, +}; + + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + int total = ARRAY_SIZE(gain_table); + + if (*pu32AgainLin >= gain_table[total - 1]) { + *pu32AgainDb = total - 1; + *pu32AgainLin = gain_table[total - 1]; + return CVI_SUCCESS; + } + + for (i = 0; i < total; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainDb = i - 1; + break; + } + } + *pu32AgainLin = gain_table[i - 1]; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + UNUSED(ViPipe); + + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + /* only surpport linear mode */ + u32Again = pu32Again[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN].u32Data = regValTable[u32Again]; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + UNUSED(ViPipe); + UNUSED(u16ManRatioEnable); + UNUSED(au32Ratio); + UNUSED(au32IntTimeMax); + UNUSED(au32IntTimeMin); + UNUSED(pu32LFMaxIntTime); + + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode\n"); + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + UNUSED(ViPipe); + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + UNUSED(ViPipe); + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + CMOS_CHECK_POINTER(pstBlc); + UNUSED(ViPipe); + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC02M1_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astGc02m1_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + UNUSED(ViPipe); + UNUSED(u8Mode); + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunGc02m1_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = gc02m1_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc02m1_addr_byte; + pstI2c_data[i].u32DataByteNum = gc02m1_data_byte; + } + + pstI2c_data[LINEAR_PAGE_0].u32RegAddr = GC02M1_PAGE_0_ADDR; + pstI2c_data[LINEAR_PAGE_0].u32Data = 0; + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC02M1_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC02M1_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN].u32RegAddr = GC02M1_AGAIN_ADDR; + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC02M1_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC02M1_VTS_L_ADDR; + pstI2c_data[LINEAR_MIRROR_FLIP].u32RegAddr = GC02M1_MIRROR_FLIP_ADDR; + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + + CVI_U32 gainsUpdate = 0, shutterUpdate = 0, vtsUpdate = 0; + + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + if (i == LINEAR_AGAIN) + gainsUpdate = 1; + + if (i <= LINEAR_EXP_L && i >= LINEAR_EXP_H) + shutterUpdate = 1; + + if ((i >= LINEAR_VTS_H) && (i <= LINEAR_VTS_L)) + vtsUpdate = 1; + + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (gainsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN].bUpdate = CVI_TRUE; + } + if (shutterUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_L].bUpdate = CVI_TRUE; + } + if (vtsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_VTS_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_VTS_L].bUpdate = CVI_TRUE; + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC02M1_RES_IS_1200P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC02M1_MODE_1600X1200P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U8 value; + + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc02m1_MirrorFip[ViPipe] != eSnsMirrorFlip) { + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + value = 0; + break; + case ISP_SNS_MIRROR: + value = 0x01; + break; + case ISP_SNS_FLIP: + value = 0x02; + break; + case ISP_SNS_MIRROR_FLIP: + value = 0x03; + break; + default: + return; + } + + pstSnsRegsInfo->astI2cData[LINEAR_MIRROR_FLIP].u32Data = value; + + g_aeGc02m1_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC02M1_MODE_1600X1200P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astGc02m1_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astGc02m1_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astGc02m1_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC02M1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc02m1_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astGc02m1_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astGc02m1_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc02m1_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc02m1_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc02m1_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (GC02M1_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc02m1_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc02m1_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc02m1_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC02M1_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC02M1_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC02M1_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC02M1_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC02M1_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC02M1_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC02M1_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC02M1_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Gc02m1_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc02m1_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc02m1_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc02m1_standby, + .pfnRestart = gc02m1_restart, + .pfnWriteReg = gc02m1_write_register, + .pfnReadReg = gc02m1_read_register, + .pfnSetBusInfo = gc02m1_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc02m1/gc02m1_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc02m1/gc02m1_cmos_ex.h new file mode 100644 index 000000000..62ca1b906 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc02m1/gc02m1_cmos_ex.h @@ -0,0 +1,85 @@ +#ifndef __GC02M1_CMOS_EX_H_ +#define __GC02M1_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum gc02m1_linear_regs_e { + LINEAR_PAGE_0, + LINEAR_EXP_H, + LINEAR_EXP_L, + LINEAR_AGAIN, + LINEAR_VTS_H, + LINEAR_VTS_L, + LINEAR_MIRROR_FLIP, + + LINEAR_REGS_NUM +}; + +typedef enum _GC02M1_MODE_E { + GC02M1_MODE_1600X1200P30 = 0, + GC02M1_MODE_LINEAR_NUM, + GC02M1_MODE_NUM +} GC02M1_MODE_E; + +typedef struct _GC02M1_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC02M1_STATE_S; + +typedef struct _GC02M1_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} GC02M1_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc02m1[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc02m1_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc02m1_MirrorFip[VI_MAX_PIPE_NUM]; +extern CVI_U8 gc02m1_i2c_addr; +extern const CVI_U32 gc02m1_addr_byte; +extern const CVI_U32 gc02m1_data_byte; +extern void gc02m1_init(VI_PIPE ViPipe); +extern void gc02m1_exit(VI_PIPE ViPipe); +extern void gc02m1_standby(VI_PIPE ViPipe); +extern void gc02m1_restart(VI_PIPE ViPipe); +extern int gc02m1_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc02m1_read_register(VI_PIPE ViPipe, int addr); +extern int gc02m1_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC02M1_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc02m1/gc02m1_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc02m1/gc02m1_cmos_param.h new file mode 100644 index 000000000..24c74f4d8 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc02m1/gc02m1_cmos_param.h @@ -0,0 +1,123 @@ +#ifndef __GC02M1_CMOS_PARAM_H_ +#define __GC02M1_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif + +#include "cvi_sns_ctrl.h" +#include "gc02m1_cmos_ex.h" + +static const GC02M1_MODE_S g_astGc02m1_mode[GC02M1_MODE_NUM] = { + [GC02M1_MODE_1600X1200P30] = { + .name = "1600X1200P30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1600, + .u32Height = 1200, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1600, + .u32Height = 1200, + }, + .stMaxSize = { + .u32Width = 1600, + .u32Height = 1200, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.32, /* 1268 * 30 / 0x3FFF */ + .u32HtsDef = 1774, + .u32VtsDef = 1268, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1268 - 8, + .u16Def = 100, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 16 * 646, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 1024, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256 }, + {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256 }, + {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256 }, + {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + 1092, 1092}, +#endif + }, + }, +}; + +struct combo_dev_attr_s gc02m1_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {0, 1, -1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC02M1_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc02m1/gc02m1_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc02m1/gc02m1_sensor_ctl.c new file mode 100644 index 000000000..2b41380f4 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc02m1/gc02m1_sensor_ctl.c @@ -0,0 +1,475 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc02m1_cmos_ex.h" +#define GC02M1_CHIP_ID_ADDR_H 0xf0 +#define GC02M1_CHIP_ID_ADDR_L 0xf1 +#define GC02M1_CHIP_ID 0x02e0 + +#define GC02M1_MIRROR_NORMAL 1 +#define GC02M1_MIRROR_H 0 +#define GC02M1_MIRROR_V 0 +#define GC02M1_MIRROR_HV 0 + +#if GC02M1_MIRROR_NORMAL +#define GC02M1_MIRROR 0x80 +#elif GC02M1_MIRROR_H +#define GC02M1_MIRROR 0x81 +#elif GC02M1_MIRROR_V +#define GC02M1_MIRROR 0x82 +#elif GC02M1_MIRROR_HV +#define GC02M1_MIRROR 0x83 +#else +#define GC02M1_MIRROR 0x80 +#endif + +static void gc02m1_linear_1200p30_init(VI_PIPE ViPipe); + +CVI_U8 gc02m1_i2c_addr = 0x37; +const CVI_U32 gc02m1_addr_byte = 1; +const CVI_U32 gc02m1_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc02m1_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc02m1_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc02m1_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc02m1_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc02m1_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (gc02m1_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc02m1_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, gc02m1_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc02m1_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_INFO, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int gc02m1_write_register(VI_PIPE ViPipe, int addr, int data) +{ + int idx = 0; + int ret; + char buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc02m1_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + if (gc02m1_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc02m1_addr_byte + gc02m1_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + + ret = read(g_fd[ViPipe], buf, gc02m1_addr_byte + gc02m1_data_byte); + syslog(LOG_INFO, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void gc02m1_standby(VI_PIPE ViPipe) +{ + int nVal; + + gc02m1_write_register(ViPipe, 0xfe, 0x00); + + nVal = gc02m1_read_register(ViPipe, 0x3e); + nVal &= ~(0x1 << 7); + nVal &= ~(0x1 << 4); + gc02m1_write_register(ViPipe, 0x3e, nVal); + gc02m1_write_register(ViPipe, 0xfc, 0x01); + + nVal = gc02m1_read_register(ViPipe, 0xf9); + nVal |= (0x1 << 0); + gc02m1_write_register(ViPipe, 0xf9, nVal); + + printf("gc02m1 standby\n"); +} + +void gc02m1_restart(VI_PIPE ViPipe) +{ + int nVal; + + nVal = gc02m1_read_register(ViPipe, 0xf9); + nVal &= ~(0x1 << 0); + gc02m1_write_register(ViPipe, 0xf9, nVal); + + usleep(1); + gc02m1_write_register(ViPipe, 0xfc, 0x8e); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + nVal = gc02m1_read_register(ViPipe, 0x3e); + nVal |= (0x1 << 7); + nVal |= (0x1 << 4); + gc02m1_write_register(ViPipe, 0x3e, nVal); + + printf("gc02m1 restart\n"); +} + +void gc02m1_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc02m1[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc02m1_write_register(ViPipe, + g_pastGc02m1[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc02m1[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +int gc02m1_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc02m1_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc02m1_read_register(ViPipe, GC02M1_CHIP_ID_ADDR_H); + nVal2 = gc02m1_read_register(ViPipe, GC02M1_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC02M1_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc02m1_init(VI_PIPE ViPipe) +{ + gc02m1_i2c_init(ViPipe); + + gc02m1_linear_1200p30_init(ViPipe); + + g_pastGc02m1[ViPipe]->bInit = CVI_TRUE; +} + +void gc02m1_exit(VI_PIPE ViPipe) +{ + gc02m1_i2c_exit(ViPipe); +} + +static void gc02m1_linear_1200p30_init(VI_PIPE ViPipe) +{ + usleep(10 * 1000); + + /*system*/ + gc02m1_write_register(ViPipe, 0xfc, 0x01); + gc02m1_write_register(ViPipe, 0xf4, 0x41); + gc02m1_write_register(ViPipe, 0xf5, 0xc0); + gc02m1_write_register(ViPipe, 0xf6, 0x44); + gc02m1_write_register(ViPipe, 0xf8, 0x32); + gc02m1_write_register(ViPipe, 0xf9, 0x82); + gc02m1_write_register(ViPipe, 0xfa, 0x00); + gc02m1_write_register(ViPipe, 0xfd, 0x80); + gc02m1_write_register(ViPipe, 0xfc, 0x81); + gc02m1_write_register(ViPipe, 0xfe, 0x03); + gc02m1_write_register(ViPipe, 0x01, 0x0b); + gc02m1_write_register(ViPipe, 0xf7, 0x01); + gc02m1_write_register(ViPipe, 0xfc, 0x80); + gc02m1_write_register(ViPipe, 0xfc, 0x80); + gc02m1_write_register(ViPipe, 0xfc, 0x80); + gc02m1_write_register(ViPipe, 0xfc, 0x8e); + /*CISCTL*/ + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0x87, 0x09); + gc02m1_write_register(ViPipe, 0xee, 0x72); + gc02m1_write_register(ViPipe, 0xfe, 0x01); + gc02m1_write_register(ViPipe, 0x8c, 0x90); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0x90, 0x00); + gc02m1_write_register(ViPipe, 0x03, 0x04); + gc02m1_write_register(ViPipe, 0x04, 0x7d); + gc02m1_write_register(ViPipe, 0x41, 0x04); + gc02m1_write_register(ViPipe, 0x42, 0xf4); + gc02m1_write_register(ViPipe, 0x05, 0x04); + gc02m1_write_register(ViPipe, 0x06, 0x48); + gc02m1_write_register(ViPipe, 0x07, 0x00); + gc02m1_write_register(ViPipe, 0x08, 0x18); + gc02m1_write_register(ViPipe, 0x9d, 0x18); + gc02m1_write_register(ViPipe, 0x09, 0x00); + gc02m1_write_register(ViPipe, 0x0a, 0x02); + gc02m1_write_register(ViPipe, 0x0d, 0x04); + gc02m1_write_register(ViPipe, 0x0e, 0xbc); + gc02m1_write_register(ViPipe, 0x17, GC02M1_MIRROR); + gc02m1_write_register(ViPipe, 0x19, 0x04); + gc02m1_write_register(ViPipe, 0x24, 0x00); + gc02m1_write_register(ViPipe, 0x56, 0x20); + gc02m1_write_register(ViPipe, 0x5b, 0x00); + gc02m1_write_register(ViPipe, 0x5e, 0x01); + /*analog Register width*/ + gc02m1_write_register(ViPipe, 0x21, 0x3c); + gc02m1_write_register(ViPipe, 0x44, 0x20); + gc02m1_write_register(ViPipe, 0xcc, 0x01); + /*analog mode*/ + gc02m1_write_register(ViPipe, 0x1a, 0x04); + gc02m1_write_register(ViPipe, 0x1f, 0x11); + gc02m1_write_register(ViPipe, 0x27, 0x30); + gc02m1_write_register(ViPipe, 0x2b, 0x00); + gc02m1_write_register(ViPipe, 0x33, 0x00); + gc02m1_write_register(ViPipe, 0x53, 0x90); + gc02m1_write_register(ViPipe, 0xe6, 0x50); + /*analog voltage*/ + gc02m1_write_register(ViPipe, 0x39, 0x07); + gc02m1_write_register(ViPipe, 0x43, 0x04); + gc02m1_write_register(ViPipe, 0x46, 0x2a); + gc02m1_write_register(ViPipe, 0x7c, 0xa0); + gc02m1_write_register(ViPipe, 0xd0, 0xbe); + gc02m1_write_register(ViPipe, 0xd1, 0x60); + gc02m1_write_register(ViPipe, 0xd2, 0x40); + gc02m1_write_register(ViPipe, 0xd3, 0xf3); + gc02m1_write_register(ViPipe, 0xde, 0x1d); + /*analog current*/ + gc02m1_write_register(ViPipe, 0xcd, 0x05); + gc02m1_write_register(ViPipe, 0xce, 0x6f); + /*CISCTL RESET*/ + gc02m1_write_register(ViPipe, 0xfc, 0x88); + gc02m1_write_register(ViPipe, 0xfe, 0x10); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0xfc, 0x8e); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0xfc, 0x88); + gc02m1_write_register(ViPipe, 0xfe, 0x10); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0xfc, 0x8e); + gc02m1_write_register(ViPipe, 0xfe, 0x04); + gc02m1_write_register(ViPipe, 0xe0, 0x01); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + /*ISP*/ + gc02m1_write_register(ViPipe, 0xfe, 0x01); + gc02m1_write_register(ViPipe, 0x53, 0x44); + gc02m1_write_register(ViPipe, 0x87, 0x53); + gc02m1_write_register(ViPipe, 0x89, 0x03); + /*Gain*/ + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0xb0, 0x74); + gc02m1_write_register(ViPipe, 0xb1, 0x04); + gc02m1_write_register(ViPipe, 0xb2, 0x00); + gc02m1_write_register(ViPipe, 0xb6, 0x00); + gc02m1_write_register(ViPipe, 0xfe, 0x04); + gc02m1_write_register(ViPipe, 0xd8, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x40); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x60); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0xc0); + gc02m1_write_register(ViPipe, 0xc0, 0x2a); + gc02m1_write_register(ViPipe, 0xc0, 0x80); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x40); + gc02m1_write_register(ViPipe, 0xc0, 0xa0); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x90); + gc02m1_write_register(ViPipe, 0xc0, 0x19); + gc02m1_write_register(ViPipe, 0xc0, 0xc0); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0xD0); + gc02m1_write_register(ViPipe, 0xc0, 0x2F); + gc02m1_write_register(ViPipe, 0xc0, 0xe0); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x90); + gc02m1_write_register(ViPipe, 0xc0, 0x39); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x01); + gc02m1_write_register(ViPipe, 0xc0, 0x20); + gc02m1_write_register(ViPipe, 0xc0, 0x04); + gc02m1_write_register(ViPipe, 0xc0, 0x20); + gc02m1_write_register(ViPipe, 0xc0, 0x01); + gc02m1_write_register(ViPipe, 0xc0, 0xe0); + gc02m1_write_register(ViPipe, 0xc0, 0x0f); + gc02m1_write_register(ViPipe, 0xc0, 0x40); + gc02m1_write_register(ViPipe, 0xc0, 0x01); + gc02m1_write_register(ViPipe, 0xc0, 0xe0); + gc02m1_write_register(ViPipe, 0xc0, 0x1a); + gc02m1_write_register(ViPipe, 0xc0, 0x60); + gc02m1_write_register(ViPipe, 0xc0, 0x01); + gc02m1_write_register(ViPipe, 0xc0, 0x20); + gc02m1_write_register(ViPipe, 0xc0, 0x25); + gc02m1_write_register(ViPipe, 0xc0, 0x80); + gc02m1_write_register(ViPipe, 0xc0, 0x01); + gc02m1_write_register(ViPipe, 0xc0, 0xa0); + gc02m1_write_register(ViPipe, 0xc0, 0x2c); + gc02m1_write_register(ViPipe, 0xc0, 0xa0); + gc02m1_write_register(ViPipe, 0xc0, 0x01); + gc02m1_write_register(ViPipe, 0xc0, 0xe0); + gc02m1_write_register(ViPipe, 0xc0, 0x32); + gc02m1_write_register(ViPipe, 0xc0, 0xc0); + gc02m1_write_register(ViPipe, 0xc0, 0x01); + gc02m1_write_register(ViPipe, 0xc0, 0x20); + gc02m1_write_register(ViPipe, 0xc0, 0x38); + gc02m1_write_register(ViPipe, 0xc0, 0xe0); + gc02m1_write_register(ViPipe, 0xc0, 0x01); + gc02m1_write_register(ViPipe, 0xc0, 0x60); + gc02m1_write_register(ViPipe, 0xc0, 0x3c); + gc02m1_write_register(ViPipe, 0xc0, 0x00); + gc02m1_write_register(ViPipe, 0xc0, 0x02); + gc02m1_write_register(ViPipe, 0xc0, 0xa0); + gc02m1_write_register(ViPipe, 0xc0, 0x40); + gc02m1_write_register(ViPipe, 0xc0, 0x80); + gc02m1_write_register(ViPipe, 0xc0, 0x02); + gc02m1_write_register(ViPipe, 0xc0, 0x18); + gc02m1_write_register(ViPipe, 0xc0, 0x5c); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0x9f, 0x10); + /*BLK*/ + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0x26, 0x20); + gc02m1_write_register(ViPipe, 0xfe, 0x01); + gc02m1_write_register(ViPipe, 0x40, 0x22); + gc02m1_write_register(ViPipe, 0x46, 0x7f); + gc02m1_write_register(ViPipe, 0x49, 0x0f); + gc02m1_write_register(ViPipe, 0x4a, 0xf0); + gc02m1_write_register(ViPipe, 0xfe, 0x04); + gc02m1_write_register(ViPipe, 0x14, 0x80); + gc02m1_write_register(ViPipe, 0x15, 0x80); + gc02m1_write_register(ViPipe, 0x16, 0x80); + gc02m1_write_register(ViPipe, 0x17, 0x80); + /*ant _blooming*/ + gc02m1_write_register(ViPipe, 0xfe, 0x01); + gc02m1_write_register(ViPipe, 0x41, 0x20); + gc02m1_write_register(ViPipe, 0x4c, 0x00); + gc02m1_write_register(ViPipe, 0x4d, 0x0c); + gc02m1_write_register(ViPipe, 0x44, 0x08); + gc02m1_write_register(ViPipe, 0x48, 0x03); + /*Window 1600X1200*/ + gc02m1_write_register(ViPipe, 0xfe, 0x01); + gc02m1_write_register(ViPipe, 0x90, 0x01); + gc02m1_write_register(ViPipe, 0x91, 0x00); + gc02m1_write_register(ViPipe, 0x92, 0x06); + gc02m1_write_register(ViPipe, 0x93, 0x00); + gc02m1_write_register(ViPipe, 0x94, 0x06); + gc02m1_write_register(ViPipe, 0x95, 0x04); + gc02m1_write_register(ViPipe, 0x96, 0xb0); + gc02m1_write_register(ViPipe, 0x97, 0x06); + gc02m1_write_register(ViPipe, 0x98, 0x40); + /*mipi*/ + gc02m1_write_register(ViPipe, 0xfe, 0x03); + gc02m1_write_register(ViPipe, 0x01, 0x23); + gc02m1_write_register(ViPipe, 0x03, 0xce); + gc02m1_write_register(ViPipe, 0x04, 0x48); + gc02m1_write_register(ViPipe, 0x15, 0x00); + gc02m1_write_register(ViPipe, 0x21, 0x10); + gc02m1_write_register(ViPipe, 0x22, 0x05); + gc02m1_write_register(ViPipe, 0x23, 0x20); + gc02m1_write_register(ViPipe, 0x25, 0x20); + gc02m1_write_register(ViPipe, 0x26, 0x08); + gc02m1_write_register(ViPipe, 0x29, 0x06); + gc02m1_write_register(ViPipe, 0x2a, 0x0a); + gc02m1_write_register(ViPipe, 0x2b, 0x08); + /*out*/ + gc02m1_write_register(ViPipe, 0xfe, 0x01); + gc02m1_write_register(ViPipe, 0x8c, 0x10); + gc02m1_write_register(ViPipe, 0xfe, 0x00); + gc02m1_write_register(ViPipe, 0x3e, 0x90); + + gc02m1_default_reg_init(ViPipe); + usleep(10 * 1000); + + printf("ViPipe:%d,===GC02M1 1200P 30fps 10bit LINEAR Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc1054/Makefile b/middleware/v2/component/isp/sensor/cv181x/gcore_gc1054/Makefile new file mode 100644 index 000000000..eb95cf432 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc1054/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc1054.a +TARGET_SO = $(MW_LIB)/libsns_gc1054.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc1054/gc1054_cmos.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc1054/gc1054_cmos.c new file mode 100644 index 000000000..8acc1b486 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc1054/gc1054_cmos.c @@ -0,0 +1,900 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "gc1054_cmos_ex.h" +#include "gc1054_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define GC1054_ID 1054 + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc1054[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC1054_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc1054[dev]) +#define GC1054_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc1054[dev] = pstCtx) +#define GC1054_SENSOR_RESET_CTX(dev) (g_pastGc1054[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc1054_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +GC1054_STATE_S g_astGc1054_State[VI_MAX_PIPE_NUM] = { {0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc1054_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16Gc1054_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Gc1054_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Gc1054 Lines Range*****/ +#define GC1054_FULL_LINES_MAX (8931) // 0x1FFF(Max VB) + 724 + 16 + +/*****Gc1054 Register Address*****/ +#define GC1054_EXP_PAGE_ADDR 0xfe +#define GC1054_EXP_H_ADDR 0x03 +#define GC1054_EXP_L_ADDR 0x04 +#define GC1054_AGAIN_PAGE_ADDR 0xfe +#define GC1054_AGAIN_ADDR 0xb6 +#define GC1054_VB_PAGE_ADDR 0xfe +#define GC1054_VB_H_ADDR 0x07 +#define GC1054_VB_L_ADDR 0x08 +#define GC1054_FLIP_MIRROR_PAGE_ADDR 0xfe +#define GC1054_FLIP_MIRROR_ADDR 0x17 + +#define GC1054_RES_IS_720P(w, h) ((w) <= 1280 && (h) <= 720) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const GC1054_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc1054_mode; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC1054_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain.u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain.u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain.u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain.u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : + pstMode->stExp.u16Def; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp.u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp.u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = 0, u32VB = 0; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_stGc1054_mode.u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_stGc1054_mode.f32MaxFps; + f32MinFps = g_stGc1054_mode.f32MinFps; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > GC1054_FULL_LINES_MAX) ? GC1054_FULL_LINES_MAX : u32VMAX; + + u32VB = u32VMAX - 724 - 16; + pstSnsRegsInfo->astI2cData[LINEAR_VB_H].u32Data = ((u32VB & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VB_L].u32Data = (u32VB & 0xFF); + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_U32 gain_table[11] = { + 16*64, + 16*91, + 16*127, + 16*182, + 16*258, + 16*369, + 16*516, + 16*738, + 16*1032, + 16*1491, + 16*2084, +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[11 - 1]) { //max 32.5625x + *pu32AgainDb = 11 - 1; + *pu32AgainLin = gain_table[11 - 1]; + return CVI_SUCCESS; + } + + for (i = 1; i < 11; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainDb = i - 1; + break; + } + } + *pu32AgainLin = gain_table[i - 1]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN].u32Data = *pu32Again; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + UNUSED(ViPipe); + UNUSED(u16ManRatioEnable); + UNUSED(au32Ratio); + UNUSED(au32IntTimeMax); + UNUSED(au32IntTimeMin); + UNUSED(pu32LFMaxIntTime); + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + UNUSED(ViPipe); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + UNUSED(ViPipe); + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + CMOS_CHECK_POINTER(pstBlc); + UNUSED(ViPipe); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC1054_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc1054_mode; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->stImg, sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = GC1054_MODE_1280X720P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc1054_mode.u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunGc1054_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = gc1054_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc1054_addr_byte; + pstI2c_data[i].u32DataByteNum = gc1054_data_byte; + } + + pstI2c_data[LINEAR_EXP_PAGE].u32RegAddr = GC1054_EXP_PAGE_ADDR; + pstI2c_data[LINEAR_EXP_PAGE].u32Data = 0; + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC1054_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC1054_EXP_L_ADDR; + pstI2c_data[LINEAR_GAIN_PAGE].u32RegAddr = GC1054_AGAIN_PAGE_ADDR; + pstI2c_data[LINEAR_GAIN_PAGE].u32Data = 1; + pstI2c_data[LINEAR_AGAIN].u32RegAddr = GC1054_AGAIN_ADDR; + pstI2c_data[LINEAR_VB_PAGE].u32RegAddr = GC1054_VB_PAGE_ADDR; + pstI2c_data[LINEAR_VB_PAGE].u32Data = 0; + pstI2c_data[LINEAR_VB_H].u32RegAddr = GC1054_VB_H_ADDR; + pstI2c_data[LINEAR_VB_L].u32RegAddr = GC1054_VB_L_ADDR; + pstI2c_data[LINEAR_FLIP_MIRROR_PAGE].u32RegAddr = GC1054_FLIP_MIRROR_PAGE_ADDR; + pstI2c_data[LINEAR_FLIP_MIRROR_PAGE].u32Data = 0; + pstI2c_data[LINEAR_FLIP_MIRROR].u32RegAddr = GC1054_FLIP_MIRROR_ADDR; + pstI2c_data[LINEAR_FLIP_MIRROR].u32Data = 0xc0; + + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + + CVI_U32 gainsUpdate = 0, expUpdate = 0, vbUpdate = 0; + + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + + if (i == LINEAR_AGAIN) + gainsUpdate = 1; + + if ((i >= LINEAR_EXP_H) && (i <= LINEAR_EXP_L)) + expUpdate = 1; + + if ((i >= LINEAR_VB_H) && (i <= LINEAR_VB_L)) + vbUpdate = 1; + + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (gainsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_GAIN_PAGE].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN].bUpdate = CVI_TRUE; + } + if (expUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_PAGE].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_L].bUpdate = CVI_TRUE; + } + if (vbUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_VB_PAGE].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_VB_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_VB_L].bUpdate = CVI_TRUE; + } + if (pstI2c_data[LINEAR_FLIP_MIRROR].bUpdate == CVI_TRUE) { + pstI2c_data[LINEAR_FLIP_MIRROR_PAGE].bUpdate = CVI_TRUE; + } + + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + pstCfg0->ispCfg.u8DelayFrmNum = 1; + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = CVI_FALSE; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC1054_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC1054_MODE_1280X720P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 value = 0xC0; + CVI_U8 start_x = 3; + CVI_U8 start_y = 2; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_ISP_INFO_S *pstIspCfg0 = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + pstIspCfg0 = &pstSnsState->astSyncInfo[0].ispCfg; + + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc1054_MirrorFip[ViPipe] != eSnsMirrorFlip) { + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + value = 0xC0; + start_x = 3; + start_y = 2; + break; + case ISP_SNS_MIRROR: + value = 0xC1; + start_x = 4; + start_y = 2; + break; + case ISP_SNS_FLIP: + value = 0xC2; + start_x = 3; + start_y = 3; + break; + case ISP_SNS_MIRROR_FLIP: + value = 0xC3; + start_x = 4; + start_y = 3; + break; + default: + return; + } + + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u8DropFrmNum = 1; + pstIspCfg0->img_size[0].stWndRect.s32X = start_x; + pstIspCfg0->img_size[0].stWndRect.s32Y = start_y; + + g_aeGc1054_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC1054_MODE_1280X720P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc1054_mode.u32VtsDef; + pstSnsState->au32FL[0] = g_stGc1054_mode.u32VtsDef; + pstSnsState->au32FL[1] = g_stGc1054_mode.u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc1054_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_stGc1054_mode.stImg.stSnsSize.u32Width; + pstRxAttr->img_size.height = g_stGc1054_mode.stImg.stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc1054_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc1054_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc1054_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 gc1054_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc1054_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC1054_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC1054_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC1054_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC1054_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC1054_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC1054_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC1054_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Gc1054_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Gc1054_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsGc1054_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc1054_standby, + .pfnRestart = gc1054_restart, + .pfnWriteReg = gc1054_write_register, + .pfnReadReg = gc1054_read_register, + .pfnSetBusInfo = gc1054_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc1054/gc1054_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc1054/gc1054_cmos_ex.h new file mode 100644 index 000000000..da266e899 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc1054/gc1054_cmos_ex.h @@ -0,0 +1,86 @@ +#ifndef __GC1054_CMOS_EX_H_ +#define __GC1054_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum gc1054_linear_regs_e { + LINEAR_EXP_PAGE = 0, //fe + LINEAR_EXP_H, //03 + LINEAR_EXP_L, //04 + LINEAR_GAIN_PAGE, //fe + LINEAR_AGAIN, //b6 + LINEAR_VB_PAGE, //fe + LINEAR_VB_H, //07 + LINEAR_VB_L, //08 + LINEAR_FLIP_MIRROR_PAGE, //fe + LINEAR_FLIP_MIRROR, //17 + LINEAR_REGS_NUM +}; + + +typedef enum _GC1054_MODE_E { + GC1054_MODE_1280X720P30 = 0, + GC1054_MODE_NUM +} GC1054_SLAVE_MODE_E; + +typedef struct _GC1054_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC1054_STATE_S; + +typedef struct _GC1054_MODE_S { + ISP_WDR_SIZE_S stImg; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp; + SNS_ATTR_LARGE_S stAgain; + SNS_ATTR_LARGE_S stDgain; + char name[64]; +} GC1054_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc1054[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc1054_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc1054_MirrorFip[VI_MAX_PIPE_NUM]; +extern const CVI_U8 gc1054_i2c_addr; +extern const CVI_U32 gc1054_addr_byte; +extern const CVI_U32 gc1054_data_byte; +extern void gc1054_init(VI_PIPE ViPipe); +extern void gc1054_exit(VI_PIPE ViPipe); +extern void gc1054_standby(VI_PIPE ViPipe); +extern void gc1054_restart(VI_PIPE ViPipe); +extern int gc1054_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc1054_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC1054_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc1054/gc1054_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc1054/gc1054_cmos_param.h new file mode 100644 index 000000000..1d49ef7a5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc1054/gc1054_cmos_param.h @@ -0,0 +1,223 @@ +#ifndef __GC1054_CMOS_PARAM_H_ +#define __GC1054_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc1054_cmos_ex.h" + +static const GC1054_MODE_S g_stGc1054_mode = { + .name = "1280X720P30", + .stImg = { + .stSnsSize = { + .u32Width = 1288, + .u32Height = 724, + }, + .stWndRect = { + .s32X = 3, + .s32Y = 2, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1288, + .u32Height = 724, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.63, /* 782 * 30 / 8931*/ + .u32HtsDef = 1726, + .u32VtsDef = 782, /* WIN_H + VB + 16 */ + .stExp = { + .u16Min = 1, + .u16Max = 782 - 1, /* VtsDef - 1*/ + .u16Def = 100, + .u16Step = 1, + }, + .stAgain = { + .u32Min = 1024, + .u32Max = 16 * 2084, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain = { + .u32Min = 1024, + .u32Max = 1024, + .u32Def = 1024, + .u32Step = 1, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.05999477580189704895, 0.13019448518753051758}, //B: slope, intercept + {0.06732148677110671997, -1.36387133598327636719}, //Gb: slope, intercept + {0.06651904433965682983, -1.10093510150909423828}, //Gr: slope, intercept + {0.06406146287918090820, 0.33316791057586669922}, //R: slope, intercept + }, + { //iso 200 + {0.06256803125143051147, 4.54908418655395507813}, //B: slope, intercept + {0.06911934912204742432, 2.79023528099060058594}, //Gb: slope, intercept + {0.06846688687801361084, 2.88726186752319335938}, //Gr: slope, intercept + {0.06652788817882537842, 4.40276956558227539063}, //R: slope, intercept + }, + { //iso 400 + {0.06841833144426345825, 11.72280883789062500000}, //B: slope, intercept + {0.07257881015539169312, 10.86985683441162109375}, //Gb: slope, intercept + {0.07174283266067504883, 11.20646286010742187500}, //Gr: slope, intercept + {0.07294593751430511475, 11.17350578308105468750}, //R: slope, intercept + }, + { //iso 800 + {0.07805790752172470093, 20.62956619262695312500}, //B: slope, intercept + {0.07694032043218612671, 22.20356750488281250000}, //Gb: slope, intercept + {0.07647507637739181519, 22.50957298278808593750}, //Gr: slope, intercept + {0.08402533829212188721, 19.11953735351562500000}, //R: slope, intercept + }, + { //iso 1600 + {0.09468275308609008789, 34.07563018798828125000}, //B: slope, intercept + {0.08710632473230361938, 39.15500259399414062500}, //Gb: slope, intercept + {0.08662072569131851196, 39.37175750732421875000}, //Gr: slope, intercept + {0.10222808271646499634, 31.34789276123046875000}, //R: slope, intercept + }, + { //iso 3200 + {0.12651191651821136475, 49.56183242797851562500}, //B: slope, intercept + {0.10816962271928787231, 59.42719650268554687500}, //Gb: slope, intercept + {0.10751257836818695068, 59.90552902221679687500}, //Gr: slope, intercept + {0.13802853226661682129, 45.09576034545898437500}, //R: slope, intercept + }, + { //iso 6400 + {0.17422541975975036621, 70.04063415527343750000}, //B: slope, intercept + {0.14234761893749237061, 85.51583862304687500000}, //Gb: slope, intercept + {0.14159946143627166748, 86.23278045654296875000}, //Gr: slope, intercept + {0.19450971484184265137, 62.65447235107421875000}, //R: slope, intercept + }, + { //iso 12800 + {0.24947367608547210693, 108.30633544921875000000}, //B: slope, intercept + {0.19751225411891937256, 130.88159179687500000000}, //Gb: slope, intercept + {0.19614629447460174561, 132.49082946777343750000}, //Gr: slope, intercept + {0.28106108307838439941, 97.15969085693359375000}, //R: slope, intercept + }, + { //iso 25600 + {0.35420843958854675293, 137.06745910644531250000}, //B: slope, intercept + {0.27778801321983337402, 168.72366333007812500000}, //Gb: slope, intercept + {0.27540388703346252441, 170.54939270019531250000}, //Gr: slope, intercept + {0.39949953556060791016, 123.29409790039062500000}, //R: slope, intercept + }, + { //iso 51200 + {0.45704349875450134277, 179.20147705078125000000}, //B: slope, intercept + {0.32142028212547302246, 246.71363830566406250000}, //Gb: slope, intercept + {0.31958609819412231445, 246.82630920410156250000}, //Gr: slope, intercept + {0.51058447360992431641, 161.86299133300781250000}, //R: slope, intercept + }, + { //iso 102400 + {0.61760461330413818359, 222.90534973144531250000}, //B: slope, intercept + {0.42568457126617431641, 319.29257202148437500000}, //Gb: slope, intercept + {0.41750904917716979980, 324.93432617187500000000}, //Gr: slope, intercept + {0.67956107854843139648, 203.78948974609375000000}, //R: slope, intercept + }, + { //iso 204800 + {0.63289469480514526367, 216.99952697753906250000}, //B: slope, intercept + {0.44890350103378295898, 306.80810546875000000000}, //Gb: slope, intercept + {0.44229975342750549316, 310.13763427734375000000}, //Gr: slope, intercept + {0.69596910476684570313, 196.70443725585937500000}, //R: slope, intercept + }, + { //iso 409600 + {0.71106964349746704102, 187.98352050781250000000}, //B: slope, intercept + {0.55859673023223876953, 246.22378540039062500000}, //Gb: slope, intercept + {0.55284017324447631836, 249.86463928222656250000}, //Gr: slope, intercept + {0.77318203449249267578, 168.85035705566406250000}, //R: slope, intercept + }, + { //iso 819200 + {0.70888006687164306641, 188.44216918945312500000}, //B: slope, intercept + {0.56110274791717529297, 245.46603393554687500000}, //Gb: slope, intercept + {0.55100852251052856445, 250.33049011230468750000}, //Gr: slope, intercept + {0.76897650957107543945, 169.31251525878906250000}, //R: slope, intercept + }, + { //iso 1638400 + {0.70520979166030883789, 188.93899536132812500000}, //B: slope, intercept + {0.56178557872772216797, 245.21235656738281250000}, //Gb: slope, intercept + {0.55338454246520996094, 249.57423400878906250000}, //Gr: slope, intercept + {0.77306479215621948242, 168.86497497558593750000}, //R: slope, intercept + }, + { //iso 3276800 + {0.71255809068679809570, 187.86839294433593750000}, //B: slope, intercept + {0.56056070327758789063, 245.57748413085937500000}, //Gb: slope, intercept + {0.55358195304870605469, 249.62020874023437500000}, //Gr: slope, intercept + {0.77431541681289672852, 168.74313354492187500000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {256, 256, 257, 257, 259, 259, 260, 267, 278, 298, 366, 383, 366, 373, 372, 372 }, + {256, 256, 257, 257, 258, 259, 261, 266, 274, 297, 379, 377, 372, 365, 373, 374 }, + {256, 256, 257, 257, 258, 259, 261, 266, 275, 296, 376, 388, 366, 374, 376, 372 }, + {256, 256, 257, 257, 258, 259, 260, 264, 274, 294, 362, 363, 365, 361, 353, 367 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1092, 1093, 1093, 1093, 1093, 1093, 1095, + 1099, 1104, 1125, 1130, 1125, 1127, 1126, 1126}, + {1092, 1092, 1093, 1093, 1093, 1093, 1094, 1095, + 1097, 1104, 1128, 1128, 1126, 1124, 1127, 1127}, + {1092, 1092, 1093, 1093, 1093, 1093, 1094, 1095, + 1098, 1104, 1128, 1131, 1125, 1127, 1128, 1126}, + {1092, 1092, 1093, 1093, 1093, 1093, 1093, 1095, + 1097, 1103, 1123, 1124, 1124, 1123, 1121, 1125}, +#endif + }, + }, +}; + +struct combo_dev_attr_s gc1054_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {3, 4, -1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 8, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 1, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC1054_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc1054/gc1054_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc1054/gc1054_sensor_ctl.c new file mode 100644 index 000000000..82822b860 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc1054/gc1054_sensor_ctl.c @@ -0,0 +1,313 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc1054_cmos_ex.h" + +static void gc1054_linear_720p30_init(VI_PIPE ViPipe); + +const CVI_U8 gc1054_i2c_addr = 0x21;//0x42 +const CVI_U32 gc1054_addr_byte = 1; +const CVI_U32 gc1054_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc1054_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc1054_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc1054_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc1054_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc1054_read_register(VI_PIPE ViPipe, int addr) +{ + /* TODO:*/ + UNUSED(ViPipe); + UNUSED(addr); + return CVI_SUCCESS; +} + + +int gc1054_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc1054_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (gc1054_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc1054_addr_byte + gc1054_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + //ret = read(g_fd[ViPipe], buf, gc1054_addr_byte + gc1054_data_byte); + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void gc1054_standby(VI_PIPE ViPipe) +{ + UNUSED(ViPipe); + printf("gc1054_standby\n"); +} + +void gc1054_restart(VI_PIPE ViPipe) +{ + UNUSED(ViPipe); + printf("gc1054_restart\n"); +} + +void gc1054_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc1054[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc1054_write_register(ViPipe, + g_pastGc1054[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc1054[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void gc1054_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode = g_pastGc1054[ViPipe]->enWDRMode; + + gc1054_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n"); + } else { + gc1054_linear_720p30_init(ViPipe); + } + g_pastGc1054[ViPipe]->bInit = CVI_TRUE; +} + +void gc1054_exit(VI_PIPE ViPipe) +{ + gc1054_i2c_exit(ViPipe); +} + +static void gc1054_linear_720p30_init(VI_PIPE ViPipe) +{ + /****system****/ + gc1054_write_register(ViPipe, 0xf2, 0x00); + gc1054_write_register(ViPipe, 0xf6, 0x00); + gc1054_write_register(ViPipe, 0xfc, 0x04); + gc1054_write_register(ViPipe, 0xf7, 0x01); + gc1054_write_register(ViPipe, 0xf8, 0x0b); + gc1054_write_register(ViPipe, 0xf9, 0x06); + gc1054_write_register(ViPipe, 0xfa, 0x80); + gc1054_write_register(ViPipe, 0xfc, 0x0e); + /****CISCTL & ANALOG****/ + gc1054_write_register(ViPipe, 0xfe, 0x00); + gc1054_write_register(ViPipe, 0x03, 0x02); + gc1054_write_register(ViPipe, 0x04, 0xa6); + gc1054_write_register(ViPipe, 0x05, 0x02); //HB + gc1054_write_register(ViPipe, 0x06, 0x07); + gc1054_write_register(ViPipe, 0x07, 0x00); //VB + gc1054_write_register(ViPipe, 0x08, 0x2a); + gc1054_write_register(ViPipe, 0x09, 0x00); + gc1054_write_register(ViPipe, 0x0a, 0x04); //row start + gc1054_write_register(ViPipe, 0x0b, 0x00); + gc1054_write_register(ViPipe, 0x0c, 0x00); //col start + gc1054_write_register(ViPipe, 0x0d, 0x02); + gc1054_write_register(ViPipe, 0x0e, 0xd8); //height 724 + gc1054_write_register(ViPipe, 0x0f, 0x05); + gc1054_write_register(ViPipe, 0x10, 0x10); //width 1288 + gc1054_write_register(ViPipe, 0x17, 0xc0); + gc1054_write_register(ViPipe, 0x18, 0x02); + gc1054_write_register(ViPipe, 0x19, 0x08); + gc1054_write_register(ViPipe, 0x1a, 0x18); + gc1054_write_register(ViPipe, 0x1d, 0x12); + gc1054_write_register(ViPipe, 0x1e, 0x50); + gc1054_write_register(ViPipe, 0x1f, 0x80); + gc1054_write_register(ViPipe, 0x21, 0x3a); + gc1054_write_register(ViPipe, 0x23, 0xe8); + gc1054_write_register(ViPipe, 0x25, 0x10); + gc1054_write_register(ViPipe, 0x28, 0x20); + gc1054_write_register(ViPipe, 0x34, 0x0a); //data low + gc1054_write_register(ViPipe, 0x3c, 0x10); + gc1054_write_register(ViPipe, 0x3d, 0x0e); + gc1054_write_register(ViPipe, 0xcc, 0x8f); + gc1054_write_register(ViPipe, 0xcd, 0x9a); + gc1054_write_register(ViPipe, 0xcf, 0x70); + gc1054_write_register(ViPipe, 0xd0, 0x9a); + gc1054_write_register(ViPipe, 0xd1, 0xc5); + gc1054_write_register(ViPipe, 0xd2, 0xed); //data high + gc1054_write_register(ViPipe, 0xd8, 0x3c); //dacin offset + gc1054_write_register(ViPipe, 0xd9, 0x7a); + gc1054_write_register(ViPipe, 0xda, 0x12); + gc1054_write_register(ViPipe, 0xdb, 0x50); + gc1054_write_register(ViPipe, 0xde, 0x0c); + gc1054_write_register(ViPipe, 0xe3, 0x60); + gc1054_write_register(ViPipe, 0xe4, 0x78); + gc1054_write_register(ViPipe, 0xfe, 0x01); + gc1054_write_register(ViPipe, 0xe3, 0x01); + gc1054_write_register(ViPipe, 0xe6, 0x16); //ramps offset + gc1054_write_register(ViPipe, 0xfe, 0x01); + gc1054_write_register(ViPipe, 0x80, 0x50); + gc1054_write_register(ViPipe, 0x88, 0x73); + gc1054_write_register(ViPipe, 0x89, 0x03); + gc1054_write_register(ViPipe, 0x90, 0x01); + gc1054_write_register(ViPipe, 0x92, 0x00); //crop win 2<=y<=4 + gc1054_write_register(ViPipe, 0x94, 0x00); //crop win 2<=x<=5 + gc1054_write_register(ViPipe, 0x95, 0x02); //crop win height + gc1054_write_register(ViPipe, 0x96, 0xd4); + gc1054_write_register(ViPipe, 0x97, 0x05); //crop win width + gc1054_write_register(ViPipe, 0x98, 0x08); + /*blk*/ + gc1054_write_register(ViPipe, 0xfe, 0x01); + gc1054_write_register(ViPipe, 0x40, 0x22); + gc1054_write_register(ViPipe, 0x43, 0x03); + gc1054_write_register(ViPipe, 0x4e, 0x3c); + gc1054_write_register(ViPipe, 0x4f, 0x00); + gc1054_write_register(ViPipe, 0x60, 0x00); + gc1054_write_register(ViPipe, 0x61, 0x80); + /*gain*/ + gc1054_write_register(ViPipe, 0xfe, 0x01); + gc1054_write_register(ViPipe, 0xb0, 0x48); + gc1054_write_register(ViPipe, 0xb1, 0x01); + gc1054_write_register(ViPipe, 0xb2, 0x00); + gc1054_write_register(ViPipe, 0xb6, 0x00); + gc1054_write_register(ViPipe, 0xfe, 0x02); + gc1054_write_register(ViPipe, 0x01, 0x00); + gc1054_write_register(ViPipe, 0x02, 0x01); + gc1054_write_register(ViPipe, 0x03, 0x02); + gc1054_write_register(ViPipe, 0x04, 0x03); + gc1054_write_register(ViPipe, 0x05, 0x04); + gc1054_write_register(ViPipe, 0x06, 0x05); + gc1054_write_register(ViPipe, 0x07, 0x06); + gc1054_write_register(ViPipe, 0x08, 0x0e); + gc1054_write_register(ViPipe, 0x09, 0x16); + gc1054_write_register(ViPipe, 0x0a, 0x1e); + gc1054_write_register(ViPipe, 0x0b, 0x36); + gc1054_write_register(ViPipe, 0x0c, 0x3e); + gc1054_write_register(ViPipe, 0x0d, 0x56); + gc1054_write_register(ViPipe, 0xfe, 0x02); + gc1054_write_register(ViPipe, 0xb0, 0x00); //col_gain[11:8] + gc1054_write_register(ViPipe, 0xb1, 0x00); + gc1054_write_register(ViPipe, 0xb2, 0x00); + gc1054_write_register(ViPipe, 0xb3, 0x11); + gc1054_write_register(ViPipe, 0xb4, 0x22); + gc1054_write_register(ViPipe, 0xb5, 0x54); + gc1054_write_register(ViPipe, 0xb6, 0xb8); + gc1054_write_register(ViPipe, 0xb7, 0x60); + gc1054_write_register(ViPipe, 0xb9, 0x00); //col_gain[12] + gc1054_write_register(ViPipe, 0xba, 0xc0); + gc1054_write_register(ViPipe, 0xc0, 0x20); //col_gain[7:0] + gc1054_write_register(ViPipe, 0xc1, 0x2d); + gc1054_write_register(ViPipe, 0xc2, 0x40); + gc1054_write_register(ViPipe, 0xc3, 0x5b); + gc1054_write_register(ViPipe, 0xc4, 0x80); + gc1054_write_register(ViPipe, 0xc5, 0xb5); + gc1054_write_register(ViPipe, 0xc6, 0x00); + gc1054_write_register(ViPipe, 0xc7, 0x6a); + gc1054_write_register(ViPipe, 0xc8, 0x00); + gc1054_write_register(ViPipe, 0xc9, 0xd4); + gc1054_write_register(ViPipe, 0xca, 0x00); + gc1054_write_register(ViPipe, 0xcb, 0xa8); + gc1054_write_register(ViPipe, 0xcc, 0x00); + gc1054_write_register(ViPipe, 0xcd, 0x50); + gc1054_write_register(ViPipe, 0xce, 0x00); + gc1054_write_register(ViPipe, 0xcf, 0xa1); + /****DARKSUN****/ + gc1054_write_register(ViPipe, 0xfe, 0x02); + gc1054_write_register(ViPipe, 0x54, 0xf7); + gc1054_write_register(ViPipe, 0x55, 0xf0); + gc1054_write_register(ViPipe, 0x56, 0x00); + gc1054_write_register(ViPipe, 0x57, 0x00); + gc1054_write_register(ViPipe, 0x58, 0x00); + gc1054_write_register(ViPipe, 0x5a, 0x04); + /****DD****/ + gc1054_write_register(ViPipe, 0xfe, 0x04); + gc1054_write_register(ViPipe, 0x40, 0x40); //blc 0x40-10bit + gc1054_write_register(ViPipe, 0x81, 0x8a); + /****DVP & MIPI****/ + gc1054_write_register(ViPipe, 0xfe, 0x03); + gc1054_write_register(ViPipe, 0x01, 0x03); + gc1054_write_register(ViPipe, 0x02, 0x11); + gc1054_write_register(ViPipe, 0x03, 0x90); + gc1054_write_register(ViPipe, 0x10, 0x90); + gc1054_write_register(ViPipe, 0x11, 0x2b); + gc1054_write_register(ViPipe, 0x12, 0x4a); //lwc 1280*5/4 + gc1054_write_register(ViPipe, 0x13, 0x06); + gc1054_write_register(ViPipe, 0x15, 0x06); + gc1054_write_register(ViPipe, 0x21, 0x02); + gc1054_write_register(ViPipe, 0x22, 0x02); + gc1054_write_register(ViPipe, 0x23, 0x08); + gc1054_write_register(ViPipe, 0x24, 0x02); + gc1054_write_register(ViPipe, 0x25, 0x10); + gc1054_write_register(ViPipe, 0x26, 0x04); + gc1054_write_register(ViPipe, 0x29, 0x02); + gc1054_write_register(ViPipe, 0x2a, 0x02); + gc1054_write_register(ViPipe, 0x2b, 0x08); + gc1054_write_register(ViPipe, 0x42, 0x08); + gc1054_write_register(ViPipe, 0x43, 0x05); + gc1054_write_register(ViPipe, 0xfe, 0x00); + + gc1054_default_reg_init(ViPipe); + delay_ms(40); + printf("ViPipe:%d,===GC1054 720P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053/Makefile b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053/Makefile new file mode 100644 index 000000000..8566f11ff --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc2053.a +TARGET_SO = $(MW_LIB)/libsns_gc2053.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053/gc2053_cmos.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053/gc2053_cmos.c new file mode 100644 index 000000000..2b33e50d0 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053/gc2053_cmos.c @@ -0,0 +1,883 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "gc2053_cmos_ex.h" +#include "gc2053_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define GC2053_ID 2053 +#define GC2053_I2C_ADDR_1 0x3f +#define GC2053_I2C_ADDR_2 0x37 +#define GC2053_I2C_ADDR_IS_VALID(addr) ((addr) == GC2053_I2C_ADDR_1 || (addr) == GC2053_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc2053[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC2053_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc2053[dev]) +#define GC2053_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc2053[dev] = pstCtx) +#define GC2053_SENSOR_RESET_CTX(dev) (g_pastGc2053[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc2053_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +GC2053_STATE_S g_astGc2053_State[VI_MAX_PIPE_NUM] = { {0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2053_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16Gc2053_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Gc2053_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Gc2053 Lines Range*****/ +#define GC2053_FULL_LINES_MAX (0x3fff) + +/*****Gc2053 Register Address*****/ +#define GC2053_EXP_H_ADDR 0x03 +#define GC2053_EXP_L_ADDR 0x04 +#define GC2053_AGAIN_H_ADDR 0xb4 +#define GC2053_AGAIN_L_ADDR 0xb3 +#define GC2053_COL_AGAIN_H_ADDR 0xb8 +#define GC2053_COL_AGAIN_L_ADDR 0xb9 +#define GC2053_DGAIN_H_ADDR 0xb1 +#define GC2053_DGAIN_L_ADDR 0xb2 +#define GC2053_VTS_H_ADDR 0x41 //(frame length) +#define GC2053_VTS_L_ADDR 0x42 + +#define GC2053_RES_IS_1080P(w, h) ((w) == 1920 && (h) == 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const GC2053_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc2053_mode; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC2053_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 3985*16; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 10240; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : + pstMode->stExp.u16Def; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp.u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp.u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = 0; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_stGc2053_mode.u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_stGc2053_mode.f32MaxFps; + f32MinFps = g_stGc2053_mode.f32MinFps; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > GC2053_FULL_LINES_MAX) ? GC2053_FULL_LINES_MAX : u32VMAX; + + pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF); + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_U32 regValTable[25][4] = { + {0x00, 0x00, 0x01, 0x00}, + {0x00, 0x10, 0x01, 0x0c}, + {0x00, 0x20, 0x01, 0x1b}, + {0x00, 0x30, 0x01, 0x2c}, + {0x00, 0x40, 0x01, 0x3f}, + {0x00, 0x50, 0x02, 0x16}, + {0x00, 0x60, 0x02, 0x35}, + {0x00, 0x70, 0x03, 0x16}, + {0x00, 0x80, 0x04, 0x02}, + {0x00, 0x90, 0x04, 0x31}, + {0x00, 0xa0, 0x05, 0x32}, + {0x00, 0xb0, 0x06, 0x35}, + {0x00, 0xc0, 0x08, 0x04}, + {0x00, 0x5a, 0x09, 0x19}, + {0x00, 0x83, 0x0b, 0x0f}, + {0x00, 0x93, 0x0d, 0x12}, + {0x00, 0x84, 0x10, 0x00}, + {0x00, 0x94, 0x12, 0x3a}, + {0x01, 0x2c, 0x1a, 0x02}, + {0x01, 0x3c, 0x1b, 0x20}, + {0x00, 0x8c, 0x20, 0x0f}, + {0x00, 0x9c, 0x26, 0x07}, + {0x02, 0x64, 0x36, 0x21}, + {0x02, 0x74, 0x37, 0x3a}, + {0x00, 0xc6, 0x3d, 0x02}, +}; + +static CVI_U32 gain_table[25] = { + 64*16, 76*16, 90*16, 108*16, 127*16, 148*16, 180*16, 216*16, 255*16, 300*16, + 361*16, 422*16, 504*16, 593*16, 722*16, 850*16, 1008*16, 1182*16, 1408*16, 1689*16, + 2021*16, 2391*16, 2850*16, 3369*16, 3985*16,/* 4805*16, 5768*16, 6806*16, 7723*16,*/ +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i, total; + CVI_U32 pregain; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + total = sizeof(gain_table) / sizeof(CVI_U32); + + if (*pu32AgainLin >= gain_table[total - 1]) { + *pu32AgainLin = *pu32AgainDb = gain_table[total - 1]; + return CVI_SUCCESS; + } + + for (i = 1; i < total; i++) { + if (*pu32AgainLin < gain_table[i]) + break; + } + i--; + // find the pregain + pregain = *pu32AgainLin * 64 / gain_table[i]; + // set the Db as the AE algo gain, we need this to do gain update + *pu32AgainDb = *pu32AgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32AgainLin = pregain * gain_table[i] / 64; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 pregain; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + // find the pregain + pregain = *pu32DgainLin * 64 / 1024; + // set the Db as the AE algo gain, we need this to do gain update + *pu32DgainDb = *pu32DgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32DgainLin = pregain * 16; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + int i, total; + + total = sizeof(gain_table) / sizeof(CVI_U32); + + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* only surpport linear mode */ + u32Again = pu32Again[0]; + /* To kepp the linearity. we assume AE algo adjusts the dgain only when the again reachs the maximum value */ + if (u32Again < (3985*16)) { + for (i = 1; i < total; i++) { + if (*pu32Again < gain_table[i]) + break; + } + i--; + // find the pregain + u32Dgain = u32Again * 64 / gain_table[i]; + u32Again = i; + } else { + u32Again = total - 1; + // find the pregain + u32Dgain = pu32Dgain[0] * 64 / 1024; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][0]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][1]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][2]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][3]; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 6); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + UNUSED(ViPipe); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + UNUSED(ViPipe); + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + CMOS_CHECK_POINTER(pstBlc); + UNUSED(ViPipe); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC2053_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc2053_mode; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->stImg, sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = GC2053_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc2053_mode.u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunGc2053_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = gc2053_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc2053_addr_byte; + pstI2c_data[i].u32DataByteNum = gc2053_data_byte; + } + + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC2053_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC2053_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC2053_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC2053_AGAIN_L_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC2053_COL_AGAIN_H_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC2053_COL_AGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC2053_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC2053_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC2053_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC2053_VTS_L_ADDR; + + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + + CVI_U32 gainsUpdate = 0; + + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + + if ((i >= LINEAR_AGAIN_H) && (i <= LINEAR_DGAIN_L)) + gainsUpdate = 1; + + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (gainsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L].bUpdate = CVI_TRUE; + } + + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC2053_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC2053_MODE_1920X1080P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc2053_MirrorFip[ViPipe] != eSnsMirrorFlip) { + gc2053_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeGc2053_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC2053_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc2053_mode.u32VtsDef; + pstSnsState->au32FL[0] = g_stGc2053_mode.u32VtsDef; + pstSnsState->au32FL[1] = g_stGc2053_mode.u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc2053_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_stGc2053_mode.stImg.stSnsSize.u32Width; + pstRxAttr->img_size.height = g_stGc2053_mode.stImg.stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc2053_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc2053_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc2053_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (GC2053_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc2053_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc2053_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc2053_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2053_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC2053_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2053_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC2053_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC2053_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC2053_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC2053_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC2053_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Gc2053_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Gc2053_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc2053_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc2053_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc2053_standby, + .pfnRestart = gc2053_restart, + .pfnWriteReg = gc2053_write_register, + .pfnReadReg = gc2053_read_register, + .pfnSetBusInfo = gc2053_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053/gc2053_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053/gc2053_cmos_ex.h new file mode 100644 index 000000000..05f2bb670 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053/gc2053_cmos_ex.h @@ -0,0 +1,88 @@ +#ifndef __GC2053_CMOS_EX_H_ +#define __GC2053_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum gc2053_linear_regs_e { + LINEAR_EXP_H = 0,//03 + LINEAR_EXP_L, //04 + LINEAR_AGAIN_H, //b4 + LINEAR_AGAIN_L, //b3 + LINEAR_COL_AGAIN_H, //b8 + LINEAR_COL_AGAIN_L, //b9 + LINEAR_DGAIN_H, //b1 + LINEAR_DGAIN_L, //b2 + LINEAR_VTS_H, //0x41 (frame length) + LINEAR_VTS_L,//0x42 + LINEAR_REGS_NUM +}; + + +typedef enum _GC2053_MODE_E { + GC2053_MODE_1920X1080P30 = 0, + GC2053_MODE_NUM +} GC2053_SLAVE_MODE_E; + +typedef struct _GC2053_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC2053_STATE_S; + +typedef struct _GC2053_MODE_S { + ISP_WDR_SIZE_S stImg; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp; + SNS_ATTR_LARGE_S stAgain; + SNS_ATTR_LARGE_S stDgain; + char name[64]; +} GC2053_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc2053[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc2053_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2053_MirrorFip[VI_MAX_PIPE_NUM]; +extern CVI_U8 gc2053_i2c_addr; +extern const CVI_U32 gc2053_addr_byte; +extern const CVI_U32 gc2053_data_byte; +extern void gc2053_init(VI_PIPE ViPipe); +extern void gc2053_exit(VI_PIPE ViPipe); +extern void gc2053_standby(VI_PIPE ViPipe); +extern void gc2053_restart(VI_PIPE ViPipe); +extern int gc2053_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc2053_read_register(VI_PIPE ViPipe, int addr); +extern void gc2053_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int gc2053_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2053_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053/gc2053_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053/gc2053_cmos_param.h new file mode 100644 index 000000000..d2824cf5b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053/gc2053_cmos_param.h @@ -0,0 +1,219 @@ +#ifndef __GC2053_CMOS_PARAM_H_ +#define __GC2053_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2053_cmos_ex.h" + +static const GC2053_MODE_S g_stGc2053_mode = { + .name = "1920X1080P30", + .stImg = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.07, /* 1125 * 30 / 0x3FFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp = { + .u16Min = 1, + .u16Max = 0x3fff, + .u16Def = 0x2000, + .u16Step = 1, + }, + .stAgain = { + .u32Min = 64, + .u32Max = 62977, + .u32Def = 64, + .u32Step = 1, + }, + .stDgain = { + .u32Min = 64*16, + .u32Max = 7073*16, + .u32Def = 581*16, + .u32Step = 10*16, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.05999477580189704895, 0.13019448518753051758}, //B: slope, intercept + {0.06732148677110671997, -1.36387133598327636719}, //Gb: slope, intercept + {0.06651904433965682983, -1.10093510150909423828}, //Gr: slope, intercept + {0.06406146287918090820, 0.33316791057586669922}, //R: slope, intercept + }, + { //iso 200 + {0.06256803125143051147, 4.54908418655395507813}, //B: slope, intercept + {0.06911934912204742432, 2.79023528099060058594}, //Gb: slope, intercept + {0.06846688687801361084, 2.88726186752319335938}, //Gr: slope, intercept + {0.06652788817882537842, 4.40276956558227539063}, //R: slope, intercept + }, + { //iso 400 + {0.06841833144426345825, 11.72280883789062500000}, //B: slope, intercept + {0.07257881015539169312, 10.86985683441162109375}, //Gb: slope, intercept + {0.07174283266067504883, 11.20646286010742187500}, //Gr: slope, intercept + {0.07294593751430511475, 11.17350578308105468750}, //R: slope, intercept + }, + { //iso 800 + {0.07805790752172470093, 20.62956619262695312500}, //B: slope, intercept + {0.07694032043218612671, 22.20356750488281250000}, //Gb: slope, intercept + {0.07647507637739181519, 22.50957298278808593750}, //Gr: slope, intercept + {0.08402533829212188721, 19.11953735351562500000}, //R: slope, intercept + }, + { //iso 1600 + {0.09468275308609008789, 34.07563018798828125000}, //B: slope, intercept + {0.08710632473230361938, 39.15500259399414062500}, //Gb: slope, intercept + {0.08662072569131851196, 39.37175750732421875000}, //Gr: slope, intercept + {0.10222808271646499634, 31.34789276123046875000}, //R: slope, intercept + }, + { //iso 3200 + {0.12651191651821136475, 49.56183242797851562500}, //B: slope, intercept + {0.10816962271928787231, 59.42719650268554687500}, //Gb: slope, intercept + {0.10751257836818695068, 59.90552902221679687500}, //Gr: slope, intercept + {0.13802853226661682129, 45.09576034545898437500}, //R: slope, intercept + }, + { //iso 6400 + {0.17422541975975036621, 70.04063415527343750000}, //B: slope, intercept + {0.14234761893749237061, 85.51583862304687500000}, //Gb: slope, intercept + {0.14159946143627166748, 86.23278045654296875000}, //Gr: slope, intercept + {0.19450971484184265137, 62.65447235107421875000}, //R: slope, intercept + }, + { //iso 12800 + {0.24947367608547210693, 108.30633544921875000000}, //B: slope, intercept + {0.19751225411891937256, 130.88159179687500000000}, //Gb: slope, intercept + {0.19614629447460174561, 132.49082946777343750000}, //Gr: slope, intercept + {0.28106108307838439941, 97.15969085693359375000}, //R: slope, intercept + }, + { //iso 25600 + {0.35420843958854675293, 137.06745910644531250000}, //B: slope, intercept + {0.27778801321983337402, 168.72366333007812500000}, //Gb: slope, intercept + {0.27540388703346252441, 170.54939270019531250000}, //Gr: slope, intercept + {0.39949953556060791016, 123.29409790039062500000}, //R: slope, intercept + }, + { //iso 51200 + {0.45704349875450134277, 179.20147705078125000000}, //B: slope, intercept + {0.32142028212547302246, 246.71363830566406250000}, //Gb: slope, intercept + {0.31958609819412231445, 246.82630920410156250000}, //Gr: slope, intercept + {0.51058447360992431641, 161.86299133300781250000}, //R: slope, intercept + }, + { //iso 102400 + {0.61760461330413818359, 222.90534973144531250000}, //B: slope, intercept + {0.42568457126617431641, 319.29257202148437500000}, //Gb: slope, intercept + {0.41750904917716979980, 324.93432617187500000000}, //Gr: slope, intercept + {0.67956107854843139648, 203.78948974609375000000}, //R: slope, intercept + }, + { //iso 204800 + {0.63289469480514526367, 216.99952697753906250000}, //B: slope, intercept + {0.44890350103378295898, 306.80810546875000000000}, //Gb: slope, intercept + {0.44229975342750549316, 310.13763427734375000000}, //Gr: slope, intercept + {0.69596910476684570313, 196.70443725585937500000}, //R: slope, intercept + }, + { //iso 409600 + {0.71106964349746704102, 187.98352050781250000000}, //B: slope, intercept + {0.55859673023223876953, 246.22378540039062500000}, //Gb: slope, intercept + {0.55284017324447631836, 249.86463928222656250000}, //Gr: slope, intercept + {0.77318203449249267578, 168.85035705566406250000}, //R: slope, intercept + }, + { //iso 819200 + {0.70888006687164306641, 188.44216918945312500000}, //B: slope, intercept + {0.56110274791717529297, 245.46603393554687500000}, //Gb: slope, intercept + {0.55100852251052856445, 250.33049011230468750000}, //Gr: slope, intercept + {0.76897650957107543945, 169.31251525878906250000}, //R: slope, intercept + }, + { //iso 1638400 + {0.70520979166030883789, 188.93899536132812500000}, //B: slope, intercept + {0.56178557872772216797, 245.21235656738281250000}, //Gb: slope, intercept + {0.55338454246520996094, 249.57423400878906250000}, //Gr: slope, intercept + {0.77306479215621948242, 168.86497497558593750000}, //R: slope, intercept + }, + { //iso 3276800 + {0.71255809068679809570, 187.86839294433593750000}, //B: slope, intercept + {0.56056070327758789063, 245.57748413085937500000}, //Gb: slope, intercept + {0.55358195304870605469, 249.62020874023437500000}, //Gr: slope, intercept + {0.77431541681289672852, 168.74313354492187500000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {257, 257, 257, 257, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {257, 257, 257, 257, 259, 259, 260, 267, 278, 298, 366, 383, 366, 373, 372, 372 }, + {257, 257, 257, 257, 258, 259, 261, 266, 274, 297, 379, 377, 372, 365, 373, 374 }, + {257, 257, 257, 257, 258, 259, 261, 266, 275, 296, 376, 388, 366, 374, 376, 372 }, + {257, 257, 257, 257, 258, 259, 260, 264, 274, 294, 362, 363, 365, 361, 353, 367 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1095, + 1099, 1104, 1125, 1130, 1125, 1127, 1126, 1126}, + {1093, 1093, 1093, 1093, 1093, 1093, 1094, 1095, + 1097, 1104, 1128, 1128, 1126, 1124, 1127, 1127}, + {1093, 1093, 1093, 1093, 1093, 1093, 1094, 1095, + 1098, 1104, 1128, 1131, 1125, 1127, 1128, 1126}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1095, + 1097, 1103, 1123, 1124, 1124, 1123, 1121, 1125}, +#endif + }, + }, +}; + +struct combo_dev_attr_s gc2053_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {1, 3, 2, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2053_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053/gc2053_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053/gc2053_sensor_ctl.c new file mode 100644 index 000000000..007ac86bf --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053/gc2053_sensor_ctl.c @@ -0,0 +1,395 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2053_cmos_ex.h" + +#define GC2053_CHIP_ID_ADDR_H 0xf0 +#define GC2053_CHIP_ID_ADDR_L 0xf1 +#define GC2053_CHIP_ID 0x2053 + +static void gc2053_linear_1080p30_init(VI_PIPE ViPipe); + +CVI_U8 gc2053_i2c_addr = 0x37;//0x6e +const CVI_U32 gc2053_addr_byte = 1; +const CVI_U32 gc2053_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc2053_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc2053_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc2053_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc2053_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc2053_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (gc2053_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc2053_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, gc2053_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc2053_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int gc2053_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc2053_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (gc2053_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc2053_addr_byte + gc2053_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + //syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void gc2053_standby(VI_PIPE ViPipe) +{ + gc2053_write_register(ViPipe, 0x3e, 0x00); + gc2053_write_register(ViPipe, 0xf7, 0x00); + gc2053_write_register(ViPipe, 0xfc, 0x01); + gc2053_write_register(ViPipe, 0xf9, 0x83); + + printf("gc2053_standby\n"); +} + +void gc2053_restart(VI_PIPE ViPipe) +{ + gc2053_write_register(ViPipe, 0xf9, 0x82); + delay_ms(2); + gc2053_write_register(ViPipe, 0xf7, 0x01); + gc2053_write_register(ViPipe, 0xfc, 0x8e); + gc2053_write_register(ViPipe, 0x3e, 0x91); + + printf("gc2053_restart\n"); +} + +void gc2053_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc2053[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc2053_write_register(ViPipe, + g_pastGc2053[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc2053[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} +void gc2053_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 value = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + value = 0x01; + break; + case ISP_SNS_FLIP: + value = 0x02; + break; + case ISP_SNS_MIRROR_FLIP: + value = 0x03; + break; + default: + return; + } + gc2053_write_register(ViPipe, 0xfe, 0x00); + gc2053_write_register(ViPipe, 0x17, value); +} + +int gc2053_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc2053_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc2053_read_register(ViPipe, GC2053_CHIP_ID_ADDR_H); + nVal2 = gc2053_read_register(ViPipe, GC2053_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC2053_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc2053_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode = g_pastGc2053[ViPipe]->enWDRMode; + + gc2053_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n"); + } else { + gc2053_linear_1080p30_init(ViPipe); + } + g_pastGc2053[ViPipe]->bInit = CVI_TRUE; +} + +void gc2053_exit(VI_PIPE ViPipe) +{ + gc2053_i2c_exit(ViPipe); +} + +static void gc2053_linear_1080p30_init(VI_PIPE ViPipe) +{ + /****system****/ + gc2053_write_register(ViPipe, 0xfe, 0x80); + gc2053_write_register(ViPipe, 0xfe, 0x80); + gc2053_write_register(ViPipe, 0xfe, 0x80); + gc2053_write_register(ViPipe, 0xfe, 0x00); + gc2053_write_register(ViPipe, 0xf2, 0x00); + gc2053_write_register(ViPipe, 0xf3, 0x00); + gc2053_write_register(ViPipe, 0xf4, 0x36); + gc2053_write_register(ViPipe, 0xf5, 0xc0); + gc2053_write_register(ViPipe, 0xf6, 0x44); + gc2053_write_register(ViPipe, 0xf7, 0x01); + gc2053_write_register(ViPipe, 0xf8, 0x2c); + gc2053_write_register(ViPipe, 0xf9, 0x42); + gc2053_write_register(ViPipe, 0xfc, 0x8e); + /****CISCTL & ANALOG****/ + gc2053_write_register(ViPipe, 0xfe, 0x00); + gc2053_write_register(ViPipe, 0x87, 0x18); + gc2053_write_register(ViPipe, 0xee, 0x30); + gc2053_write_register(ViPipe, 0xd0, 0xb7); + gc2053_write_register(ViPipe, 0x03, 0x04); + gc2053_write_register(ViPipe, 0x04, 0x60); + gc2053_write_register(ViPipe, 0x05, 0x04); + gc2053_write_register(ViPipe, 0x06, 0x4c); + gc2053_write_register(ViPipe, 0x07, 0x00); + gc2053_write_register(ViPipe, 0x08, 0x11); + gc2053_write_register(ViPipe, 0x09, 0x00); + gc2053_write_register(ViPipe, 0x0a, 0x02); + gc2053_write_register(ViPipe, 0x0b, 0x00); + gc2053_write_register(ViPipe, 0x0c, 0x02); + gc2053_write_register(ViPipe, 0x0d, 0x04); + gc2053_write_register(ViPipe, 0x0e, 0x40); + gc2053_write_register(ViPipe, 0x12, 0xe2); + gc2053_write_register(ViPipe, 0x13, 0x16); + gc2053_write_register(ViPipe, 0x19, 0x0a); + gc2053_write_register(ViPipe, 0x21, 0x1c); + gc2053_write_register(ViPipe, 0x28, 0x0a); + gc2053_write_register(ViPipe, 0x29, 0x24); + gc2053_write_register(ViPipe, 0x2b, 0x04); + gc2053_write_register(ViPipe, 0x32, 0xf8); + gc2053_write_register(ViPipe, 0x37, 0x03); + gc2053_write_register(ViPipe, 0x39, 0x15); + gc2053_write_register(ViPipe, 0x41, 0x04); + gc2053_write_register(ViPipe, 0x42, 0x65); + gc2053_write_register(ViPipe, 0x43, 0x07); + gc2053_write_register(ViPipe, 0x44, 0x40); + gc2053_write_register(ViPipe, 0x46, 0x0b); + gc2053_write_register(ViPipe, 0x4b, 0x20); + gc2053_write_register(ViPipe, 0x4e, 0x08); + gc2053_write_register(ViPipe, 0x55, 0x20); + gc2053_write_register(ViPipe, 0x66, 0x05); + gc2053_write_register(ViPipe, 0x67, 0x05); + gc2053_write_register(ViPipe, 0x77, 0x01); + gc2053_write_register(ViPipe, 0x78, 0x00); + gc2053_write_register(ViPipe, 0x7c, 0x93); + gc2053_write_register(ViPipe, 0x8c, 0x12); + gc2053_write_register(ViPipe, 0x8d, 0x92); + gc2053_write_register(ViPipe, 0x90, 0x00); + gc2053_write_register(ViPipe, 0x9d, 0x10); + gc2053_write_register(ViPipe, 0xce, 0x7c); + gc2053_write_register(ViPipe, 0xd2, 0x41); + gc2053_write_register(ViPipe, 0xd3, 0xdc); + gc2053_write_register(ViPipe, 0xe6, 0x50); + /*gain*/ + gc2053_write_register(ViPipe, 0xb6, 0xc0); + gc2053_write_register(ViPipe, 0xb0, 0x70); + gc2053_write_register(ViPipe, 0xb1, 0x01); + gc2053_write_register(ViPipe, 0xb2, 0x00); + gc2053_write_register(ViPipe, 0xb3, 0x00); + gc2053_write_register(ViPipe, 0xb4, 0x00); + gc2053_write_register(ViPipe, 0xb8, 0x01); + gc2053_write_register(ViPipe, 0xb9, 0x00); + /*blk*/ + gc2053_write_register(ViPipe, 0x26, 0x30); + gc2053_write_register(ViPipe, 0xfe, 0x01); + gc2053_write_register(ViPipe, 0x40, 0x23); + gc2053_write_register(ViPipe, 0x55, 0x07); + gc2053_write_register(ViPipe, 0x60, 0x40); + gc2053_write_register(ViPipe, 0xfe, 0x04); + gc2053_write_register(ViPipe, 0x14, 0x78); + gc2053_write_register(ViPipe, 0x15, 0x78); + gc2053_write_register(ViPipe, 0x16, 0x78); + gc2053_write_register(ViPipe, 0x17, 0x78); + /*window*/ + gc2053_write_register(ViPipe, 0xfe, 0x01); + gc2053_write_register(ViPipe, 0x91, 0x00); + gc2053_write_register(ViPipe, 0x92, 0x00); + gc2053_write_register(ViPipe, 0x93, 0x00); + gc2053_write_register(ViPipe, 0x94, 0x03); + gc2053_write_register(ViPipe, 0x95, 0x04); + gc2053_write_register(ViPipe, 0x96, 0x38); + gc2053_write_register(ViPipe, 0x97, 0x07); + gc2053_write_register(ViPipe, 0x98, 0x80); + /*ISP*/ + gc2053_write_register(ViPipe, 0xfe, 0x01); + gc2053_write_register(ViPipe, 0x01, 0x05); + gc2053_write_register(ViPipe, 0x02, 0x89); + gc2053_write_register(ViPipe, 0x04, 0x01); + gc2053_write_register(ViPipe, 0x07, 0xa6); + gc2053_write_register(ViPipe, 0x08, 0xa9); + gc2053_write_register(ViPipe, 0x09, 0xa8); + gc2053_write_register(ViPipe, 0x0a, 0xa7); + gc2053_write_register(ViPipe, 0x0b, 0xff); + gc2053_write_register(ViPipe, 0x0c, 0xff); + gc2053_write_register(ViPipe, 0x0f, 0x00); + gc2053_write_register(ViPipe, 0x50, 0x1c); + gc2053_write_register(ViPipe, 0x89, 0x03); + gc2053_write_register(ViPipe, 0xfe, 0x04); + gc2053_write_register(ViPipe, 0x28, 0x86); + gc2053_write_register(ViPipe, 0x29, 0x86); + gc2053_write_register(ViPipe, 0x2a, 0x86); + gc2053_write_register(ViPipe, 0x2b, 0x68); + gc2053_write_register(ViPipe, 0x2c, 0x68); + gc2053_write_register(ViPipe, 0x2d, 0x68); + gc2053_write_register(ViPipe, 0x2e, 0x68); + gc2053_write_register(ViPipe, 0x2f, 0x68); + gc2053_write_register(ViPipe, 0x30, 0x4f); + gc2053_write_register(ViPipe, 0x31, 0x68); + gc2053_write_register(ViPipe, 0x32, 0x67); + gc2053_write_register(ViPipe, 0x33, 0x66); + gc2053_write_register(ViPipe, 0x34, 0x66); + gc2053_write_register(ViPipe, 0x35, 0x66); + gc2053_write_register(ViPipe, 0x36, 0x66); + gc2053_write_register(ViPipe, 0x37, 0x66); + gc2053_write_register(ViPipe, 0x38, 0x62); + gc2053_write_register(ViPipe, 0x39, 0x62); + gc2053_write_register(ViPipe, 0x3a, 0x62); + gc2053_write_register(ViPipe, 0x3b, 0x62); + gc2053_write_register(ViPipe, 0x3c, 0x62); + gc2053_write_register(ViPipe, 0x3d, 0x62); + gc2053_write_register(ViPipe, 0x3e, 0x62); + gc2053_write_register(ViPipe, 0x3f, 0x62); + /****DVP & MIPI****/ + gc2053_write_register(ViPipe, 0xfe, 0x01); + gc2053_write_register(ViPipe, 0x9a, 0x06); + gc2053_write_register(ViPipe, 0xfe, 0x00); + gc2053_write_register(ViPipe, 0x7b, 0x2a); + gc2053_write_register(ViPipe, 0x23, 0x2d); + gc2053_write_register(ViPipe, 0xfe, 0x03); + gc2053_write_register(ViPipe, 0x01, 0x27); + gc2053_write_register(ViPipe, 0x02, 0x56); + gc2053_write_register(ViPipe, 0x03, 0x8e); + gc2053_write_register(ViPipe, 0x12, 0x80); + gc2053_write_register(ViPipe, 0x13, 0x07); + gc2053_write_register(ViPipe, 0x15, 0x12); + gc2053_write_register(ViPipe, 0xfe, 0x00); + gc2053_write_register(ViPipe, 0x3e, 0x91); + + gc2053_default_reg_init(ViPipe); + printf("ViPipe:%d,===GC2053 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_1L/Makefile b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_1L/Makefile new file mode 100644 index 000000000..64bd2a954 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_1L/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc2053_1l.a +TARGET_SO = $(MW_LIB)/libsns_gc2053_1l.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_1L/gc2053_1l_cmos.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_1L/gc2053_1l_cmos.c new file mode 100644 index 000000000..265a2a4ea --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_1L/gc2053_1l_cmos.c @@ -0,0 +1,969 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "gc2053_1l_cmos_ex.h" +#include "gc2053_1l_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define GC2053_1L_ID 2053 +#define GC2053_1L_I2C_ADDR_1 0x3f +#define GC2053_1L_I2C_ADDR_2 0x37 +#define GC2053_1L_I2C_ADDR_IS_VALID(addr) ((addr) == GC2053_1L_I2C_ADDR_1 || (addr) == GC2053_1L_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc2053_1l[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC2053_1L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc2053_1l[dev]) +#define GC2053_1L_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc2053_1l[dev] = pstCtx) +#define GC2053_1L_SENSOR_RESET_CTX(dev) (g_pastGc2053_1l[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc2053_1l_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +GC2053_1L_STATE_S g_astGc2053_1l_State[VI_MAX_PIPE_NUM] = { {0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2053_1l_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16Gc2053_1l_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Gc2053_1l_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Gc2053_1l Lines Range*****/ +#define GC2053_1L_FULL_LINES_MAX (0x3fff) + +/*****Gc2053_1l Register Address*****/ +#define GC2053_1L_EXP_H_ADDR 0x03 +#define GC2053_1L_EXP_L_ADDR 0x04 +#define GC2053_1L_AGAIN_H_ADDR 0xb4 +#define GC2053_1L_AGAIN_L_ADDR 0xb3 +#define GC2053_1L_COL_AGAIN_H_ADDR 0xb8 +#define GC2053_1L_COL_AGAIN_L_ADDR 0xb9 +#define GC2053_1L_DGAIN_H_ADDR 0xb1 +#define GC2053_1L_DGAIN_L_ADDR 0xb2 +#define GC2053_1L_VTS_H_ADDR 0x41 //(frame length) +#define GC2053_1L_VTS_L_ADDR 0x42 + +#define GC2053_1L_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const GC2053_1L_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc2053_1l_mode; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC2053_1L_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 3985*16; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 10240; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : + pstMode->stExp.u16Def; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp.u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp.u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = 0; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_stGc2053_1l_mode.u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_stGc2053_1l_mode.f32MaxFps; + f32MinFps = g_stGc2053_1l_mode.f32MinFps; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > GC2053_1L_FULL_LINES_MAX) ? GC2053_1L_FULL_LINES_MAX : u32VMAX; + + pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF); + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_U32 regValTable[25][4] = { + {0x00, 0x00, 0x01, 0x00}, + {0x00, 0x10, 0x01, 0x0c}, + {0x00, 0x20, 0x01, 0x1b}, + {0x00, 0x30, 0x01, 0x2c}, + {0x00, 0x40, 0x01, 0x3f}, + {0x00, 0x50, 0x02, 0x16}, + {0x00, 0x60, 0x02, 0x35}, + {0x00, 0x70, 0x03, 0x16}, + {0x00, 0x80, 0x04, 0x02}, + {0x00, 0x90, 0x04, 0x31}, + {0x00, 0xa0, 0x05, 0x32}, + {0x00, 0xb0, 0x06, 0x35}, + {0x00, 0xc0, 0x08, 0x04}, + {0x00, 0x5a, 0x09, 0x19}, + {0x00, 0x83, 0x0b, 0x0f}, + {0x00, 0x93, 0x0d, 0x12}, + {0x00, 0x84, 0x10, 0x00}, + {0x00, 0x94, 0x12, 0x3a}, + {0x01, 0x2c, 0x1a, 0x02}, + {0x01, 0x3c, 0x1b, 0x20}, + {0x00, 0x8c, 0x20, 0x0f}, + {0x00, 0x9c, 0x26, 0x07}, + {0x02, 0x64, 0x36, 0x21}, + {0x02, 0x74, 0x37, 0x3a}, + {0x00, 0xc6, 0x3d, 0x02}, + /* + {0x00, 0xdc, 0x3f, 0x3f}, + {0x02, 0x85, 0x3f, 0x3f}, + {0x02, 0x95, 0x3f, 0x3f}, + {0x00, 0xce, 0x3f, 0x3f}, + */ +}; + +static CVI_U32 gain_table[25] = { + 64*16, 76*16, 90*16, 108*16, 127*16, 148*16, 180*16, 216*16, 255*16, 300*16, + 361*16, 422*16, 504*16, 593*16, 722*16, 850*16, 1008*16, 1182*16, 1408*16, 1689*16, + 2021*16, 2391*16, 2850*16, 3369*16, 3985*16,/* 4805*16, 5768*16, 6806*16, 7723*16,*/ +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i, total; + CVI_U32 pregain; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + total = sizeof(gain_table) / sizeof(CVI_U32); + + if (*pu32AgainLin >= gain_table[total - 1]) { + *pu32AgainLin = *pu32AgainDb = gain_table[total - 1]; + return CVI_SUCCESS; + } + + for (i = 1; i < total; i++) { + if (*pu32AgainLin < gain_table[i]) + break; + } + i--; + // find the pregain + pregain = *pu32AgainLin * 64 / gain_table[i]; + // set the Db as the AE algo gain, we need this to do gain update + *pu32AgainDb = *pu32AgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32AgainLin = pregain * gain_table[i] / 64; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 pregain; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + // find the pregain + pregain = *pu32DgainLin * 64 / 1024; + // set the Db as the AE algo gain, we need this to do gain update + *pu32DgainDb = *pu32DgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32DgainLin = pregain * 16; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + int i, total; + + total = sizeof(gain_table) / sizeof(CVI_U32); + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* only surpport linear mode */ + u32Again = pu32Again[0]; + /* To kepp the linearity. we assume AE algo adjusts the dgain only when the again reachs the maximum value */ + if (u32Again < (3985*16)) { + for (i = 1; i < total; i++) { + if (*pu32Again < gain_table[i]) + break; + } + i--; + // find the pregain + u32Dgain = u32Again * 64 / gain_table[i]; + u32Again = i; + } else { + u32Again = total - 1; + // find the pregain + u32Dgain = pu32Dgain[0] * 64 / 1024; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][0]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][1]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][2]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][3]; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 6); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + UNUSED(ViPipe); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 8 : 8; + /* + * Long exp + Short exp < VTS - 4 + * max l2s distance = FL - boundary - active_h - 4 + * max sexp = max l2s distance - (L2S offset + 1) * 2 + */ + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 4) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + + u32IntTimeMaxTmp = (g_astGc2053_1l_State[ViPipe].u32Sexp_MAX < u32IntTimeMaxTmp) ? + g_astGc2053_1l_State[ViPipe].u32Sexp_MAX : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + syslog(LOG_DEBUG, "Max inttime0 = %u\n", u32IntTimeMaxTmp); + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio is too large!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + UNUSED(ViPipe); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + UNUSED(ViPipe); + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + CMOS_CHECK_POINTER(pstBlc); + UNUSED(ViPipe); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC2053_1L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc2053_1l_mode; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->stImg, sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = GC2053_1L_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc2053_1l_mode.u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunGc2053_1l_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = gc2053_1l_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc2053_1l_addr_byte; + pstI2c_data[i].u32DataByteNum = gc2053_1l_data_byte; + } + + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC2053_1L_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC2053_1L_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC2053_1L_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC2053_1L_AGAIN_L_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC2053_1L_COL_AGAIN_H_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC2053_1L_COL_AGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC2053_1L_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC2053_1L_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC2053_1L_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC2053_1L_VTS_L_ADDR; + + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + + CVI_U32 gainsUpdate = 0; + + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + + if ((i >= LINEAR_AGAIN_H) && (i <= LINEAR_DGAIN_L)) + gainsUpdate = 1; + + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (gainsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L].bUpdate = CVI_TRUE; + } + + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC2053_1L_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC2053_1L_MODE_1920X1080P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc2053_1l_MirrorFip[ViPipe] != eSnsMirrorFlip) { + gc2053_1l_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeGc2053_1l_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC2053_1L_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc2053_1l_mode.u32VtsDef; + pstSnsState->au32FL[0] = g_stGc2053_1l_mode.u32VtsDef; + pstSnsState->au32FL[1] = g_stGc2053_1l_mode.u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc2053_1l_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_stGc2053_1l_mode.stImg.stSnsSize.u32Width; + pstRxAttr->img_size.height = g_stGc2053_1l_mode.stImg.stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc2053_1l_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc2053_1l_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc2053_1l_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (GC2053_1L_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc2053_1l_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc2053_1l_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc2053_1l_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC2053_1L_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2053_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC2053_1L_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC2053_1L_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC2053_1L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC2053_1L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC2053_1L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Gc2053_1l_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Gc2053_1l_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc2053_1l_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc2053_1l_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc2053_1l_standby, + .pfnRestart = gc2053_1l_restart, + .pfnWriteReg = gc2053_1l_write_register, + .pfnReadReg = gc2053_1l_read_register, + .pfnSetBusInfo = gc2053_1l_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_1L/gc2053_1l_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_1L/gc2053_1l_cmos_ex.h new file mode 100644 index 000000000..bbabb3598 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_1L/gc2053_1l_cmos_ex.h @@ -0,0 +1,88 @@ +#ifndef __GC2053_1L_CMOS_EX_H_ +#define __GC2053_1L_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum gc2053_1l_linear_regs_e { + LINEAR_EXP_H = 0,//03 + LINEAR_EXP_L, //04 + LINEAR_AGAIN_H, //b4 + LINEAR_AGAIN_L, //b3 + LINEAR_COL_AGAIN_H, //b8 + LINEAR_COL_AGAIN_L, //b9 + LINEAR_DGAIN_H, //b1 + LINEAR_DGAIN_L, //b2 + LINEAR_VTS_H, //0x41 (frame length) + LINEAR_VTS_L,//0x42 + LINEAR_REGS_NUM +}; + + +typedef enum _GC2053_1L_MODE_E { + GC2053_1L_MODE_1920X1080P30 = 0, + GC2053_1L_MODE_NUM +} GC2053_1L_SLAVE_MODE_E; + +typedef struct _GC2053_1L_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC2053_1L_STATE_S; + +typedef struct _GC2053_1L_MODE_S { + ISP_WDR_SIZE_S stImg; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp; + SNS_ATTR_LARGE_S stAgain; + SNS_ATTR_LARGE_S stDgain; + char name[64]; +} GC2053_1L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc2053_1l[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc2053_1l_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2053_1l_MirrorFip[VI_MAX_PIPE_NUM]; +extern CVI_U8 gc2053_1l_i2c_addr; +extern const CVI_U32 gc2053_1l_addr_byte; +extern const CVI_U32 gc2053_1l_data_byte; +extern void gc2053_1l_init(VI_PIPE ViPipe); +extern void gc2053_1l_exit(VI_PIPE ViPipe); +extern void gc2053_1l_standby(VI_PIPE ViPipe); +extern void gc2053_1l_restart(VI_PIPE ViPipe); +extern int gc2053_1l_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc2053_1l_read_register(VI_PIPE ViPipe, int addr); +extern void gc2053_1l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int gc2053_1l_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2053_1L_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_1L/gc2053_1l_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_1L/gc2053_1l_cmos_param.h new file mode 100644 index 000000000..9eece0767 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_1L/gc2053_1l_cmos_param.h @@ -0,0 +1,223 @@ +#ifndef __GC2053_1L_CMOS_PARAM_H_ +#define __GC2053_1L_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2053_1l_cmos_ex.h" + +static const GC2053_1L_MODE_S g_stGc2053_1l_mode = { + .name = "1920X1080P30", + .stImg = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.07, /* 1125 * 30 / 0x3FFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp = { + .u16Min = 1, + .u16Max = 0x3fff, + .u16Def = 0x2000, + .u16Step = 1, + }, + .stAgain = { + .u32Min = 64, + .u32Max = 62977, + .u32Def = 64, + .u32Step = 1, + }, + .stDgain = { + .u32Min = 64*16, + .u32Max = 7073*16, + .u32Def = 581*16, + .u32Step = 10*16, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.05999477580189704895, 0.13019448518753051758}, //B: slope, intercept + {0.06732148677110671997, -1.36387133598327636719}, //Gb: slope, intercept + {0.06651904433965682983, -1.10093510150909423828}, //Gr: slope, intercept + {0.06406146287918090820, 0.33316791057586669922}, //R: slope, intercept + }, + { //iso 200 + {0.06256803125143051147, 4.54908418655395507813}, //B: slope, intercept + {0.06911934912204742432, 2.79023528099060058594}, //Gb: slope, intercept + {0.06846688687801361084, 2.88726186752319335938}, //Gr: slope, intercept + {0.06652788817882537842, 4.40276956558227539063}, //R: slope, intercept + }, + { //iso 400 + {0.06841833144426345825, 11.72280883789062500000}, //B: slope, intercept + {0.07257881015539169312, 10.86985683441162109375}, //Gb: slope, intercept + {0.07174283266067504883, 11.20646286010742187500}, //Gr: slope, intercept + {0.07294593751430511475, 11.17350578308105468750}, //R: slope, intercept + }, + { //iso 800 + {0.07805790752172470093, 20.62956619262695312500}, //B: slope, intercept + {0.07694032043218612671, 22.20356750488281250000}, //Gb: slope, intercept + {0.07647507637739181519, 22.50957298278808593750}, //Gr: slope, intercept + {0.08402533829212188721, 19.11953735351562500000}, //R: slope, intercept + }, + { //iso 1600 + {0.09468275308609008789, 34.07563018798828125000}, //B: slope, intercept + {0.08710632473230361938, 39.15500259399414062500}, //Gb: slope, intercept + {0.08662072569131851196, 39.37175750732421875000}, //Gr: slope, intercept + {0.10222808271646499634, 31.34789276123046875000}, //R: slope, intercept + }, + { //iso 3200 + {0.12651191651821136475, 49.56183242797851562500}, //B: slope, intercept + {0.10816962271928787231, 59.42719650268554687500}, //Gb: slope, intercept + {0.10751257836818695068, 59.90552902221679687500}, //Gr: slope, intercept + {0.13802853226661682129, 45.09576034545898437500}, //R: slope, intercept + }, + { //iso 6400 + {0.17422541975975036621, 70.04063415527343750000}, //B: slope, intercept + {0.14234761893749237061, 85.51583862304687500000}, //Gb: slope, intercept + {0.14159946143627166748, 86.23278045654296875000}, //Gr: slope, intercept + {0.19450971484184265137, 62.65447235107421875000}, //R: slope, intercept + }, + { //iso 12800 + {0.24947367608547210693, 108.30633544921875000000}, //B: slope, intercept + {0.19751225411891937256, 130.88159179687500000000}, //Gb: slope, intercept + {0.19614629447460174561, 132.49082946777343750000}, //Gr: slope, intercept + {0.28106108307838439941, 97.15969085693359375000}, //R: slope, intercept + }, + { //iso 25600 + {0.35420843958854675293, 137.06745910644531250000}, //B: slope, intercept + {0.27778801321983337402, 168.72366333007812500000}, //Gb: slope, intercept + {0.27540388703346252441, 170.54939270019531250000}, //Gr: slope, intercept + {0.39949953556060791016, 123.29409790039062500000}, //R: slope, intercept + }, + { //iso 51200 + {0.45704349875450134277, 179.20147705078125000000}, //B: slope, intercept + {0.32142028212547302246, 246.71363830566406250000}, //Gb: slope, intercept + {0.31958609819412231445, 246.82630920410156250000}, //Gr: slope, intercept + {0.51058447360992431641, 161.86299133300781250000}, //R: slope, intercept + }, + { //iso 102400 + {0.61760461330413818359, 222.90534973144531250000}, //B: slope, intercept + {0.42568457126617431641, 319.29257202148437500000}, //Gb: slope, intercept + {0.41750904917716979980, 324.93432617187500000000}, //Gr: slope, intercept + {0.67956107854843139648, 203.78948974609375000000}, //R: slope, intercept + }, + { //iso 204800 + {0.63289469480514526367, 216.99952697753906250000}, //B: slope, intercept + {0.44890350103378295898, 306.80810546875000000000}, //Gb: slope, intercept + {0.44229975342750549316, 310.13763427734375000000}, //Gr: slope, intercept + {0.69596910476684570313, 196.70443725585937500000}, //R: slope, intercept + }, + { //iso 409600 + {0.71106964349746704102, 187.98352050781250000000}, //B: slope, intercept + {0.55859673023223876953, 246.22378540039062500000}, //Gb: slope, intercept + {0.55284017324447631836, 249.86463928222656250000}, //Gr: slope, intercept + {0.77318203449249267578, 168.85035705566406250000}, //R: slope, intercept + }, + { //iso 819200 + {0.70888006687164306641, 188.44216918945312500000}, //B: slope, intercept + {0.56110274791717529297, 245.46603393554687500000}, //Gb: slope, intercept + {0.55100852251052856445, 250.33049011230468750000}, //Gr: slope, intercept + {0.76897650957107543945, 169.31251525878906250000}, //R: slope, intercept + }, + { //iso 1638400 + {0.70520979166030883789, 188.93899536132812500000}, //B: slope, intercept + {0.56178557872772216797, 245.21235656738281250000}, //Gb: slope, intercept + {0.55338454246520996094, 249.57423400878906250000}, //Gr: slope, intercept + {0.77306479215621948242, 168.86497497558593750000}, //R: slope, intercept + }, + { //iso 3276800 + {0.71255809068679809570, 187.86839294433593750000}, //B: slope, intercept + {0.56056070327758789063, 245.57748413085937500000}, //Gb: slope, intercept + {0.55358195304870605469, 249.62020874023437500000}, //Gr: slope, intercept + {0.77431541681289672852, 168.74313354492187500000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {257, 257, 257, 257, 0, 0, 0 +#ifdef ARCH_CV182X + , 0, 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {257, 257, 257, 257, 259, 259, 260, 267, 278, 298, 366, 383, 366, 373, 372, 372 }, + {257, 257, 257, 257, 258, 259, 261, 266, 274, 297, 379, 377, 372, 365, 373, 374 }, + {257, 257, 257, 257, 258, 259, 261, 266, 275, 296, 376, 388, 366, 374, 376, 372 }, + {257, 257, 257, 257, 258, 259, 260, 264, 274, 294, 362, 363, 365, 361, 353, 367 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1095, + 1099, 1104, 1125, 1130, 1125, 1127, 1126, 1126}, + {1093, 1093, 1093, 1093, 1093, 1093, 1094, 1095, + 1097, 1104, 1128, 1128, 1126, 1124, 1127, 1127}, + {1093, 1093, 1093, 1093, 1093, 1093, 1094, 1095, + 1098, 1104, 1128, 1131, 1125, 1127, 1128, 1126}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1095, + 1097, 1103, 1123, 1124, 1124, 1123, 1121, 1125}, +#endif + }, + }, +}; + +struct combo_dev_attr_s gc2053_1l_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {3, 4, -1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 31, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 1, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2053_1L_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_1L/gc2053_1l_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_1L/gc2053_1l_sensor_ctl.c new file mode 100644 index 000000000..328bb8320 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_1L/gc2053_1l_sensor_ctl.c @@ -0,0 +1,398 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2053_1l_cmos_ex.h" + +#define GC2053_1L_CHIP_ID_ADDR_H 0xf0 +#define GC2053_1L_CHIP_ID_ADDR_L 0xf1 +#define GC2053_1L_CHIP_ID 0x2053 + +static void gc2053_1l_linear_1080p30_init(VI_PIPE ViPipe); + +CVI_U8 gc2053_1l_i2c_addr = 0x3f;//0x7e +const CVI_U32 gc2053_1l_addr_byte = 1; +const CVI_U32 gc2053_1l_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc2053_1l_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc2053_1l_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc2053_1l_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc2053_1l_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc2053_1l_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (gc2053_1l_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc2053_1l_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, gc2053_1l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc2053_1l_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int gc2053_1l_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc2053_1l_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (gc2053_1l_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc2053_1l_addr_byte + gc2053_1l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + ret = read(g_fd[ViPipe], buf, gc2053_1l_addr_byte + gc2053_1l_data_byte); + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void gc2053_1l_standby(VI_PIPE ViPipe) +{ + gc2053_1l_write_register(ViPipe, 0x3e, 0x00); + gc2053_1l_write_register(ViPipe, 0xf7, 0x00); + gc2053_1l_write_register(ViPipe, 0xfc, 0x01); + gc2053_1l_write_register(ViPipe, 0xf9, 0x83); + + printf("gc2053_1l_standby\n"); +} + +void gc2053_1l_restart(VI_PIPE ViPipe) +{ + gc2053_1l_write_register(ViPipe, 0xf9, 0x82); + delay_ms(2); + gc2053_1l_write_register(ViPipe, 0xf7, 0x01); + gc2053_1l_write_register(ViPipe, 0xfc, 0x8e); + gc2053_1l_write_register(ViPipe, 0x3e, 0x90); + + printf("gc2053_1l_restart\n"); +} + +void gc2053_1l_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc2053_1l[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc2053_1l_write_register(ViPipe, + g_pastGc2053_1l[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc2053_1l[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} +void gc2053_1l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 value = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + value = 0x01; + break; + case ISP_SNS_FLIP: + value = 0x02; + break; + case ISP_SNS_MIRROR_FLIP: + value = 0x03; + break; + default: + return; + } + gc2053_1l_write_register(ViPipe, 0xfe, 0x00); + gc2053_1l_write_register(ViPipe, 0x17, value); +} + +int gc2053_1l_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc2053_1l_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc2053_1l_read_register(ViPipe, GC2053_1L_CHIP_ID_ADDR_H); + nVal2 = gc2053_1l_read_register(ViPipe, GC2053_1L_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC2053_1L_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc2053_1l_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode = g_pastGc2053_1l[ViPipe]->enWDRMode; + + gc2053_1l_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n"); + } else { + gc2053_1l_linear_1080p30_init(ViPipe); + } + g_pastGc2053_1l[ViPipe]->bInit = CVI_TRUE; +} + +void gc2053_1l_exit(VI_PIPE ViPipe) +{ + gc2053_1l_i2c_exit(ViPipe); +} + +static void gc2053_1l_linear_1080p30_init(VI_PIPE ViPipe) +{ + /****system****/ + gc2053_1l_write_register(ViPipe, 0xfe, 0x80); + gc2053_1l_write_register(ViPipe, 0xfe, 0x80); + gc2053_1l_write_register(ViPipe, 0xfe, 0x80); + gc2053_1l_write_register(ViPipe, 0xfe, 0x00); + gc2053_1l_write_register(ViPipe, 0xf2, 0x00); + gc2053_1l_write_register(ViPipe, 0xf3, 0x00); + gc2053_1l_write_register(ViPipe, 0xf4, 0x36); + gc2053_1l_write_register(ViPipe, 0xf5, 0xc0); + gc2053_1l_write_register(ViPipe, 0xf6, 0x82); + gc2053_1l_write_register(ViPipe, 0xf7, 0x01); + gc2053_1l_write_register(ViPipe, 0xf8, 0x20); + gc2053_1l_write_register(ViPipe, 0xf9, 0x82); + gc2053_1l_write_register(ViPipe, 0xfc, 0x8e); + /****CISCTL & ANALOG****/ + gc2053_1l_write_register(ViPipe, 0xfe, 0x00); + gc2053_1l_write_register(ViPipe, 0x87, 0x18); + gc2053_1l_write_register(ViPipe, 0xee, 0x30); + gc2053_1l_write_register(ViPipe, 0xd0, 0xb7); + gc2053_1l_write_register(ViPipe, 0x03, 0x04); + gc2053_1l_write_register(ViPipe, 0x04, 0x10); + gc2053_1l_write_register(ViPipe, 0x05, 0x05);//05 + gc2053_1l_write_register(ViPipe, 0x06, 0x00);//60//[11:0]hb + gc2053_1l_write_register(ViPipe, 0x07, 0x00); + gc2053_1l_write_register(ViPipe, 0x08, 0x19); + gc2053_1l_write_register(ViPipe, 0x09, 0x00); + gc2053_1l_write_register(ViPipe, 0x0a, 0x02); //cisctl row start + gc2053_1l_write_register(ViPipe, 0x0b, 0x00); + gc2053_1l_write_register(ViPipe, 0x0c, 0x02); //cisctl col start + gc2053_1l_write_register(ViPipe, 0x0d, 0x04); + gc2053_1l_write_register(ViPipe, 0x0e, 0x40); + gc2053_1l_write_register(ViPipe, 0x12, 0xe2); + gc2053_1l_write_register(ViPipe, 0x13, 0x16); + gc2053_1l_write_register(ViPipe, 0x19, 0x0a); + gc2053_1l_write_register(ViPipe, 0x21, 0x1c); + gc2053_1l_write_register(ViPipe, 0x28, 0x0a); + gc2053_1l_write_register(ViPipe, 0x29, 0x24); + gc2053_1l_write_register(ViPipe, 0x2b, 0x04); + gc2053_1l_write_register(ViPipe, 0x32, 0xf8); + gc2053_1l_write_register(ViPipe, 0x37, 0x03); + gc2053_1l_write_register(ViPipe, 0x39, 0x15); + gc2053_1l_write_register(ViPipe, 0x41, 0x04); + gc2053_1l_write_register(ViPipe, 0x42, 0x65); + gc2053_1l_write_register(ViPipe, 0x43, 0x07); + gc2053_1l_write_register(ViPipe, 0x44, 0x40); + gc2053_1l_write_register(ViPipe, 0x46, 0x0b); + gc2053_1l_write_register(ViPipe, 0x4b, 0x20); + gc2053_1l_write_register(ViPipe, 0x4e, 0x08); + gc2053_1l_write_register(ViPipe, 0x55, 0x20); + gc2053_1l_write_register(ViPipe, 0x66, 0x05); + gc2053_1l_write_register(ViPipe, 0x67, 0x05); + gc2053_1l_write_register(ViPipe, 0x77, 0x01); + gc2053_1l_write_register(ViPipe, 0x78, 0x00); + gc2053_1l_write_register(ViPipe, 0x7c, 0x93); + gc2053_1l_write_register(ViPipe, 0x8c, 0x12); + gc2053_1l_write_register(ViPipe, 0x8d, 0x92); + gc2053_1l_write_register(ViPipe, 0x90, 0x00); + gc2053_1l_write_register(ViPipe, 0x9d, 0x10); + gc2053_1l_write_register(ViPipe, 0xce, 0x7c); + gc2053_1l_write_register(ViPipe, 0xd2, 0x41); + gc2053_1l_write_register(ViPipe, 0xd3, 0xdc); + gc2053_1l_write_register(ViPipe, 0xda, 0x05); + gc2053_1l_write_register(ViPipe, 0xdb, 0x00); + gc2053_1l_write_register(ViPipe, 0xe6, 0x50); + /*gain*/ + gc2053_1l_write_register(ViPipe, 0xb6, 0xc0); + gc2053_1l_write_register(ViPipe, 0xb0, 0x70); + gc2053_1l_write_register(ViPipe, 0xb1, 0x01); + gc2053_1l_write_register(ViPipe, 0xb2, 0x00); + gc2053_1l_write_register(ViPipe, 0xb3, 0x00); + gc2053_1l_write_register(ViPipe, 0xb4, 0x00); + gc2053_1l_write_register(ViPipe, 0xb8, 0x01); + gc2053_1l_write_register(ViPipe, 0xb9, 0x00); + /*blk*/ + gc2053_1l_write_register(ViPipe, 0x26, 0x30); + gc2053_1l_write_register(ViPipe, 0xfe, 0x01); + gc2053_1l_write_register(ViPipe, 0x40, 0x23); + gc2053_1l_write_register(ViPipe, 0x55, 0x07); + gc2053_1l_write_register(ViPipe, 0x60, 0x40); //[7:0]WB_offset + gc2053_1l_write_register(ViPipe, 0xfe, 0x04); + gc2053_1l_write_register(ViPipe, 0x14, 0x78); + gc2053_1l_write_register(ViPipe, 0x15, 0x78); + gc2053_1l_write_register(ViPipe, 0x16, 0x78); + gc2053_1l_write_register(ViPipe, 0x17, 0x78); + /*window*/ + gc2053_1l_write_register(ViPipe, 0xfe, 0x01); + gc2053_1l_write_register(ViPipe, 0x92, 0x00); //win y1 + gc2053_1l_write_register(ViPipe, 0x94, 0x03); //win x1 + gc2053_1l_write_register(ViPipe, 0x95, 0x04); + gc2053_1l_write_register(ViPipe, 0x96, 0x38); //[10:0]out_height + gc2053_1l_write_register(ViPipe, 0x97, 0x07); + gc2053_1l_write_register(ViPipe, 0x98, 0x80); //[11:0]out_width + /*ISP*/ + gc2053_1l_write_register(ViPipe, 0xfe, 0x01); + gc2053_1l_write_register(ViPipe, 0x01, 0x05); + gc2053_1l_write_register(ViPipe, 0x02, 0x89); + gc2053_1l_write_register(ViPipe, 0x04, 0x01); //[0]DD_en + gc2053_1l_write_register(ViPipe, 0x07, 0xa6); + gc2053_1l_write_register(ViPipe, 0x08, 0xa9); + gc2053_1l_write_register(ViPipe, 0x09, 0xa8); + gc2053_1l_write_register(ViPipe, 0x0a, 0xa7); + gc2053_1l_write_register(ViPipe, 0x0b, 0xff); + gc2053_1l_write_register(ViPipe, 0x0c, 0xff); + gc2053_1l_write_register(ViPipe, 0x0f, 0x00); + gc2053_1l_write_register(ViPipe, 0x50, 0x1c); + gc2053_1l_write_register(ViPipe, 0x89, 0x03); + gc2053_1l_write_register(ViPipe, 0xfe, 0x04); + gc2053_1l_write_register(ViPipe, 0x28, 0x86);//84 + gc2053_1l_write_register(ViPipe, 0x29, 0x86);//84 + gc2053_1l_write_register(ViPipe, 0x2a, 0x86);//84 + gc2053_1l_write_register(ViPipe, 0x2b, 0x68);//84 + gc2053_1l_write_register(ViPipe, 0x2c, 0x68);//84 + gc2053_1l_write_register(ViPipe, 0x2d, 0x68);//84 + gc2053_1l_write_register(ViPipe, 0x2e, 0x68);//83 + gc2053_1l_write_register(ViPipe, 0x2f, 0x68);//82 + gc2053_1l_write_register(ViPipe, 0x30, 0x4f);//82 + gc2053_1l_write_register(ViPipe, 0x31, 0x68);//82 + gc2053_1l_write_register(ViPipe, 0x32, 0x67);//82 + gc2053_1l_write_register(ViPipe, 0x33, 0x66);//82 + gc2053_1l_write_register(ViPipe, 0x34, 0x66);//82 + gc2053_1l_write_register(ViPipe, 0x35, 0x66);//82 + gc2053_1l_write_register(ViPipe, 0x36, 0x66);//64 + gc2053_1l_write_register(ViPipe, 0x37, 0x66);//68 + gc2053_1l_write_register(ViPipe, 0x38, 0x62); + gc2053_1l_write_register(ViPipe, 0x39, 0x62); + gc2053_1l_write_register(ViPipe, 0x3a, 0x62); + gc2053_1l_write_register(ViPipe, 0x3b, 0x62); + gc2053_1l_write_register(ViPipe, 0x3c, 0x62); + gc2053_1l_write_register(ViPipe, 0x3d, 0x62); + gc2053_1l_write_register(ViPipe, 0x3e, 0x62); + gc2053_1l_write_register(ViPipe, 0x3f, 0x62); + /****DVP & MIPI****/ + gc2053_1l_write_register(ViPipe, 0xfe, 0x01); + gc2053_1l_write_register(ViPipe, 0x9a, 0x06); + gc2053_1l_write_register(ViPipe, 0xfe, 0x00); + gc2053_1l_write_register(ViPipe, 0x7b, 0x2a); + gc2053_1l_write_register(ViPipe, 0x23, 0x2d); + gc2053_1l_write_register(ViPipe, 0xfe, 0x03); + gc2053_1l_write_register(ViPipe, 0x01, 0x27); + gc2053_1l_write_register(ViPipe, 0x02, 0x56); + gc2053_1l_write_register(ViPipe, 0x03, 0xb6); + gc2053_1l_write_register(ViPipe, 0x12, 0x80); + gc2053_1l_write_register(ViPipe, 0x13, 0x07); + gc2053_1l_write_register(ViPipe, 0x15, 0x12); + gc2053_1l_write_register(ViPipe, 0x29, 0x16);// hs_prepare + gc2053_1l_write_register(ViPipe, 0x36, 0x03);// clk lp drv + gc2053_1l_write_register(ViPipe, 0x37, 0x0f);// clk lp drv + gc2053_1l_write_register(ViPipe, 0xfe, 0x00); + gc2053_1l_write_register(ViPipe, 0x3e, 0x90); + + gc2053_1l_default_reg_init(ViPipe); + printf("ViPipe:%d,===GC2053_1L 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_slave/Makefile b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_slave/Makefile new file mode 100644 index 000000000..d64869402 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_slave/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc2053_slave.a +TARGET_SO = $(MW_LIB)/libsns_gc2053_slave.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_slave/gc2053_slave_cmos.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_slave/gc2053_slave_cmos.c new file mode 100644 index 000000000..a93bc4c7e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_slave/gc2053_slave_cmos.c @@ -0,0 +1,883 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "gc2053_slave_cmos_ex.h" +#include "gc2053_slave_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define GC2053_SLAVE_ID 2053 +#define GC2053_SLAVE_I2C_ADDR_1 0x3f +#define GC2053_SLAVE_I2C_ADDR_2 0x37 +#define GC2053_SLAVE_I2C_ADDR_IS_VALID(addr) ((addr) == GC2053_SLAVE_I2C_ADDR_1 || (addr) == GC2053_SLAVE_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc2053_Slave[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC2053_SLAVE_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc2053_Slave[dev]) +#define GC2053_SLAVE_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc2053_Slave[dev] = pstCtx) +#define GC2053_SLAVE_SENSOR_RESET_CTX(dev) (g_pastGc2053_Slave[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc2053_Slave_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 3}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +GC2053_SLAVE_STATE_S g_astGc2053_Slave_State[VI_MAX_PIPE_NUM] = { {0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2053_Slave_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16Gc2053_Slave_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Gc2053_Slave_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Gc2053_Slave Lines Range*****/ +#define GC2053_SLAVE_FULL_LINES_MAX (0x3fff) + +/*****Gc2053_Slave Register Address*****/ +#define GC2053_SLAVE_EXP_H_ADDR 0x03 +#define GC2053_SLAVE_EXP_L_ADDR 0x04 +#define GC2053_SLAVE_AGAIN_H_ADDR 0xb4 +#define GC2053_SLAVE_AGAIN_L_ADDR 0xb3 +#define GC2053_SLAVE_COL_AGAIN_H_ADDR 0xb8 +#define GC2053_SLAVE_COL_AGAIN_L_ADDR 0xb9 +#define GC2053_SLAVE_DGAIN_H_ADDR 0xb1 +#define GC2053_SLAVE_DGAIN_L_ADDR 0xb2 +#define GC2053_SLAVE_VTS_H_ADDR 0x41 //(frame length) +#define GC2053_SLAVE_VTS_L_ADDR 0x42 + +#define GC2053_SLAVE_RES_IS_1080P(w, h) ((w) == 1920 && (h) == 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const GC2053_SLAVE_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc2053_Slave_mode; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC2053_SLAVE_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 3985*16; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 10240; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : + pstMode->stExp.u16Def; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp.u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp.u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = 0; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_stGc2053_Slave_mode.u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_stGc2053_Slave_mode.f32MaxFps; + f32MinFps = g_stGc2053_Slave_mode.f32MinFps; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > GC2053_SLAVE_FULL_LINES_MAX) ? GC2053_SLAVE_FULL_LINES_MAX : u32VMAX; + + pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF); + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_U32 regValTable[25][4] = { + {0x00, 0x00, 0x01, 0x00}, + {0x00, 0x10, 0x01, 0x0c}, + {0x00, 0x20, 0x01, 0x1b}, + {0x00, 0x30, 0x01, 0x2c}, + {0x00, 0x40, 0x01, 0x3f}, + {0x00, 0x50, 0x02, 0x16}, + {0x00, 0x60, 0x02, 0x35}, + {0x00, 0x70, 0x03, 0x16}, + {0x00, 0x80, 0x04, 0x02}, + {0x00, 0x90, 0x04, 0x31}, + {0x00, 0xa0, 0x05, 0x32}, + {0x00, 0xb0, 0x06, 0x35}, + {0x00, 0xc0, 0x08, 0x04}, + {0x00, 0x5a, 0x09, 0x19}, + {0x00, 0x83, 0x0b, 0x0f}, + {0x00, 0x93, 0x0d, 0x12}, + {0x00, 0x84, 0x10, 0x00}, + {0x00, 0x94, 0x12, 0x3a}, + {0x01, 0x2c, 0x1a, 0x02}, + {0x01, 0x3c, 0x1b, 0x20}, + {0x00, 0x8c, 0x20, 0x0f}, + {0x00, 0x9c, 0x26, 0x07}, + {0x02, 0x64, 0x36, 0x21}, + {0x02, 0x74, 0x37, 0x3a}, + {0x00, 0xc6, 0x3d, 0x02}, +}; + +static CVI_U32 gain_table[25] = { + 64*16, 76*16, 90*16, 108*16, 127*16, 148*16, 180*16, 216*16, 255*16, 300*16, + 361*16, 422*16, 504*16, 593*16, 722*16, 850*16, 1008*16, 1182*16, 1408*16, 1689*16, + 2021*16, 2391*16, 2850*16, 3369*16, 3985*16,/* 4805*16, 5768*16, 6806*16, 7723*16,*/ +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i, total; + CVI_U32 pregain; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + total = sizeof(gain_table) / sizeof(CVI_U32); + + if (*pu32AgainLin >= gain_table[total - 1]) { + *pu32AgainLin = *pu32AgainDb = gain_table[total - 1]; + return CVI_SUCCESS; + } + + for (i = 1; i < total; i++) { + if (*pu32AgainLin < gain_table[i]) + break; + } + i--; + // find the pregain + pregain = *pu32AgainLin * 64 / gain_table[i]; + // set the Db as the AE algo gain, we need this to do gain update + *pu32AgainDb = *pu32AgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32AgainLin = pregain * gain_table[i] / 64; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 pregain; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + // find the pregain + pregain = *pu32DgainLin * 64 / 1024; + // set the Db as the AE algo gain, we need this to do gain update + *pu32DgainDb = *pu32DgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32DgainLin = pregain * 16; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + int i, total; + + total = sizeof(gain_table) / sizeof(CVI_U32); + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* only surpport linear mode */ + u32Again = pu32Again[0]; + /* To kepp the linearity. we assume AE algo adjusts the dgain only when the again reachs the maximum value */ + if (u32Again < (3985*16)) { + for (i = 1; i < total; i++) { + if (*pu32Again < gain_table[i]) + break; + } + i--; + // find the pregain + u32Dgain = u32Again * 64 / gain_table[i]; + u32Again = i; + } else { + u32Again = total - 1; + // find the pregain + u32Dgain = pu32Dgain[0] * 64 / 1024; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][0]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][1]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][2]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][3]; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 6); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + UNUSED(ViPipe); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + UNUSED(ViPipe); + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + CMOS_CHECK_POINTER(pstBlc); + UNUSED(ViPipe); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC2053_SLAVE_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc2053_Slave_mode; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->stImg, sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = GC2053_SLAVE_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc2053_Slave_mode.u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunGc2053_Slave_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = gc2053_slave_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc2053_slave_addr_byte; + pstI2c_data[i].u32DataByteNum = gc2053_slave_data_byte; + } + + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC2053_SLAVE_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC2053_SLAVE_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC2053_SLAVE_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC2053_SLAVE_AGAIN_L_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC2053_SLAVE_COL_AGAIN_H_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC2053_SLAVE_COL_AGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC2053_SLAVE_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC2053_SLAVE_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC2053_SLAVE_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC2053_SLAVE_VTS_L_ADDR; + + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + + CVI_U32 gainsUpdate = 0; + + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + + if ((i >= LINEAR_AGAIN_H) && (i <= LINEAR_DGAIN_L)) + gainsUpdate = 1; + + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (gainsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L].bUpdate = CVI_TRUE; + } + + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC2053_SLAVE_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC2053_SLAVE_MODE_1920X1080P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc2053_Slave_MirrorFip[ViPipe] != eSnsMirrorFlip) { + gc2053_slave_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeGc2053_Slave_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC2053_SLAVE_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc2053_Slave_mode.u32VtsDef; + pstSnsState->au32FL[0] = g_stGc2053_Slave_mode.u32VtsDef; + pstSnsState->au32FL[1] = g_stGc2053_Slave_mode.u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc2053_slave_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_stGc2053_Slave_mode.stImg.stSnsSize.u32Width; + pstRxAttr->img_size.height = g_stGc2053_Slave_mode.stImg.stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc2053_slave_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc2053_slave_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc2053_slave_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (GC2053_SLAVE_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc2053_slave_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc2053_slave_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc2053_Slave_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC2053_SLAVE_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2053_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC2053_SLAVE_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC2053_SLAVE_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC2053_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC2053_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC2053_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Gc2053_Slave_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Gc2053_Slave_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc2053_slave_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc2053_Slave_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc2053_slave_standby, + .pfnRestart = gc2053_slave_restart, + .pfnWriteReg = gc2053_slave_write_register, + .pfnReadReg = gc2053_slave_read_register, + .pfnSetBusInfo = gc2053_slave_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_slave/gc2053_slave_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_slave/gc2053_slave_cmos_ex.h new file mode 100644 index 000000000..60b1f7e56 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_slave/gc2053_slave_cmos_ex.h @@ -0,0 +1,88 @@ +#ifndef __GC2053_SLAVE_CMOS_EX_H_ +#define __GC2053_SLAVE_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum gc2053_slave_linear_regs_e { + LINEAR_EXP_H = 0,//03 + LINEAR_EXP_L, //04 + LINEAR_AGAIN_H, //b4 + LINEAR_AGAIN_L, //b3 + LINEAR_COL_AGAIN_H, //b8 + LINEAR_COL_AGAIN_L, //b9 + LINEAR_DGAIN_H, //b1 + LINEAR_DGAIN_L, //b2 + LINEAR_VTS_H, //0x41 (frame length) + LINEAR_VTS_L,//0x42 + LINEAR_REGS_NUM +}; + + +typedef enum _GC2053_SLAVE_MODE_E { + GC2053_SLAVE_MODE_1920X1080P30 = 0, + GC2053_SLAVE_MODE_NUM +} GC2053_SLAVE_MODE_E; + +typedef struct _GC2053_SLAVE_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC2053_SLAVE_STATE_S; + +typedef struct _GC2053_SLAVE_MODE_S { + ISP_WDR_SIZE_S stImg; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp; + SNS_ATTR_LARGE_S stAgain; + SNS_ATTR_LARGE_S stDgain; + char name[64]; +} GC2053_SLAVE_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc2053_Slave[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc2053_Slave_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2053_Slave_MirrorFip[VI_MAX_PIPE_NUM]; +extern CVI_U8 gc2053_slave_i2c_addr; +extern const CVI_U32 gc2053_slave_addr_byte; +extern const CVI_U32 gc2053_slave_data_byte; +extern void gc2053_slave_init(VI_PIPE ViPipe); +extern void gc2053_slave_exit(VI_PIPE ViPipe); +extern void gc2053_slave_standby(VI_PIPE ViPipe); +extern void gc2053_slave_restart(VI_PIPE ViPipe); +extern int gc2053_slave_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc2053_slave_read_register(VI_PIPE ViPipe, int addr); +extern void gc2053_slave_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int gc2053_slave_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2053_SLAVE_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_slave/gc2053_slave_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_slave/gc2053_slave_cmos_param.h new file mode 100644 index 000000000..983eac40e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_slave/gc2053_slave_cmos_param.h @@ -0,0 +1,219 @@ +#ifndef __GC2053_CMOS_PARAM_H_ +#define __GC2053_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2053_slave_cmos_ex.h" + +static const GC2053_SLAVE_MODE_S g_stGc2053_Slave_mode = { + .name = "1920X1080P30", + .stImg = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.07, /* 1125 * 30 / 0x3FFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp = { + .u16Min = 1, + .u16Max = 0x3fff, + .u16Def = 0x2000, + .u16Step = 1, + }, + .stAgain = { + .u32Min = 64, + .u32Max = 62977, + .u32Def = 64, + .u32Step = 1, + }, + .stDgain = { + .u32Min = 64*16, + .u32Max = 7073*16, + .u32Def = 581*16, + .u32Step = 10*16, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.05999477580189704895, 0.13019448518753051758}, //B: slope, intercept + {0.06732148677110671997, -1.36387133598327636719}, //Gb: slope, intercept + {0.06651904433965682983, -1.10093510150909423828}, //Gr: slope, intercept + {0.06406146287918090820, 0.33316791057586669922}, //R: slope, intercept + }, + { //iso 200 + {0.06256803125143051147, 4.54908418655395507813}, //B: slope, intercept + {0.06911934912204742432, 2.79023528099060058594}, //Gb: slope, intercept + {0.06846688687801361084, 2.88726186752319335938}, //Gr: slope, intercept + {0.06652788817882537842, 4.40276956558227539063}, //R: slope, intercept + }, + { //iso 400 + {0.06841833144426345825, 11.72280883789062500000}, //B: slope, intercept + {0.07257881015539169312, 10.86985683441162109375}, //Gb: slope, intercept + {0.07174283266067504883, 11.20646286010742187500}, //Gr: slope, intercept + {0.07294593751430511475, 11.17350578308105468750}, //R: slope, intercept + }, + { //iso 800 + {0.07805790752172470093, 20.62956619262695312500}, //B: slope, intercept + {0.07694032043218612671, 22.20356750488281250000}, //Gb: slope, intercept + {0.07647507637739181519, 22.50957298278808593750}, //Gr: slope, intercept + {0.08402533829212188721, 19.11953735351562500000}, //R: slope, intercept + }, + { //iso 1600 + {0.09468275308609008789, 34.07563018798828125000}, //B: slope, intercept + {0.08710632473230361938, 39.15500259399414062500}, //Gb: slope, intercept + {0.08662072569131851196, 39.37175750732421875000}, //Gr: slope, intercept + {0.10222808271646499634, 31.34789276123046875000}, //R: slope, intercept + }, + { //iso 3200 + {0.12651191651821136475, 49.56183242797851562500}, //B: slope, intercept + {0.10816962271928787231, 59.42719650268554687500}, //Gb: slope, intercept + {0.10751257836818695068, 59.90552902221679687500}, //Gr: slope, intercept + {0.13802853226661682129, 45.09576034545898437500}, //R: slope, intercept + }, + { //iso 6400 + {0.17422541975975036621, 70.04063415527343750000}, //B: slope, intercept + {0.14234761893749237061, 85.51583862304687500000}, //Gb: slope, intercept + {0.14159946143627166748, 86.23278045654296875000}, //Gr: slope, intercept + {0.19450971484184265137, 62.65447235107421875000}, //R: slope, intercept + }, + { //iso 12800 + {0.24947367608547210693, 108.30633544921875000000}, //B: slope, intercept + {0.19751225411891937256, 130.88159179687500000000}, //Gb: slope, intercept + {0.19614629447460174561, 132.49082946777343750000}, //Gr: slope, intercept + {0.28106108307838439941, 97.15969085693359375000}, //R: slope, intercept + }, + { //iso 25600 + {0.35420843958854675293, 137.06745910644531250000}, //B: slope, intercept + {0.27778801321983337402, 168.72366333007812500000}, //Gb: slope, intercept + {0.27540388703346252441, 170.54939270019531250000}, //Gr: slope, intercept + {0.39949953556060791016, 123.29409790039062500000}, //R: slope, intercept + }, + { //iso 51200 + {0.45704349875450134277, 179.20147705078125000000}, //B: slope, intercept + {0.32142028212547302246, 246.71363830566406250000}, //Gb: slope, intercept + {0.31958609819412231445, 246.82630920410156250000}, //Gr: slope, intercept + {0.51058447360992431641, 161.86299133300781250000}, //R: slope, intercept + }, + { //iso 102400 + {0.61760461330413818359, 222.90534973144531250000}, //B: slope, intercept + {0.42568457126617431641, 319.29257202148437500000}, //Gb: slope, intercept + {0.41750904917716979980, 324.93432617187500000000}, //Gr: slope, intercept + {0.67956107854843139648, 203.78948974609375000000}, //R: slope, intercept + }, + { //iso 204800 + {0.63289469480514526367, 216.99952697753906250000}, //B: slope, intercept + {0.44890350103378295898, 306.80810546875000000000}, //Gb: slope, intercept + {0.44229975342750549316, 310.13763427734375000000}, //Gr: slope, intercept + {0.69596910476684570313, 196.70443725585937500000}, //R: slope, intercept + }, + { //iso 409600 + {0.71106964349746704102, 187.98352050781250000000}, //B: slope, intercept + {0.55859673023223876953, 246.22378540039062500000}, //Gb: slope, intercept + {0.55284017324447631836, 249.86463928222656250000}, //Gr: slope, intercept + {0.77318203449249267578, 168.85035705566406250000}, //R: slope, intercept + }, + { //iso 819200 + {0.70888006687164306641, 188.44216918945312500000}, //B: slope, intercept + {0.56110274791717529297, 245.46603393554687500000}, //Gb: slope, intercept + {0.55100852251052856445, 250.33049011230468750000}, //Gr: slope, intercept + {0.76897650957107543945, 169.31251525878906250000}, //R: slope, intercept + }, + { //iso 1638400 + {0.70520979166030883789, 188.93899536132812500000}, //B: slope, intercept + {0.56178557872772216797, 245.21235656738281250000}, //Gb: slope, intercept + {0.55338454246520996094, 249.57423400878906250000}, //Gr: slope, intercept + {0.77306479215621948242, 168.86497497558593750000}, //R: slope, intercept + }, + { //iso 3276800 + {0.71255809068679809570, 187.86839294433593750000}, //B: slope, intercept + {0.56056070327758789063, 245.57748413085937500000}, //Gb: slope, intercept + {0.55358195304870605469, 249.62020874023437500000}, //Gr: slope, intercept + {0.77431541681289672852, 168.74313354492187500000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {257, 257, 257, 257, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {257, 257, 257, 257, 259, 259, 260, 267, 278, 298, 366, 383, 366, 373, 372, 372 }, + {257, 257, 257, 257, 258, 259, 261, 266, 274, 297, 379, 377, 372, 365, 373, 374 }, + {257, 257, 257, 257, 258, 259, 261, 266, 275, 296, 376, 388, 366, 374, 376, 372 }, + {257, 257, 257, 257, 258, 259, 260, 264, 274, 294, 362, 363, 365, 361, 353, 367 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1095, + 1099, 1104, 1125, 1130, 1125, 1127, 1126, 1126}, + {1093, 1093, 1093, 1093, 1093, 1093, 1094, 1095, + 1097, 1104, 1128, 1128, 1126, 1124, 1127, 1127}, + {1093, 1093, 1093, 1093, 1093, 1093, 1094, 1095, + 1098, 1104, 1128, 1131, 1125, 1127, 1128, 1126}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1095, + 1097, 1103, 1123, 1124, 1124, 1123, 1121, 1125}, +#endif + }, + }, +}; + +struct combo_dev_attr_s gc2053_slave_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {0, 4, 2, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 1, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2053_SLAVE_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_slave/gc2053_slave_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_slave/gc2053_slave_sensor_ctl.c new file mode 100644 index 000000000..520515021 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2053_slave/gc2053_slave_sensor_ctl.c @@ -0,0 +1,395 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2053_slave_cmos_ex.h" + +#define GC2053_SLAVE_CHIP_ID_ADDR_H 0xf0 +#define GC2053_SLAVE_CHIP_ID_ADDR_L 0xf1 +#define GC2053_SLAVE_CHIP_ID 0x2053 + +static void gc2053_slave_linear_1080p30_init(VI_PIPE ViPipe); + +CVI_U8 gc2053_slave_i2c_addr = 0x37;//0x6e +const CVI_U32 gc2053_slave_addr_byte = 1; +const CVI_U32 gc2053_slave_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc2053_slave_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc2053_Slave_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc2053_slave_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc2053_slave_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc2053_slave_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (gc2053_slave_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc2053_slave_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, gc2053_slave_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc2053_slave_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int gc2053_slave_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc2053_slave_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (gc2053_slave_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc2053_slave_addr_byte + gc2053_slave_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + //syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void gc2053_slave_standby(VI_PIPE ViPipe) +{ + gc2053_slave_write_register(ViPipe, 0x3e, 0x00); + gc2053_slave_write_register(ViPipe, 0xf7, 0x00); + gc2053_slave_write_register(ViPipe, 0xfc, 0x01); + gc2053_slave_write_register(ViPipe, 0xf9, 0x83); + + printf("gc2053_standby\n"); +} + +void gc2053_slave_restart(VI_PIPE ViPipe) +{ + gc2053_slave_write_register(ViPipe, 0xf9, 0x82); + delay_ms(2); + gc2053_slave_write_register(ViPipe, 0xf7, 0x01); + gc2053_slave_write_register(ViPipe, 0xfc, 0x8e); + gc2053_slave_write_register(ViPipe, 0x3e, 0x91); + + printf("gc2053_restart\n"); +} + +void gc2053_slave_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc2053_Slave[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc2053_slave_write_register(ViPipe, + g_pastGc2053_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc2053_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} +void gc2053_slave_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 value = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + value = 0x01; + break; + case ISP_SNS_FLIP: + value = 0x02; + break; + case ISP_SNS_MIRROR_FLIP: + value = 0x03; + break; + default: + return; + } + gc2053_slave_write_register(ViPipe, 0xfe, 0x00); + gc2053_slave_write_register(ViPipe, 0x17, value); +} + +int gc2053_slave_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc2053_slave_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc2053_slave_read_register(ViPipe, GC2053_SLAVE_CHIP_ID_ADDR_H); + nVal2 = gc2053_slave_read_register(ViPipe, GC2053_SLAVE_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC2053_SLAVE_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc2053_slave_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode = g_pastGc2053_Slave[ViPipe]->enWDRMode; + + gc2053_slave_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n"); + } else { + gc2053_slave_linear_1080p30_init(ViPipe); + } + g_pastGc2053_Slave[ViPipe]->bInit = CVI_TRUE; +} + +void gc2053_slave_exit(VI_PIPE ViPipe) +{ + gc2053_slave_i2c_exit(ViPipe); +} + +static void gc2053_slave_linear_1080p30_init(VI_PIPE ViPipe) +{ + /****system****/ + gc2053_slave_write_register(ViPipe, 0xfe, 0x80); + gc2053_slave_write_register(ViPipe, 0xfe, 0x80); + gc2053_slave_write_register(ViPipe, 0xfe, 0x80); + gc2053_slave_write_register(ViPipe, 0xfe, 0x00); + gc2053_slave_write_register(ViPipe, 0xf2, 0x00); + gc2053_slave_write_register(ViPipe, 0xf3, 0x00); + gc2053_slave_write_register(ViPipe, 0xf4, 0x36); + gc2053_slave_write_register(ViPipe, 0xf5, 0xc0); + gc2053_slave_write_register(ViPipe, 0xf6, 0x44); + gc2053_slave_write_register(ViPipe, 0xf7, 0x01); + gc2053_slave_write_register(ViPipe, 0xf8, 0x2c); + gc2053_slave_write_register(ViPipe, 0xf9, 0x42); + gc2053_slave_write_register(ViPipe, 0xfc, 0x8e); + /****CISCTL & ANALOG****/ + gc2053_slave_write_register(ViPipe, 0xfe, 0x00); + gc2053_slave_write_register(ViPipe, 0x87, 0x18); + gc2053_slave_write_register(ViPipe, 0xee, 0x30); + gc2053_slave_write_register(ViPipe, 0xd0, 0xb7); + gc2053_slave_write_register(ViPipe, 0x03, 0x04); + gc2053_slave_write_register(ViPipe, 0x04, 0x60); + gc2053_slave_write_register(ViPipe, 0x05, 0x04); + gc2053_slave_write_register(ViPipe, 0x06, 0x4c); + gc2053_slave_write_register(ViPipe, 0x07, 0x00); + gc2053_slave_write_register(ViPipe, 0x08, 0x11); + gc2053_slave_write_register(ViPipe, 0x09, 0x00); + gc2053_slave_write_register(ViPipe, 0x0a, 0x02); + gc2053_slave_write_register(ViPipe, 0x0b, 0x00); + gc2053_slave_write_register(ViPipe, 0x0c, 0x02); + gc2053_slave_write_register(ViPipe, 0x0d, 0x04); + gc2053_slave_write_register(ViPipe, 0x0e, 0x40); + gc2053_slave_write_register(ViPipe, 0x12, 0xe2); + gc2053_slave_write_register(ViPipe, 0x13, 0x16); + gc2053_slave_write_register(ViPipe, 0x19, 0x0a); + gc2053_slave_write_register(ViPipe, 0x21, 0x1c); + gc2053_slave_write_register(ViPipe, 0x28, 0x0a); + gc2053_slave_write_register(ViPipe, 0x29, 0x24); + gc2053_slave_write_register(ViPipe, 0x2b, 0x04); + gc2053_slave_write_register(ViPipe, 0x32, 0xf8); + gc2053_slave_write_register(ViPipe, 0x37, 0x03); + gc2053_slave_write_register(ViPipe, 0x39, 0x15); + gc2053_slave_write_register(ViPipe, 0x41, 0x04); + gc2053_slave_write_register(ViPipe, 0x42, 0x65); + gc2053_slave_write_register(ViPipe, 0x43, 0x07); + gc2053_slave_write_register(ViPipe, 0x44, 0x40); + gc2053_slave_write_register(ViPipe, 0x46, 0x0b); + gc2053_slave_write_register(ViPipe, 0x4b, 0x20); + gc2053_slave_write_register(ViPipe, 0x4e, 0x08); + gc2053_slave_write_register(ViPipe, 0x55, 0x20); + gc2053_slave_write_register(ViPipe, 0x66, 0x05); + gc2053_slave_write_register(ViPipe, 0x67, 0x05); + gc2053_slave_write_register(ViPipe, 0x77, 0x01); + gc2053_slave_write_register(ViPipe, 0x78, 0x00); + gc2053_slave_write_register(ViPipe, 0x7c, 0x93); + gc2053_slave_write_register(ViPipe, 0x8c, 0x12); + gc2053_slave_write_register(ViPipe, 0x8d, 0x92); + gc2053_slave_write_register(ViPipe, 0x90, 0x00); + gc2053_slave_write_register(ViPipe, 0x9d, 0x10); + gc2053_slave_write_register(ViPipe, 0xce, 0x7c); + gc2053_slave_write_register(ViPipe, 0xd2, 0x41); + gc2053_slave_write_register(ViPipe, 0xd3, 0xdc); + gc2053_slave_write_register(ViPipe, 0xe6, 0x50); + /*gain*/ + gc2053_slave_write_register(ViPipe, 0xb6, 0xc0); + gc2053_slave_write_register(ViPipe, 0xb0, 0x70); + gc2053_slave_write_register(ViPipe, 0xb1, 0x01); + gc2053_slave_write_register(ViPipe, 0xb2, 0x00); + gc2053_slave_write_register(ViPipe, 0xb3, 0x00); + gc2053_slave_write_register(ViPipe, 0xb4, 0x00); + gc2053_slave_write_register(ViPipe, 0xb8, 0x01); + gc2053_slave_write_register(ViPipe, 0xb9, 0x00); + /*blk*/ + gc2053_slave_write_register(ViPipe, 0x26, 0x30); + gc2053_slave_write_register(ViPipe, 0xfe, 0x01); + gc2053_slave_write_register(ViPipe, 0x40, 0x23); + gc2053_slave_write_register(ViPipe, 0x55, 0x07); + gc2053_slave_write_register(ViPipe, 0x60, 0x40); + gc2053_slave_write_register(ViPipe, 0xfe, 0x04); + gc2053_slave_write_register(ViPipe, 0x14, 0x78); + gc2053_slave_write_register(ViPipe, 0x15, 0x78); + gc2053_slave_write_register(ViPipe, 0x16, 0x78); + gc2053_slave_write_register(ViPipe, 0x17, 0x78); + /*window*/ + gc2053_slave_write_register(ViPipe, 0xfe, 0x01); + gc2053_slave_write_register(ViPipe, 0x91, 0x00); + gc2053_slave_write_register(ViPipe, 0x92, 0x00); + gc2053_slave_write_register(ViPipe, 0x93, 0x00); + gc2053_slave_write_register(ViPipe, 0x94, 0x03); + gc2053_slave_write_register(ViPipe, 0x95, 0x04); + gc2053_slave_write_register(ViPipe, 0x96, 0x38); + gc2053_slave_write_register(ViPipe, 0x97, 0x07); + gc2053_slave_write_register(ViPipe, 0x98, 0x80); + /*ISP*/ + gc2053_slave_write_register(ViPipe, 0xfe, 0x01); + gc2053_slave_write_register(ViPipe, 0x01, 0x05); + gc2053_slave_write_register(ViPipe, 0x02, 0x89); + gc2053_slave_write_register(ViPipe, 0x04, 0x01); + gc2053_slave_write_register(ViPipe, 0x07, 0xa6); + gc2053_slave_write_register(ViPipe, 0x08, 0xa9); + gc2053_slave_write_register(ViPipe, 0x09, 0xa8); + gc2053_slave_write_register(ViPipe, 0x0a, 0xa7); + gc2053_slave_write_register(ViPipe, 0x0b, 0xff); + gc2053_slave_write_register(ViPipe, 0x0c, 0xff); + gc2053_slave_write_register(ViPipe, 0x0f, 0x00); + gc2053_slave_write_register(ViPipe, 0x50, 0x1c); + gc2053_slave_write_register(ViPipe, 0x89, 0x03); + gc2053_slave_write_register(ViPipe, 0xfe, 0x04); + gc2053_slave_write_register(ViPipe, 0x28, 0x86); + gc2053_slave_write_register(ViPipe, 0x29, 0x86); + gc2053_slave_write_register(ViPipe, 0x2a, 0x86); + gc2053_slave_write_register(ViPipe, 0x2b, 0x68); + gc2053_slave_write_register(ViPipe, 0x2c, 0x68); + gc2053_slave_write_register(ViPipe, 0x2d, 0x68); + gc2053_slave_write_register(ViPipe, 0x2e, 0x68); + gc2053_slave_write_register(ViPipe, 0x2f, 0x68); + gc2053_slave_write_register(ViPipe, 0x30, 0x4f); + gc2053_slave_write_register(ViPipe, 0x31, 0x68); + gc2053_slave_write_register(ViPipe, 0x32, 0x67); + gc2053_slave_write_register(ViPipe, 0x33, 0x66); + gc2053_slave_write_register(ViPipe, 0x34, 0x66); + gc2053_slave_write_register(ViPipe, 0x35, 0x66); + gc2053_slave_write_register(ViPipe, 0x36, 0x66); + gc2053_slave_write_register(ViPipe, 0x37, 0x66); + gc2053_slave_write_register(ViPipe, 0x38, 0x62); + gc2053_slave_write_register(ViPipe, 0x39, 0x62); + gc2053_slave_write_register(ViPipe, 0x3a, 0x62); + gc2053_slave_write_register(ViPipe, 0x3b, 0x62); + gc2053_slave_write_register(ViPipe, 0x3c, 0x62); + gc2053_slave_write_register(ViPipe, 0x3d, 0x62); + gc2053_slave_write_register(ViPipe, 0x3e, 0x62); + gc2053_slave_write_register(ViPipe, 0x3f, 0x62); + /****DVP & MIPI****/ + gc2053_slave_write_register(ViPipe, 0xfe, 0x01); + gc2053_slave_write_register(ViPipe, 0x9a, 0x06); + gc2053_slave_write_register(ViPipe, 0xfe, 0x00); + gc2053_slave_write_register(ViPipe, 0x7b, 0x2a); + gc2053_slave_write_register(ViPipe, 0x23, 0x2d); + gc2053_slave_write_register(ViPipe, 0xfe, 0x03); + gc2053_slave_write_register(ViPipe, 0x01, 0x27); + gc2053_slave_write_register(ViPipe, 0x02, 0x56); + gc2053_slave_write_register(ViPipe, 0x03, 0x8e); + gc2053_slave_write_register(ViPipe, 0x12, 0x80); + gc2053_slave_write_register(ViPipe, 0x13, 0x07); + gc2053_slave_write_register(ViPipe, 0x15, 0x12); + gc2053_slave_write_register(ViPipe, 0xfe, 0x00); + gc2053_slave_write_register(ViPipe, 0x3e, 0x91); + + gc2053_slave_default_reg_init(ViPipe); + printf("ViPipe:%d,===GC2053 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2093/Makefile b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2093/Makefile new file mode 100644 index 000000000..a6b89d54e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2093/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc2093.a +TARGET_SO = $(MW_LIB)/libsns_gc2093.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2093/gc2093_cmos.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2093/gc2093_cmos.c new file mode 100644 index 000000000..14b24233b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2093/gc2093_cmos.c @@ -0,0 +1,1193 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "gc2093_cmos_ex.h" +#include "gc2093_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define GC2093_ID 2093 +/**************************************************************************** + * global variables * + ***************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc2093[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC2093_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc2093[dev]) +#define GC2093_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc2093[dev] = pstCtx) +#define GC2093_SENSOR_RESET_CTX(dev) (g_pastGc2093[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc2093_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2093_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16Gc2093_GainMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ***************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Gc2093 Lines Range*****/ +#define GC2093_FULL_LINES_MAX (0x3fff) + +/*****Gc2093 Register Address*****/ +#define GC2093_EXP_H_ADDR 0x0003 +#define GC2093_EXP_L_ADDR 0x0004 +#define GC2093_SEXP_H_ADDR 0x0001 +#define GC2093_SEXP_L_ADDR 0x0002 + +#define GC2093_AGAIN_H_ADDR 0x00b4 +#define GC2093_AGAIN_L_ADDR 0x00b3 +#define GC2093_COL_AGAIN_H_ADDR 0x00b8 +#define GC2093_COL_AGAIN_L_ADDR 0x00b9 +#define GC2093_AGAIN_MAG1 0x0155 +#define GC2093_AGAIN_HOLD 0x031d +#define GC2093_AGAIN_MAG2 0x00c2 +#define GC2093_AGAIN_MAG3 0x00cf +#define GC2093_AGAIN_MAG4 0x00d9 + +#define GC2093_DGAIN_H_ADDR 0x00b1 +#define GC2093_DGAIN_L_ADDR 0x00b2 +#define GC2093_VTS_H_ADDR 0x0041 //(frame length) +#define GC2093_VTS_L_ADDR 0x0042 + +#define GC2093_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC2093_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astGc2093_mode[GC2093_MODE_1920X1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astGc2093_mode[GC2093_MODE_1920X1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 74976; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 10240; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? + g_au32InitExposure[ViPipe] : g_astGc2093_mode[GC2093_MODE_1920X1080P30].stExp[0].u16Def; + + pstAeSnsDft->u32MaxIntTime = g_astGc2093_mode[GC2093_MODE_1920X1080P30].stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = g_astGc2093_mode[GC2093_MODE_1920X1080P30].stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astGc2093_mode[GC2093_MODE_1920X1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astGc2093_mode[GC2093_MODE_1920X1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 3; + pstAeSnsDft->u32MinIntTime = 1; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 74976; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 10240; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astGc2093_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astGc2093_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astGc2093_mode[pstSnsState->u8ImgMode].f32MinFps; + + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + + u32VMAX = (u32VMAX > GC2093_FULL_LINES_MAX) ? GC2093_FULL_LINES_MAX : u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF); + } else { + pstSnsRegsInfo->astI2cData[WDR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR_VTS_L].u32Data = (u32VMAX & 0xFF); + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + CVI_U16 u16Sexp, u16Lexp; + CVI_U32 u32MaxRangeLExp, u32MaxRangeSExp; + + /* + *exp_shortau32FL[0] - 1088 - 20 - 1 - 8; + pstSnsState->au32WDRIntTime[0] = (u32ShortIntTime <= u32MaxRangeSExp) ? + u32ShortIntTime : u32MaxRangeSExp; + if (!pstSnsState->au32WDRIntTime[0]) + pstSnsState->au32WDRIntTime[0] = 1; + u16Sexp = (CVI_U16)pstSnsState->au32WDRIntTime[0]; + + u32MaxRangeLExp = pstSnsState->au32FL[0] - u16Sexp; + pstSnsState->au32WDRIntTime[1] = (u32LongIntTime <= u32MaxRangeLExp) ? + u32LongIntTime : u32MaxRangeLExp; + if (!pstSnsState->au32WDRIntTime[1]) + pstSnsState->au32WDRIntTime[1] = 1; + u16Lexp = (CVI_U16)pstSnsState->au32WDRIntTime[1]; + + pstSnsRegsInfo->astI2cData[WDR_LEXP_H].u32Data = ((u16Lexp >> 8) & 0x3F); + pstSnsRegsInfo->astI2cData[WDR_LEXP_L].u32Data = (u16Lexp & 0xFF); + + pstSnsRegsInfo->astI2cData[WDR_SEXP_H].u32Data = ((u16Sexp >> 8) & 0x3F); + pstSnsRegsInfo->astI2cData[WDR_SEXP_L].u32Data = (u16Sexp & 0xFF); + + //Fixed blooming problem that would occur in highlighted environments + //sync solution from gc simon + if (u16Sexp < 0x4) + gc2093_write_register(ViPipe, 0x0032, 0xfd); + else + gc2093_write_register(ViPipe, 0x0032, 0xf8); + } else { + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = ((u32IntTime[0] >> 8) & 0x3F); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF); + } + + return CVI_SUCCESS; +} + +static CVI_U32 regValTable[25][7] = { + //0xb3 0xb8 0xb9 0x155 0xc2 0xcf 0xd9 + {0x00, 0x01, 0x00, 0x08, 0x10, 0x08, 0x0a}, + {0x10, 0x01, 0x0c, 0x08, 0x10, 0x08, 0x0a}, + {0x20, 0x01, 0x1b, 0x08, 0x11, 0x08, 0x0c}, + {0x30, 0x01, 0x2c, 0x08, 0x12, 0x08, 0x0e}, + {0x40, 0x01, 0x3f, 0x08, 0x14, 0x08, 0x12}, + {0x50, 0x02, 0x16, 0x08, 0x15, 0x08, 0x14}, + {0x60, 0x02, 0x35, 0x08, 0x17, 0x08, 0x18}, + {0x70, 0x03, 0x16, 0x08, 0x18, 0x08, 0x1a}, + {0x80, 0x04, 0x02, 0x08, 0x1a, 0x08, 0x1e}, + {0x90, 0x04, 0x31, 0x08, 0x1b, 0x08, 0x20}, + {0xa0, 0x05, 0x32, 0x08, 0x1d, 0x08, 0x24}, + {0xb0, 0x06, 0x35, 0x08, 0x1e, 0x08, 0x26}, + {0xc0, 0x08, 0x04, 0x08, 0x20, 0x08, 0x2a}, + {0x5a, 0x09, 0x19, 0x08, 0x1e, 0x08, 0x2a}, + {0x83, 0x0b, 0x0f, 0x08, 0x1f, 0x08, 0x2a}, + {0x93, 0x0d, 0x12, 0x08, 0x21, 0x08, 0x2e}, + {0x84, 0x10, 0x00, 0x0b, 0x22, 0x08, 0x30}, + {0x94, 0x12, 0x3a, 0x0b, 0x24, 0x08, 0x34}, + {0x5d, 0x1a, 0x02, 0x0b, 0x26, 0x08, 0x34}, + {0x9b, 0x1b, 0x20, 0x0b, 0x26, 0x08, 0x34}, + {0x8c, 0x20, 0x0f, 0x0b, 0x26, 0x08, 0x34}, + {0x9c, 0x26, 0x07, 0x12, 0x26, 0x08, 0x34}, + {0xB6, 0x36, 0x21, 0x12, 0x26, 0x08, 0x34}, + {0xad, 0x37, 0x3a, 0x12, 0x26, 0x08, 0x34}, + {0xbd, 0x3d, 0x02, 0x12, 0x26, 0x08, 0x34}, +}; + +static CVI_U32 regValTable_WDR[25][7] = { + //0xb3 0xb8 0xb9 0x155 0xc2 0xcf 0xd9 + {0x00, 0x01, 0x00, 0x08, 0x10, 0x08, 0x0a}, + {0x10, 0x01, 0x0c, 0x08, 0x10, 0x08, 0x0a}, + {0x20, 0x01, 0x1b, 0x08, 0x11, 0x08, 0x0c}, + {0x30, 0x01, 0x2c, 0x08, 0x12, 0x08, 0x0e}, + {0x40, 0x01, 0x3f, 0x08, 0x14, 0x08, 0x12}, + {0x50, 0x02, 0x16, 0x08, 0x15, 0x08, 0x14}, + {0x60, 0x02, 0x35, 0x08, 0x17, 0x08, 0x18}, + {0x70, 0x03, 0x16, 0x08, 0x18, 0x08, 0x1a}, + {0x80, 0x04, 0x02, 0x08, 0x1a, 0x08, 0x1e}, + {0x90, 0x04, 0x31, 0x08, 0x1b, 0x08, 0x20}, + {0xa0, 0x05, 0x32, 0x08, 0x1d, 0x08, 0x24}, + {0xb0, 0x06, 0x35, 0x08, 0x1e, 0x08, 0x26}, + {0xc0, 0x08, 0x04, 0x08, 0x20, 0x08, 0x2a}, + {0x5a, 0x09, 0x19, 0x08, 0x1e, 0x08, 0x2a}, + {0x83, 0x0b, 0x0f, 0x08, 0x1f, 0x08, 0x2a}, + {0x93, 0x0d, 0x12, 0x08, 0x21, 0x08, 0x2e}, + {0x84, 0x10, 0x00, 0x0b, 0x22, 0x08, 0x30}, + {0x94, 0x12, 0x3a, 0x0b, 0x24, 0x08, 0x34}, + {0x5d, 0x1a, 0x02, 0x0b, 0x26, 0x08, 0x34}, + {0x9b, 0x1b, 0x20, 0x0b, 0x26, 0x08, 0x34}, + {0x8c, 0x20, 0x0f, 0x0b, 0x26, 0x08, 0x34}, + {0x9c, 0x26, 0x07, 0x12, 0x26, 0x08, 0x34}, + {0xB6, 0x36, 0x21, 0x12, 0x26, 0x08, 0x34}, + {0xad, 0x37, 0x3a, 0x12, 0x26, 0x08, 0x34}, + {0xbd, 0x3d, 0x02, 0x12, 0x26, 0x08, 0x34}, +}; + +static CVI_U32 gain_table[25] = { + 1024, 1216, 1456, 1712, 2000, 2352, 2832, 3376, 3968, 4752, 5696, 6800, 8064, + 9584, 11344, 13376, 15648, 18448, 26352, 26416, 30960, 36672, 51824, 63344, 74976, +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i, total; + CVI_U32 pregain; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + UNUSED(ViPipe); + total = sizeof(gain_table) / sizeof(CVI_U32); + + if (*pu32AgainLin >= gain_table[total - 1]) { + *pu32AgainLin = *pu32AgainDb = gain_table[total - 1]; + return CVI_SUCCESS; + } + + for (i = 1; i < total; i++) { + if (*pu32AgainLin < gain_table[i]) + break; + } + i--; + // find the pregain + pregain = *pu32AgainLin * 64 / gain_table[i]; + // set the Db as the AE algo gain, we need this to do gain update + *pu32AgainDb = *pu32AgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32AgainLin = pregain * gain_table[i] / 64; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 pregain; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + UNUSED(ViPipe); + // find the pregain + pregain = *pu32DgainLin * 64 / 1024; + // set the Db as the AE algo gain, we need this to do gain update + *pu32DgainDb = *pu32DgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32DgainLin = pregain * 16; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + int i, total; + + total = sizeof(gain_table) / sizeof(CVI_U32); + + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* only surpport linear mode */ + u32Again = pu32Again[0]; + /* To kepp the linearity. we assume AE algo adjusts the dgain only when the again reachs the maximum value */ + if (u32Again < (74976)) { + for (i = 1; i < total; i++) { + if (*pu32Again < gain_table[i]) + break; + } + i--; + // find the pregain + u32Dgain = u32Again * 64 / gain_table[i]; + u32Again = i; + } else { + u32Again = total - 1; + // find the pregain + u32Dgain = pu32Dgain[0] * 64 / 1024; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][0]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][1]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][2]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG1].u32Data = regValTable[u32Again][3]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_HOLD].u32Data = 0X2D; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG2].u32Data = regValTable[u32Again][4]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG3].u32Data = regValTable[u32Again][5]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG4].u32Data = regValTable[u32Again][6]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REL].u32Data = 0X28; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 6); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2; + } else { + pstSnsRegsInfo->astI2cData[WDR_AGAIN_L].u32Data = regValTable_WDR[u32Again][0]; + pstSnsRegsInfo->astI2cData[WDR_COL_AGAIN_H].u32Data = regValTable_WDR[u32Again][1]; + pstSnsRegsInfo->astI2cData[WDR_COL_AGAIN_L].u32Data = regValTable_WDR[u32Again][2]; + pstSnsRegsInfo->astI2cData[WDR_AGAIN_MAG1].u32Data = regValTable_WDR[u32Again][3]; + pstSnsRegsInfo->astI2cData[WDR_AGAIN_HOLD].u32Data = 0X2D; + pstSnsRegsInfo->astI2cData[WDR_AGAIN_MAG2].u32Data = regValTable_WDR[u32Again][4]; + pstSnsRegsInfo->astI2cData[WDR_AGAIN_MAG3].u32Data = regValTable_WDR[u32Again][5]; + pstSnsRegsInfo->astI2cData[WDR_AGAIN_MAG4].u32Data = regValTable_WDR[u32Again][6]; + pstSnsRegsInfo->astI2cData[WDR_AGAIN_HOLD].u32Data = 0X28; + + pstSnsRegsInfo->astI2cData[WDR_DGAIN_H].u32Data = (u32Dgain >> 6); + pstSnsRegsInfo->astI2cData[WDR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2; + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 1; + CVI_U32 u32ShortTimeMaxLimit = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + /* + *exp_shortau32FL[1] - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + /*expect new max sexp*/ + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 1) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32ShortTimeMaxLimit = pstSnsState->au32FL[0] - 1088 - 20 - 1 - 8; + /*real new max sexp*/ + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + /*we need to make sure sexp <= frame length-window_height-20 -1*/ + u32IntTimeMaxTmp = (u32IntTimeMaxTmp <= u32ShortTimeMaxLimit) ? u32IntTimeMaxTmp : u32ShortTimeMaxLimit; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + CVI_TRACE_SNS(CVI_DBG_DEBUG, "sexp[%d, %d], lexp[%d, %d], ratio:%d\n", + au32IntTimeMin[0], au32IntTimeMax[0], + au32IntTimeMin[1], au32IntTimeMax[1], au32Ratio[0]); + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio is too large!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + UNUSED(ViPipe); + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + UNUSED(ViPipe); + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + CMOS_CHECK_POINTER(pstBlc); + UNUSED(ViPipe); + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC2093_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astGc2093_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == GC2093_MODE_1920X1080P30_WDR) + pstSnsState->u8ImgMode = GC2093_MODE_1920X1080P30; + + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astGc2093_mode[pstSnsState->u8ImgMode].u32VtsDef; + //syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == GC2093_MODE_1920X1080P30) + pstSnsState->u8ImgMode = GC2093_MODE_1920X1080P30_WDR; + + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astGc2093_mode[pstSnsState->u8ImgMode].u32VtsDef; + //syslog(LOG_INFO, "2to1 line WDR 1080p mode(60fps->30fps)\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunGc2093_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = gc2093_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc2093_addr_byte; + pstI2c_data[i].u32DataByteNum = gc2093_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + //WDR Mode Regs + + pstI2c_data[WDR_LEXP_H].u32RegAddr = GC2093_EXP_H_ADDR; + pstI2c_data[WDR_LEXP_L].u32RegAddr = GC2093_EXP_L_ADDR; + pstI2c_data[WDR_SEXP_H].u32RegAddr = GC2093_SEXP_H_ADDR; + pstI2c_data[WDR_SEXP_L].u32RegAddr = GC2093_SEXP_L_ADDR; + pstI2c_data[WDR_AGAIN_L].u32RegAddr = GC2093_AGAIN_L_ADDR; + pstI2c_data[WDR_COL_AGAIN_H].u32RegAddr = GC2093_COL_AGAIN_H_ADDR; + pstI2c_data[WDR_COL_AGAIN_L].u32RegAddr = GC2093_COL_AGAIN_L_ADDR; + pstI2c_data[WDR_AGAIN_MAG1].u32RegAddr = GC2093_AGAIN_MAG1; + pstI2c_data[WDR_AGAIN_HOLD].u32RegAddr = GC2093_AGAIN_HOLD; + pstI2c_data[WDR_AGAIN_MAG2].u32RegAddr = GC2093_AGAIN_MAG2; + pstI2c_data[WDR_AGAIN_MAG3].u32RegAddr = GC2093_AGAIN_MAG3; + pstI2c_data[WDR_AGAIN_MAG4].u32RegAddr = GC2093_AGAIN_MAG4; + pstI2c_data[WDR_AGAIN_REL].u32RegAddr = GC2093_AGAIN_HOLD; + pstI2c_data[WDR_DGAIN_H].u32RegAddr = GC2093_DGAIN_H_ADDR; + pstI2c_data[WDR_DGAIN_L].u32RegAddr = GC2093_DGAIN_L_ADDR; + pstI2c_data[WDR_VTS_H].u32RegAddr = GC2093_VTS_H_ADDR; + pstI2c_data[WDR_VTS_H].u8DelayFrmNum = 1; + pstI2c_data[WDR_VTS_L].u32RegAddr = GC2093_VTS_L_ADDR; + pstI2c_data[WDR_VTS_L].u8DelayFrmNum = 1; + break; + default: + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC2093_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC2093_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC2093_AGAIN_L_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC2093_COL_AGAIN_H_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC2093_COL_AGAIN_L_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG1].u32RegAddr = GC2093_AGAIN_MAG1; + pstI2c_data[LINEAR_AGAIN_HOLD].u32RegAddr = GC2093_AGAIN_HOLD; + pstI2c_data[LINEAR_AGAIN_MAG2].u32RegAddr = GC2093_AGAIN_MAG2; + pstI2c_data[LINEAR_AGAIN_MAG3].u32RegAddr = GC2093_AGAIN_MAG3; + pstI2c_data[LINEAR_AGAIN_MAG4].u32RegAddr = GC2093_AGAIN_MAG4; + pstI2c_data[LINEAR_AGAIN_REL].u32RegAddr = GC2093_AGAIN_HOLD; + pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC2093_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC2093_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC2093_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_H].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC2093_VTS_L_ADDR; + pstI2c_data[LINEAR_VTS_L].u8DelayFrmNum = 1; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + + CVI_U32 gainsUpdate = 0; + + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((i >= LINEAR_AGAIN_L) && (i <= LINEAR_DGAIN_L)) + gainsUpdate = 1; + } else { + if ((i >= WDR_AGAIN_L) && (i <= WDR_DGAIN_L)) + gainsUpdate = 1; + } + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (gainsUpdate) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG1].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_HOLD].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG2].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG3].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG4].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_REL].bUpdate = CVI_TRUE; + + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L].bUpdate = CVI_TRUE; + } else { + pstCfg0->snsCfg.astI2cData[WDR_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[WDR_COL_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[WDR_COL_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[WDR_AGAIN_MAG1].bUpdate = CVI_TRUE; + + pstCfg0->snsCfg.astI2cData[WDR_AGAIN_HOLD].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[WDR_AGAIN_MAG2].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[WDR_AGAIN_MAG3].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[WDR_AGAIN_MAG4].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[WDR_AGAIN_REL].bUpdate = CVI_TRUE; + + pstCfg0->snsCfg.astI2cData[WDR_DGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[WDR_DGAIN_L].bUpdate = CVI_TRUE; + } + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC2093_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC2093_MODE_1920X1080P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (GC2093_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = GC2093_MODE_1920X1080P30_WDR; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc2093_MirrorFip[ViPipe] != eSnsMirrorFlip) { + gc2093_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeGc2093_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC2093_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astGc2093_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astGc2093_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astGc2093_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2093_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc2093_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astGc2093_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astGc2093_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc2093_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc2093_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc2093_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 gc2093_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc2093_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2093_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC2093_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2093_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC2093_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC2093_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC2093_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC2093_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC2093_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Gc2093_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc2093_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc2093_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc2093_standby, + .pfnRestart = gc2093_restart, + .pfnWriteReg = gc2093_write_register, + .pfnReadReg = gc2093_read_register, + .pfnSetBusInfo = gc2093_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2093/gc2093_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2093/gc2093_cmos_ex.h new file mode 100644 index 000000000..d0f8c9869 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2093/gc2093_cmos_ex.h @@ -0,0 +1,116 @@ +#ifndef __GC2093_CMOS_EX_H_ +#define __GC2093_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum gc2093_linear_regs_e { + LINEAR_EXP_H = 0, //03 + LINEAR_EXP_L, //04 + LINEAR_AGAIN_L, //b3 + LINEAR_COL_AGAIN_H, //b8 + LINEAR_COL_AGAIN_L, //b9 + LINEAR_AGAIN_MAG1, //0x155 + LINEAR_AGAIN_HOLD, //0x031d + LINEAR_AGAIN_MAG2, //0xc2 + LINEAR_AGAIN_MAG3, //0xcf + LINEAR_AGAIN_MAG4, //0xd9 + LINEAR_AGAIN_REL, //0x031d + LINEAR_DGAIN_H, //b1 + LINEAR_DGAIN_L, //b2 + LINEAR_VTS_H, //0x41 (frame length) + LINEAR_VTS_L, //0x42 + LINEAR_REGS_NUM +}; + +enum gc2093_wdr_regs_e { + WDR_SEXP_H = 0, //01 + WDR_SEXP_L, //02 + WDR_LEXP_H, //03 + WDR_LEXP_L, //04 + WDR_AGAIN_L, //b3 + WDR_COL_AGAIN_H, //b8 + WDR_COL_AGAIN_L, //b9 + WDR_AGAIN_MAG1, //0x155 + WDR_AGAIN_HOLD, //0x031d + WDR_AGAIN_MAG2, //0xc2 + WDR_AGAIN_MAG3, //0xcf + WDR_AGAIN_MAG4, //0xd9 + WDR_AGAIN_REL, //0x031d + WDR_DGAIN_H, //b1 + WDR_DGAIN_L, //b2 + WDR_VTS_H, //0x41 (frame length) + WDR_VTS_L, //0x42 + WDR_REGS_NUM +}; + + +typedef enum _GC2093_MODE_E { + GC2093_MODE_1920X1080P30 = 0, + GC2093_MODE_LINEAR_NUM, + GC2093_MODE_1920X1080P30_WDR = GC2093_MODE_LINEAR_NUM, + GC2093_MODE_NUM +} GC2093_MODE_E; + +typedef struct _GC2093_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC2093_STATE_S; + +typedef struct _GC2093_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} GC2093_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc2093[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc2093_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2093_MirrorFip[VI_MAX_PIPE_NUM]; +extern const CVI_U8 gc2093_i2c_addr; +extern const CVI_U32 gc2093_addr_byte; +extern const CVI_U32 gc2093_data_byte; +extern void gc2093_init(VI_PIPE ViPipe); +extern void gc2093_exit(VI_PIPE ViPipe); +extern void gc2093_standby(VI_PIPE ViPipe); +extern void gc2093_restart(VI_PIPE ViPipe); +extern int gc2093_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc2093_read_register(VI_PIPE ViPipe, int addr); +extern void gc2093_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int gc2093_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2093_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2093/gc2093_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2093/gc2093_cmos_param.h new file mode 100644 index 000000000..6166d549f --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2093/gc2093_cmos_param.h @@ -0,0 +1,287 @@ +#ifndef __GC2093_CMOS_PARAM_H_ +#define __GC2093_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2093_cmos_ex.h" + +static const GC2093_MODE_S g_astGc2093_mode[GC2093_MODE_NUM] = { + [GC2093_MODE_1920X1080P30] = { + .name = "1920X1080P30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.07, /* 1125 * 30 / 0x3FFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 0x3fff, + .u16Def = 0x2000, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 64, + .u32Max = 62977, + .u32Def = 64, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 64*16, + .u32Max = 7073*16, + .u32Def = 581*16, + .u32Step = 10*16, + }, + }, + [GC2093_MODE_1920X1080P30_WDR] = { + .name = "1920X1080P30_WDR", + .astImg[0] = { + /* sef */ + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .astImg[1] = { + /* lef */ + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.29, /* 1250 * 30 / 0x3FFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1250, + .stAgain[0] = { + .u32Min = 64, + .u32Max = 62977, + .u32Def = 64, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 64, + .u32Max = 62977, + .u32Def = 64, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 64*16, + .u32Max = 7073*16, + .u32Def = 581*16, + .u32Step = 10*16, + }, + .stDgain[1] = { + .u32Min = 64*16, + .u32Max = 7073*16, + .u32Def = 581*16, + .u32Step = 10*16, + }, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.05999477580189704895, 0.13019448518753051758}, //B: slope, intercept + {0.06732148677110671997, -1.36387133598327636719}, //Gb: slope, intercept + {0.06651904433965682983, -1.10093510150909423828}, //Gr: slope, intercept + {0.06406146287918090820, 0.33316791057586669922}, //R: slope, intercept + }, + { //iso 200 + {0.06256803125143051147, 4.54908418655395507813}, //B: slope, intercept + {0.06911934912204742432, 2.79023528099060058594}, //Gb: slope, intercept + {0.06846688687801361084, 2.88726186752319335938}, //Gr: slope, intercept + {0.06652788817882537842, 4.40276956558227539063}, //R: slope, intercept + }, + { //iso 400 + {0.06841833144426345825, 11.72280883789062500000}, //B: slope, intercept + {0.07257881015539169312, 10.86985683441162109375}, //Gb: slope, intercept + {0.07174283266067504883, 11.20646286010742187500}, //Gr: slope, intercept + {0.07294593751430511475, 11.17350578308105468750}, //R: slope, intercept + }, + { //iso 800 + {0.07805790752172470093, 20.62956619262695312500}, //B: slope, intercept + {0.07694032043218612671, 22.20356750488281250000}, //Gb: slope, intercept + {0.07647507637739181519, 22.50957298278808593750}, //Gr: slope, intercept + {0.08402533829212188721, 19.11953735351562500000}, //R: slope, intercept + }, + { //iso 1600 + {0.09468275308609008789, 34.07563018798828125000}, //B: slope, intercept + {0.08710632473230361938, 39.15500259399414062500}, //Gb: slope, intercept + {0.08662072569131851196, 39.37175750732421875000}, //Gr: slope, intercept + {0.10222808271646499634, 31.34789276123046875000}, //R: slope, intercept + }, + { //iso 3200 + {0.12651191651821136475, 49.56183242797851562500}, //B: slope, intercept + {0.10816962271928787231, 59.42719650268554687500}, //Gb: slope, intercept + {0.10751257836818695068, 59.90552902221679687500}, //Gr: slope, intercept + {0.13802853226661682129, 45.09576034545898437500}, //R: slope, intercept + }, + { //iso 6400 + {0.17422541975975036621, 70.04063415527343750000}, //B: slope, intercept + {0.14234761893749237061, 85.51583862304687500000}, //Gb: slope, intercept + {0.14159946143627166748, 86.23278045654296875000}, //Gr: slope, intercept + {0.19450971484184265137, 62.65447235107421875000}, //R: slope, intercept + }, + { //iso 12800 + {0.24947367608547210693, 108.30633544921875000000}, //B: slope, intercept + {0.19751225411891937256, 130.88159179687500000000}, //Gb: slope, intercept + {0.19614629447460174561, 132.49082946777343750000}, //Gr: slope, intercept + {0.28106108307838439941, 97.15969085693359375000}, //R: slope, intercept + }, + { //iso 25600 + {0.35420843958854675293, 137.06745910644531250000}, //B: slope, intercept + {0.27778801321983337402, 168.72366333007812500000}, //Gb: slope, intercept + {0.27540388703346252441, 170.54939270019531250000}, //Gr: slope, intercept + {0.39949953556060791016, 123.29409790039062500000}, //R: slope, intercept + }, + { //iso 51200 + {0.45704349875450134277, 179.20147705078125000000}, //B: slope, intercept + {0.32142028212547302246, 246.71363830566406250000}, //Gb: slope, intercept + {0.31958609819412231445, 246.82630920410156250000}, //Gr: slope, intercept + {0.51058447360992431641, 161.86299133300781250000}, //R: slope, intercept + }, + { //iso 102400 + {0.61760461330413818359, 222.90534973144531250000}, //B: slope, intercept + {0.42568457126617431641, 319.29257202148437500000}, //Gb: slope, intercept + {0.41750904917716979980, 324.93432617187500000000}, //Gr: slope, intercept + {0.67956107854843139648, 203.78948974609375000000}, //R: slope, intercept + }, + { //iso 204800 + {0.63289469480514526367, 216.99952697753906250000}, //B: slope, intercept + {0.44890350103378295898, 306.80810546875000000000}, //Gb: slope, intercept + {0.44229975342750549316, 310.13763427734375000000}, //Gr: slope, intercept + {0.69596910476684570313, 196.70443725585937500000}, //R: slope, intercept + }, + { //iso 409600 + {0.71106964349746704102, 187.98352050781250000000}, //B: slope, intercept + {0.55859673023223876953, 246.22378540039062500000}, //Gb: slope, intercept + {0.55284017324447631836, 249.86463928222656250000}, //Gr: slope, intercept + {0.77318203449249267578, 168.85035705566406250000}, //R: slope, intercept + }, + { //iso 819200 + {0.70888006687164306641, 188.44216918945312500000}, //B: slope, intercept + {0.56110274791717529297, 245.46603393554687500000}, //Gb: slope, intercept + {0.55100852251052856445, 250.33049011230468750000}, //Gr: slope, intercept + {0.76897650957107543945, 169.31251525878906250000}, //R: slope, intercept + }, + { //iso 1638400 + {0.70520979166030883789, 188.93899536132812500000}, //B: slope, intercept + {0.56178557872772216797, 245.21235656738281250000}, //Gb: slope, intercept + {0.55338454246520996094, 249.57423400878906250000}, //Gr: slope, intercept + {0.77306479215621948242, 168.86497497558593750000}, //R: slope, intercept + }, + { //iso 3276800 + {0.71255809068679809570, 187.86839294433593750000}, //B: slope, intercept + {0.56056070327758789063, 245.57748413085937500000}, //Gb: slope, intercept + {0.55358195304870605469, 249.62020874023437500000}, //Gr: slope, intercept + {0.77431541681289672852, 168.74313354492187500000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {256, 257, 257, 257, 259, 259, 260, 267, 278, 298, 366, 383, 366, 373, 372, 372 }, + {256, 257, 257, 257, 258, 259, 261, 266, 274, 297, 379, 377, 372, 365, 373, 374 }, + {256, 257, 257, 257, 258, 259, 261, 266, 275, 296, 376, 388, 366, 374, 376, 372 }, + {256, 257, 257, 257, 258, 259, 260, 264, 274, 294, 362, 363, 365, 361, 353, 367 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1093, 1093, 1093, 1093, 1093, 1093, 1095, 1099, 1104, 1125, 1130, 1125, 1127, + 1126, 1126}, + {1092, 1093, 1093, 1093, 1093, 1093, 1094, 1095, 1097, 1104, 1128, 1128, 1126, 1124, + 1127, 1127}, + {1092, 1093, 1093, 1093, 1093, 1093, 1094, 1095, 1098, 1104, 1128, 1131, 1125, 1127, + 1128, 1126}, + {1092, 1093, 1093, 1093, 1093, 1093, 1093, 1095, 1097, 1103, 1123, 1124, 1124, 1123, + 1121, 1125}, +#endif + }, + }, +}; + +struct combo_dev_attr_s gc2093_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {1, 0, 2, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2093_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2093/gc2093_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2093/gc2093_sensor_ctl.c new file mode 100644 index 000000000..c8ce2cfa2 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2093/gc2093_sensor_ctl.c @@ -0,0 +1,562 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2093_cmos_ex.h" + +static void gc2093_linear_1080p30_init(VI_PIPE ViPipe); +static void gc2093_wdr_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 gc2093_i2c_addr = 0x37;//0x6e +const CVI_U32 gc2093_addr_byte = 2; +const CVI_U32 gc2093_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc2093_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc2093_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc2093_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc2093_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc2093_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (gc2093_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc2093_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, gc2093_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc2093_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int gc2093_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc2093_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + if (gc2093_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc2093_addr_byte + gc2093_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + ret = read(g_fd[ViPipe], buf, gc2093_addr_byte + gc2093_data_byte); + //syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void gc2093_standby(VI_PIPE ViPipe) +{ + gc2093_write_register(ViPipe, 0x003e, 0x00); + gc2093_write_register(ViPipe, 0x03f7, 0x00); + gc2093_write_register(ViPipe, 0x03fc, 0x01); + gc2093_write_register(ViPipe, 0x03f9, 0x41); + + printf("gc2093_standby\n"); +} + +void gc2093_restart(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastGc2093[ViPipe]->enWDRMode; + u8ImgMode = g_pastGc2093[ViPipe]->u8ImgMode; + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == GC2093_MODE_1920X1080P30_WDR) { + gc2093_write_register(ViPipe, 0x03f9, 0x40); + usleep(1); + gc2093_write_register(ViPipe, 0x03f7, 0x01); + gc2093_write_register(ViPipe, 0x03fc, 0x8e); + gc2093_write_register(ViPipe, 0x003e, 0x91); + } + } else { + gc2093_write_register(ViPipe, 0x03f9, 0x42); + usleep(1); + gc2093_write_register(ViPipe, 0x03f7, 0x11); + gc2093_write_register(ViPipe, 0x03fc, 0x8e); + gc2093_write_register(ViPipe, 0x003e, 0x91); + } + + printf("gc2093_restart\n"); +} + +void gc2093_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc2093[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc2093_write_register(ViPipe, + g_pastGc2093[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc2093[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define GC2093_CHIP_ID_ADDR_H 0x03f0 +#define GC2093_CHIP_ID_ADDR_L 0x03f1 +#define GC2093_CHIP_ID 0x2093 + +void gc2093_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 value = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + value = 0x01; + break; + case ISP_SNS_FLIP: + value = 0x02; + break; + case ISP_SNS_MIRROR_FLIP: + value = 0x03; + break; + default: + return; + } + gc2093_write_register(ViPipe, 0xfe, 0x00); + gc2093_write_register(ViPipe, 0x17, value); +} + +int gc2093_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc2093_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc2093_read_register(ViPipe, GC2093_CHIP_ID_ADDR_H); + nVal2 = gc2093_read_register(ViPipe, GC2093_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC2093_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc2093_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastGc2093[ViPipe]->enWDRMode; + u8ImgMode = g_pastGc2093[ViPipe]->u8ImgMode; + + gc2093_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == GC2093_MODE_1920X1080P30_WDR) { + gc2093_wdr_1080p30_init(ViPipe); + } + } else { + gc2093_linear_1080p30_init(ViPipe); + } + + + g_pastGc2093[ViPipe]->bInit = CVI_TRUE; +} + +void gc2093_exit(VI_PIPE ViPipe) +{ + gc2093_i2c_exit(ViPipe); +} + +static void gc2093_linear_1080p30_init(VI_PIPE ViPipe) +{ + delay_ms(10); + /****system****/ + gc2093_write_register(ViPipe, 0x03fe, 0xf0); + gc2093_write_register(ViPipe, 0x03fe, 0xf0); + gc2093_write_register(ViPipe, 0x03fe, 0xf0); + gc2093_write_register(ViPipe, 0x03fe, 0x00); + gc2093_write_register(ViPipe, 0x03f2, 0x00); + gc2093_write_register(ViPipe, 0x03f3, 0x00); + gc2093_write_register(ViPipe, 0x03f4, 0x36); + gc2093_write_register(ViPipe, 0x03f5, 0xc0); + gc2093_write_register(ViPipe, 0x03f6, 0x0B); + gc2093_write_register(ViPipe, 0x03f7, 0x11); + gc2093_write_register(ViPipe, 0x03f8, 0x2A); + gc2093_write_register(ViPipe, 0x03f9, 0x42); + gc2093_write_register(ViPipe, 0x03fc, 0x8e); + /****CISCTL & ANALOG*/ + gc2093_write_register(ViPipe, 0x0087, 0x18); + gc2093_write_register(ViPipe, 0x00ee, 0x30); + gc2093_write_register(ViPipe, 0x00d0, 0xbf); + gc2093_write_register(ViPipe, 0x01a0, 0x00); + gc2093_write_register(ViPipe, 0x01a4, 0x40); + gc2093_write_register(ViPipe, 0x01a5, 0x40); + gc2093_write_register(ViPipe, 0x01a6, 0x40); + gc2093_write_register(ViPipe, 0x01af, 0x09); + gc2093_write_register(ViPipe, 0x0003, 0x04); + gc2093_write_register(ViPipe, 0x0004, 0x65); + gc2093_write_register(ViPipe, 0x0005, 0x05); + gc2093_write_register(ViPipe, 0x0006, 0x78); + gc2093_write_register(ViPipe, 0x0007, 0x00); + gc2093_write_register(ViPipe, 0x0008, 0x11); + gc2093_write_register(ViPipe, 0x0009, 0x00); + gc2093_write_register(ViPipe, 0x000a, 0x02); + gc2093_write_register(ViPipe, 0x000b, 0x00); + gc2093_write_register(ViPipe, 0x000c, 0x04); + gc2093_write_register(ViPipe, 0x000d, 0x04); + gc2093_write_register(ViPipe, 0x000e, 0x40); + gc2093_write_register(ViPipe, 0x000f, 0x07); + gc2093_write_register(ViPipe, 0x0010, 0x8c); + gc2093_write_register(ViPipe, 0x0013, 0x15); + gc2093_write_register(ViPipe, 0x0019, 0x0c); + gc2093_write_register(ViPipe, 0x0041, 0x04); + gc2093_write_register(ViPipe, 0x0042, 0x65); + gc2093_write_register(ViPipe, 0x0053, 0x60); + gc2093_write_register(ViPipe, 0x008d, 0x92); + gc2093_write_register(ViPipe, 0x0090, 0x00); + gc2093_write_register(ViPipe, 0x00c7, 0xe1); + gc2093_write_register(ViPipe, 0x001b, 0x73); + gc2093_write_register(ViPipe, 0x0028, 0x0d); + gc2093_write_register(ViPipe, 0x0029, 0x40); + gc2093_write_register(ViPipe, 0x002b, 0x04); + gc2093_write_register(ViPipe, 0x002e, 0x23); + gc2093_write_register(ViPipe, 0x0037, 0x03); + gc2093_write_register(ViPipe, 0x0043, 0x04); + gc2093_write_register(ViPipe, 0x0044, 0x30); + gc2093_write_register(ViPipe, 0x004a, 0x01); + gc2093_write_register(ViPipe, 0x004b, 0x28); + gc2093_write_register(ViPipe, 0x0055, 0x30); + gc2093_write_register(ViPipe, 0x0066, 0x3f); + gc2093_write_register(ViPipe, 0x0068, 0x3f); + gc2093_write_register(ViPipe, 0x006b, 0x44); + gc2093_write_register(ViPipe, 0x0077, 0x00); + gc2093_write_register(ViPipe, 0x0078, 0x20); + gc2093_write_register(ViPipe, 0x007c, 0xa1); + gc2093_write_register(ViPipe, 0x00ce, 0x7c); + gc2093_write_register(ViPipe, 0x00d3, 0xd4); + gc2093_write_register(ViPipe, 0x00e6, 0x50); + /*gain*/ + gc2093_write_register(ViPipe, 0x00b6, 0xc0); + gc2093_write_register(ViPipe, 0x00b0, 0x68); + gc2093_write_register(ViPipe, 0x00b3, 0x00); + gc2093_write_register(ViPipe, 0x00b8, 0x01); + gc2093_write_register(ViPipe, 0x00b9, 0x00); + gc2093_write_register(ViPipe, 0x00b1, 0x01); + gc2093_write_register(ViPipe, 0x00b2, 0x00); + /*isp*/ + gc2093_write_register(ViPipe, 0x0101, 0x0c); + gc2093_write_register(ViPipe, 0x0102, 0x89); + gc2093_write_register(ViPipe, 0x0104, 0x01); + gc2093_write_register(ViPipe, 0x0107, 0xa6); + gc2093_write_register(ViPipe, 0x0108, 0xa9); + gc2093_write_register(ViPipe, 0x0109, 0xa8); + gc2093_write_register(ViPipe, 0x010a, 0xa7); + gc2093_write_register(ViPipe, 0x010b, 0xff); + gc2093_write_register(ViPipe, 0x010c, 0xff); + gc2093_write_register(ViPipe, 0x010f, 0x00); + gc2093_write_register(ViPipe, 0x0158, 0x00); + gc2093_write_register(ViPipe, 0x0428, 0x86); + gc2093_write_register(ViPipe, 0x0429, 0x86); + gc2093_write_register(ViPipe, 0x042a, 0x86); + gc2093_write_register(ViPipe, 0x042b, 0x68); + gc2093_write_register(ViPipe, 0x042c, 0x68); + gc2093_write_register(ViPipe, 0x042d, 0x68); + gc2093_write_register(ViPipe, 0x042e, 0x68); + gc2093_write_register(ViPipe, 0x042f, 0x68); + gc2093_write_register(ViPipe, 0x0430, 0x4f); + gc2093_write_register(ViPipe, 0x0431, 0x68); + gc2093_write_register(ViPipe, 0x0432, 0x67); + gc2093_write_register(ViPipe, 0x0433, 0x66); + gc2093_write_register(ViPipe, 0x0434, 0x66); + gc2093_write_register(ViPipe, 0x0435, 0x66); + gc2093_write_register(ViPipe, 0x0436, 0x66); + gc2093_write_register(ViPipe, 0x0437, 0x66); + gc2093_write_register(ViPipe, 0x0438, 0x62); + gc2093_write_register(ViPipe, 0x0439, 0x62); + gc2093_write_register(ViPipe, 0x043a, 0x62); + gc2093_write_register(ViPipe, 0x043b, 0x62); + gc2093_write_register(ViPipe, 0x043c, 0x62); + gc2093_write_register(ViPipe, 0x043d, 0x62); + gc2093_write_register(ViPipe, 0x043e, 0x62); + gc2093_write_register(ViPipe, 0x043f, 0x62); + /*dark sun*/ + gc2093_write_register(ViPipe, 0x0123, 0x08); + gc2093_write_register(ViPipe, 0x0123, 0x00); + gc2093_write_register(ViPipe, 0x0120, 0x01); + gc2093_write_register(ViPipe, 0x0121, 0x04); + gc2093_write_register(ViPipe, 0x0122, 0x65); + gc2093_write_register(ViPipe, 0x0124, 0x03); + gc2093_write_register(ViPipe, 0x0125, 0xff); + gc2093_write_register(ViPipe, 0x001a, 0x8c); + gc2093_write_register(ViPipe, 0x00c6, 0xe0); + /*blk*/ + gc2093_write_register(ViPipe, 0x0026, 0x30); + gc2093_write_register(ViPipe, 0x0142, 0x00); + gc2093_write_register(ViPipe, 0x0149, 0x1e); + gc2093_write_register(ViPipe, 0x014a, 0x0f); + gc2093_write_register(ViPipe, 0x014b, 0x00); + gc2093_write_register(ViPipe, 0x0155, 0x07); + gc2093_write_register(ViPipe, 0x0414, 0x78); + gc2093_write_register(ViPipe, 0x0415, 0x78); + gc2093_write_register(ViPipe, 0x0416, 0x78); + gc2093_write_register(ViPipe, 0x0417, 0x78); + gc2093_write_register(ViPipe, 0x04e0, 0x18); + /*window*/ + gc2093_write_register(ViPipe, 0x0192, 0x02); + gc2093_write_register(ViPipe, 0x0194, 0x03); + gc2093_write_register(ViPipe, 0x0195, 0x04); + gc2093_write_register(ViPipe, 0x0196, 0x38); + gc2093_write_register(ViPipe, 0x0197, 0x07); + gc2093_write_register(ViPipe, 0x0198, 0x80); + /****DVP & MIPI****/ + gc2093_write_register(ViPipe, 0x019a, 0x06); + gc2093_write_register(ViPipe, 0x007b, 0x2a); + gc2093_write_register(ViPipe, 0x0023, 0x2d); + gc2093_write_register(ViPipe, 0x0201, 0x27); + gc2093_write_register(ViPipe, 0x0202, 0x56); + gc2093_write_register(ViPipe, 0x0203, 0xb6); + gc2093_write_register(ViPipe, 0x0212, 0x80); + gc2093_write_register(ViPipe, 0x0213, 0x07); + gc2093_write_register(ViPipe, 0x0215, 0x10); + gc2093_write_register(ViPipe, 0x003e, 0x91); + + gc2093_default_reg_init(ViPipe); + delay_ms(80); + + printf("ViPipe:%d,===GC2093 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +static void gc2093_wdr_1080p30_init(VI_PIPE ViPipe) +{ + delay_ms(10); + /****system**/ + gc2093_write_register(ViPipe, 0x03fe, 0xf0); + gc2093_write_register(ViPipe, 0x03fe, 0xf0); + gc2093_write_register(ViPipe, 0x03fe, 0xf0); + gc2093_write_register(ViPipe, 0x03fe, 0x00); + gc2093_write_register(ViPipe, 0x03f2, 0x00); + gc2093_write_register(ViPipe, 0x03f3, 0x00); + gc2093_write_register(ViPipe, 0x03f4, 0x36); + gc2093_write_register(ViPipe, 0x03f5, 0xc0); + gc2093_write_register(ViPipe, 0x03f6, 0x0B); + gc2093_write_register(ViPipe, 0x03f7, 0x01); + gc2093_write_register(ViPipe, 0x03f8, 0x58); + gc2093_write_register(ViPipe, 0x03f9, 0x40); + gc2093_write_register(ViPipe, 0x03fc, 0x8e); + /****CISCTL**/ + gc2093_write_register(ViPipe, 0x0087, 0x18); + gc2093_write_register(ViPipe, 0x00ee, 0x30); + gc2093_write_register(ViPipe, 0x00d0, 0xbf); + gc2093_write_register(ViPipe, 0x01a0, 0x00); + gc2093_write_register(ViPipe, 0x01a4, 0x40); + gc2093_write_register(ViPipe, 0x01a5, 0x40); + gc2093_write_register(ViPipe, 0x01a6, 0x40); + gc2093_write_register(ViPipe, 0x01af, 0x09); + gc2093_write_register(ViPipe, 0x0001, 0x00); + gc2093_write_register(ViPipe, 0x0002, 0x02); + gc2093_write_register(ViPipe, 0x0003, 0x04); + gc2093_write_register(ViPipe, 0x0004, 0x02); + gc2093_write_register(ViPipe, 0x0005, 0x02); + gc2093_write_register(ViPipe, 0x0006, 0x94); + gc2093_write_register(ViPipe, 0x0007, 0x00); + gc2093_write_register(ViPipe, 0x0008, 0x11); + gc2093_write_register(ViPipe, 0x0009, 0x00); + gc2093_write_register(ViPipe, 0x000a, 0x02); + gc2093_write_register(ViPipe, 0x000b, 0x00); + gc2093_write_register(ViPipe, 0x000c, 0x04); + gc2093_write_register(ViPipe, 0x000d, 0x04); + gc2093_write_register(ViPipe, 0x000e, 0x40); + gc2093_write_register(ViPipe, 0x000f, 0x07); + gc2093_write_register(ViPipe, 0x0010, 0x8c); + gc2093_write_register(ViPipe, 0x0013, 0x15); + gc2093_write_register(ViPipe, 0x0019, 0x0c); + gc2093_write_register(ViPipe, 0x0041, 0x04); + gc2093_write_register(ViPipe, 0x0042, 0xE2); + gc2093_write_register(ViPipe, 0x0053, 0x60); + gc2093_write_register(ViPipe, 0x008d, 0x92); + gc2093_write_register(ViPipe, 0x0090, 0x00); + gc2093_write_register(ViPipe, 0x00c7, 0xe1); + gc2093_write_register(ViPipe, 0x001b, 0x73); + gc2093_write_register(ViPipe, 0x0028, 0x0d); + gc2093_write_register(ViPipe, 0x0029, 0x24); + gc2093_write_register(ViPipe, 0x002b, 0x04); + gc2093_write_register(ViPipe, 0x002e, 0x23); + gc2093_write_register(ViPipe, 0x0037, 0x03); + gc2093_write_register(ViPipe, 0x0043, 0x04); + gc2093_write_register(ViPipe, 0x0044, 0x28); + gc2093_write_register(ViPipe, 0x004a, 0x01); + gc2093_write_register(ViPipe, 0x004b, 0x20); + gc2093_write_register(ViPipe, 0x0055, 0x28); + gc2093_write_register(ViPipe, 0x0066, 0x3f); + gc2093_write_register(ViPipe, 0x0068, 0x3f); + gc2093_write_register(ViPipe, 0x006b, 0x44); + gc2093_write_register(ViPipe, 0x0077, 0x00); + gc2093_write_register(ViPipe, 0x0078, 0x20); + gc2093_write_register(ViPipe, 0x007c, 0xa1); + gc2093_write_register(ViPipe, 0x00ce, 0x7c); + gc2093_write_register(ViPipe, 0x00d3, 0xd4); + gc2093_write_register(ViPipe, 0x00e6, 0x50); + /*gain*/ + gc2093_write_register(ViPipe, 0x00b6, 0xc0); + gc2093_write_register(ViPipe, 0x00b0, 0x68); + /*isp*/ + gc2093_write_register(ViPipe, 0x0101, 0x0c); + gc2093_write_register(ViPipe, 0x0102, 0x89); + gc2093_write_register(ViPipe, 0x0104, 0x01); + gc2093_write_register(ViPipe, 0x010e, 0x01); + gc2093_write_register(ViPipe, 0x010f, 0x00); + gc2093_write_register(ViPipe, 0x0158, 0x00); + /*dark sun*/ + gc2093_write_register(ViPipe, 0x0123, 0x08); + gc2093_write_register(ViPipe, 0x0123, 0x00); + gc2093_write_register(ViPipe, 0x0120, 0x01); + gc2093_write_register(ViPipe, 0x0121, 0x04); + gc2093_write_register(ViPipe, 0x0122, 0xd8); + gc2093_write_register(ViPipe, 0x0124, 0x03); + gc2093_write_register(ViPipe, 0x0125, 0xff); + gc2093_write_register(ViPipe, 0x001a, 0x8c); + gc2093_write_register(ViPipe, 0x00c6, 0xe0); + /*blk*/ + gc2093_write_register(ViPipe, 0x0026, 0x30); + gc2093_write_register(ViPipe, 0x0142, 0x00); + gc2093_write_register(ViPipe, 0x0149, 0x1e); + gc2093_write_register(ViPipe, 0x014a, 0x0f); + gc2093_write_register(ViPipe, 0x014b, 0x00); + gc2093_write_register(ViPipe, 0x0155, 0x07); + gc2093_write_register(ViPipe, 0x0414, 0x78); + gc2093_write_register(ViPipe, 0x0415, 0x78); + gc2093_write_register(ViPipe, 0x0416, 0x78); + gc2093_write_register(ViPipe, 0x0417, 0x78); + gc2093_write_register(ViPipe, 0x0454, 0x78); + gc2093_write_register(ViPipe, 0x0455, 0x78); + gc2093_write_register(ViPipe, 0x0456, 0x78); + gc2093_write_register(ViPipe, 0x0457, 0x78); + gc2093_write_register(ViPipe, 0x04e0, 0x18); + /*window*/ + gc2093_write_register(ViPipe, 0x0192, 0x02); + gc2093_write_register(ViPipe, 0x0194, 0x03); + gc2093_write_register(ViPipe, 0x0195, 0x04); + gc2093_write_register(ViPipe, 0x0196, 0x38); + gc2093_write_register(ViPipe, 0x0197, 0x07); + gc2093_write_register(ViPipe, 0x0198, 0x80); + /****DVP**/ + gc2093_write_register(ViPipe, 0x019a, 0x06); + gc2093_write_register(ViPipe, 0x007b, 0x2a); + gc2093_write_register(ViPipe, 0x0023, 0x2d); + gc2093_write_register(ViPipe, 0x0201, 0x27); + gc2093_write_register(ViPipe, 0x0202, 0x56); + gc2093_write_register(ViPipe, 0x0203, 0xb6); + gc2093_write_register(ViPipe, 0x0212, 0x80); + gc2093_write_register(ViPipe, 0x0213, 0x07); + gc2093_write_register(ViPipe, 0x0215, 0x10); + gc2093_write_register(ViPipe, 0x003e, 0x91); + /****HDR EN**/ + gc2093_write_register(ViPipe, 0x0027, 0x71); + gc2093_write_register(ViPipe, 0x0215, 0x92); + gc2093_write_register(ViPipe, 0x024d, 0x01); + gc2093_default_reg_init(ViPipe); + delay_ms(80); + + printf("ViPipe:%d,===GC2093 1080P 30fps 10bit LINE WDR2TO1 OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2145/Makefile b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2145/Makefile new file mode 100644 index 000000000..ba45cb01b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2145/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc2145.a +TARGET_SO = $(MW_LIB)/libsns_gc2145.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2145/gc2145_cmos.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2145/gc2145_cmos.c new file mode 100644 index 000000000..ae1f61ced --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2145/gc2145_cmos.c @@ -0,0 +1,305 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "gc2145_cmos_ex.h" +#include "gc2145_cmos_param.h" + +#define GC2145_ID 0x2145 +#define GC2145_I2C_ADDR_1 0x3f +#define GC2145_I2C_ADDR_2 0x37 +#define GC2145_I2C_ADDR_IS_VALID(addr) ((addr) == GC2145_I2C_ADDR_1 || (addr) == GC2145_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc2145[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC2145_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc2145[dev]) +#define GC2145_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc2145[dev] = pstCtx) +#define GC2145_SENSOR_RESET_CTX(dev) (g_pastGc2145[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc2145_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +#define GC2145_RES_IS_1200P(w, h) ((w) == 1600 && (h) == 1200) + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC2145_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2145_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astGc2145_mode; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->stImg, sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC2145_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstCfg0 = &pstSnsState->astSyncInfo[0]; + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC2145_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 12) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC2145_RES_IS_1200P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC2145_MODE_1600X1200P12; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2145_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC2145_MODE_1600X1200P12; + pstSnsState->enWDRMode = WDR_MODE_NONE; +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2145_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc2145_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astGc2145_mode.stImg.stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astGc2145_mode.stImg.stSnsSize.u32Height; + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc2145_rx_attr; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc2145_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc2145_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (GC2145_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc2145_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc2145_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc2145_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2145_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC2145_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2145_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC2145_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + (void) pstAeLib; + (void) pstAwbLib; + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC2145_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + (void) pstAeLib; + (void) pstAwbLib; + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC2145_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc2145_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc2145_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = CVI_NULL, + .pfnRestart = CVI_NULL, + .pfnWriteReg = gc2145_write_register, + .pfnReadReg = gc2145_read_register, + .pfnSetBusInfo = gc2145_set_bus_info, + .pfnSetInit = CVI_NULL, + .pfnMirrorFlip = CVI_NULL, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = CVI_NULL, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2145/gc2145_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2145/gc2145_cmos_ex.h new file mode 100644 index 000000000..34bb36b24 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2145/gc2145_cmos_ex.h @@ -0,0 +1,64 @@ +#ifndef __GC2145_CMOS_EX_H_ +#define __GC2145_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +typedef enum _GC2145_MODE_E { + GC2145_MODE_1600X1200P12 = 0, + GC2145_MODE_NUM +} GC2145_SLAVE_MODE_E; + +typedef struct _GC2145_MODE_S { + ISP_WDR_SIZE_S stImg; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp; + SNS_ATTR_LARGE_S stAgain; + SNS_ATTR_LARGE_S stDgain; + char name[64]; +} GC2145_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc2145[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc2145_BusInfo[]; +extern CVI_U8 gc2145_i2c_addr; +extern const CVI_U32 gc2145_addr_byte; +extern const CVI_U32 gc2145_data_byte; +extern void gc2145_init(VI_PIPE ViPipe); +extern void gc2145_exit(VI_PIPE ViPipe); +extern void gc2145_standby(VI_PIPE ViPipe); +extern void gc2145_restart(VI_PIPE ViPipe); +extern int gc2145_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc2145_read_register(VI_PIPE ViPipe, int addr); +extern void gc2145_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int gc2145_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2145_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2145/gc2145_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2145/gc2145_cmos_param.h new file mode 100644 index 000000000..ab7c9caba --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2145/gc2145_cmos_param.h @@ -0,0 +1,72 @@ +#ifndef __GC2145_CMOS_PARAM_H_ +#define __GC2145_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2145_cmos_ex.h" + +static const GC2145_MODE_S g_astGc2145_mode = { + .name = "1600X1200P12", + .stImg = { + .stSnsSize = { + .u32Width = 1600, + .u32Height = 1200, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1600, + .u32Height = 1200, + }, + .stMaxSize = { + .u32Width = 1600, + .u32Height = 1200, + }, + }, +}; + +struct combo_dev_attr_s gc2145_rx_attr = { + .input_mode = INPUT_MODE_BT601, + .mac_clk = RX_MAC_CLK_400M, + .ttl_attr = { + .vi = TTL_VI_SRC_VI1, + .ttl_fmt = TTL_VSDE_11B, + .raw_data_type = RAW_DATA_8BIT, + .func = { + 8, -1, -1, 7, + 2, 3, 4, 5, + 6, 9, 10, 1, + -1, -1, -1, -1, + -1, -1, -1, -1, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2145_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2145/gc2145_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2145/gc2145_sensor_ctl.c new file mode 100644 index 000000000..20c98157b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2145/gc2145_sensor_ctl.c @@ -0,0 +1,875 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2145_cmos_ex.h" + +static void gc2145_linear_1200p12_init(VI_PIPE ViPipe); + +CVI_U8 gc2145_i2c_addr = 0x3C;//0x78 +const CVI_U32 gc2145_addr_byte = 1; +const CVI_U32 gc2145_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc2145_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc2145_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc2145_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc2145_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc2145_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (gc2145_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc2145_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, gc2145_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc2145_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int gc2145_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc2145_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (gc2145_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc2145_addr_byte + gc2145_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + //syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +#define GC2145_CHIP_ID_ADDR_H 0xf0 +#define GC2145_CHIP_ID_ADDR_L 0xf1 +#define GC2145_CHIP_ID 0x2145 + +int gc2145_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc2145_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc2145_read_register(ViPipe, GC2145_CHIP_ID_ADDR_H); + nVal2 = gc2145_read_register(ViPipe, GC2145_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC2145_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc2145_init(VI_PIPE ViPipe) +{ + gc2145_i2c_init(ViPipe); + + gc2145_linear_1200p12_init(ViPipe); + + g_pastGc2145[ViPipe]->bInit = CVI_TRUE; +} + +void gc2145_exit(VI_PIPE ViPipe) +{ + gc2145_i2c_exit(ViPipe); +} + +static void gc2145_linear_1200p12_init(VI_PIPE ViPipe) +{ + gc2145_write_register(ViPipe, 0xfe, 0xf0); + gc2145_write_register(ViPipe, 0xfe, 0xf0); + gc2145_write_register(ViPipe, 0xfe, 0xf0); + gc2145_write_register(ViPipe, 0xfc, 0x06); + gc2145_write_register(ViPipe, 0xf6, 0x00); + gc2145_write_register(ViPipe, 0xf7, 0x1d); + gc2145_write_register(ViPipe, 0xf8, 0x84); + gc2145_write_register(ViPipe, 0xfa, 0x00); + gc2145_write_register(ViPipe, 0xf9, 0xfe); + gc2145_write_register(ViPipe, 0xf2, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0x03, 0x04); + gc2145_write_register(ViPipe, 0x04, 0xe2); + gc2145_write_register(ViPipe, 0x09, 0x00); + gc2145_write_register(ViPipe, 0x0a, 0x00); + gc2145_write_register(ViPipe, 0x0b, 0x00); + gc2145_write_register(ViPipe, 0x0c, 0x00); + gc2145_write_register(ViPipe, 0x0d, 0x04); + gc2145_write_register(ViPipe, 0x0e, 0xc0); + gc2145_write_register(ViPipe, 0x0f, 0x06); + gc2145_write_register(ViPipe, 0x10, 0x52); + gc2145_write_register(ViPipe, 0x12, 0x2e); + gc2145_write_register(ViPipe, 0x17, 0x14); + gc2145_write_register(ViPipe, 0x18, 0x22); + gc2145_write_register(ViPipe, 0x19, 0x0e); + gc2145_write_register(ViPipe, 0x1a, 0x01); + gc2145_write_register(ViPipe, 0x1b, 0x4b); + gc2145_write_register(ViPipe, 0x1c, 0x07); + gc2145_write_register(ViPipe, 0x1d, 0x10); + gc2145_write_register(ViPipe, 0x1e, 0x88); + gc2145_write_register(ViPipe, 0x1f, 0x78); + gc2145_write_register(ViPipe, 0x20, 0x03); + gc2145_write_register(ViPipe, 0x21, 0x40); + gc2145_write_register(ViPipe, 0x22, 0xa0); + gc2145_write_register(ViPipe, 0x24, 0x16); + gc2145_write_register(ViPipe, 0x25, 0x01); + gc2145_write_register(ViPipe, 0x26, 0x10); + gc2145_write_register(ViPipe, 0x2d, 0x60); + gc2145_write_register(ViPipe, 0x30, 0x01); + gc2145_write_register(ViPipe, 0x31, 0x90); + gc2145_write_register(ViPipe, 0x33, 0x06); + gc2145_write_register(ViPipe, 0x34, 0x01); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0x80, 0x7f); + gc2145_write_register(ViPipe, 0x81, 0x26); + gc2145_write_register(ViPipe, 0x82, 0xfa); + gc2145_write_register(ViPipe, 0x83, 0x00); + gc2145_write_register(ViPipe, 0x84, 0x00); + gc2145_write_register(ViPipe, 0x86, 0x02); + gc2145_write_register(ViPipe, 0x88, 0x03); + gc2145_write_register(ViPipe, 0x89, 0x03); + gc2145_write_register(ViPipe, 0x85, 0x08); + gc2145_write_register(ViPipe, 0x8a, 0x00); + gc2145_write_register(ViPipe, 0x8b, 0x00); + gc2145_write_register(ViPipe, 0xb0, 0x55); + gc2145_write_register(ViPipe, 0xc3, 0x00); + gc2145_write_register(ViPipe, 0xc4, 0x80); + gc2145_write_register(ViPipe, 0xc5, 0x90); + gc2145_write_register(ViPipe, 0xc6, 0x3b); + gc2145_write_register(ViPipe, 0xc7, 0x46); + gc2145_write_register(ViPipe, 0xec, 0x06); + gc2145_write_register(ViPipe, 0xed, 0x04); + gc2145_write_register(ViPipe, 0xee, 0x60); + gc2145_write_register(ViPipe, 0xef, 0x90); + gc2145_write_register(ViPipe, 0xb6, 0x01); + gc2145_write_register(ViPipe, 0x90, 0x01); + gc2145_write_register(ViPipe, 0x91, 0x00); + gc2145_write_register(ViPipe, 0x92, 0x00); + gc2145_write_register(ViPipe, 0x93, 0x00); + gc2145_write_register(ViPipe, 0x94, 0x00); + gc2145_write_register(ViPipe, 0x95, 0x04); + gc2145_write_register(ViPipe, 0x96, 0xb0); + gc2145_write_register(ViPipe, 0x97, 0x06); + gc2145_write_register(ViPipe, 0x98, 0x40); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0x40, 0x42); + gc2145_write_register(ViPipe, 0x41, 0x00); + gc2145_write_register(ViPipe, 0x43, 0x5b); + gc2145_write_register(ViPipe, 0x5e, 0x00); + gc2145_write_register(ViPipe, 0x5f, 0x00); + gc2145_write_register(ViPipe, 0x60, 0x00); + gc2145_write_register(ViPipe, 0x61, 0x00); + gc2145_write_register(ViPipe, 0x62, 0x00); + gc2145_write_register(ViPipe, 0x63, 0x00); + gc2145_write_register(ViPipe, 0x64, 0x00); + gc2145_write_register(ViPipe, 0x65, 0x00); + gc2145_write_register(ViPipe, 0x66, 0x20); + gc2145_write_register(ViPipe, 0x67, 0x20); + gc2145_write_register(ViPipe, 0x68, 0x20); + gc2145_write_register(ViPipe, 0x69, 0x20); + gc2145_write_register(ViPipe, 0x76, 0x00); + gc2145_write_register(ViPipe, 0x6a, 0x08); + gc2145_write_register(ViPipe, 0x6b, 0x08); + gc2145_write_register(ViPipe, 0x6c, 0x08); + gc2145_write_register(ViPipe, 0x6d, 0x08); + gc2145_write_register(ViPipe, 0x6e, 0x08); + gc2145_write_register(ViPipe, 0x6f, 0x08); + gc2145_write_register(ViPipe, 0x70, 0x08); + gc2145_write_register(ViPipe, 0x71, 0x08); + gc2145_write_register(ViPipe, 0x76, 0x00); + gc2145_write_register(ViPipe, 0x72, 0xf0); + gc2145_write_register(ViPipe, 0x7e, 0x3c); + gc2145_write_register(ViPipe, 0x7f, 0x00); + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0x48, 0x15); + + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x01, 0x04); + gc2145_write_register(ViPipe, 0x02, 0xc0); + gc2145_write_register(ViPipe, 0x03, 0x04); + gc2145_write_register(ViPipe, 0x04, 0x90); + gc2145_write_register(ViPipe, 0x05, 0x30); + gc2145_write_register(ViPipe, 0x06, 0x90); + gc2145_write_register(ViPipe, 0x07, 0x30); + gc2145_write_register(ViPipe, 0x08, 0x80); + gc2145_write_register(ViPipe, 0x09, 0x00); + gc2145_write_register(ViPipe, 0x0a, 0x82); + gc2145_write_register(ViPipe, 0x0b, 0x11); + gc2145_write_register(ViPipe, 0x0c, 0x10); + gc2145_write_register(ViPipe, 0x11, 0x10); + gc2145_write_register(ViPipe, 0x13, 0x7b); + gc2145_write_register(ViPipe, 0x17, 0x00); + gc2145_write_register(ViPipe, 0x1c, 0x11); + gc2145_write_register(ViPipe, 0x1e, 0x61); + gc2145_write_register(ViPipe, 0x1f, 0x35); + gc2145_write_register(ViPipe, 0x20, 0x40); + gc2145_write_register(ViPipe, 0x22, 0x40); + gc2145_write_register(ViPipe, 0x23, 0x20); + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0x0f, 0x04); + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x12, 0x35); + gc2145_write_register(ViPipe, 0x15, 0xb0); + gc2145_write_register(ViPipe, 0x10, 0x31); + gc2145_write_register(ViPipe, 0x3e, 0x28); + gc2145_write_register(ViPipe, 0x3f, 0xb0); + gc2145_write_register(ViPipe, 0x40, 0x90); + gc2145_write_register(ViPipe, 0x41, 0x0f); + + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0x90, 0x6c); + gc2145_write_register(ViPipe, 0x91, 0x03); + gc2145_write_register(ViPipe, 0x92, 0xcb); + gc2145_write_register(ViPipe, 0x94, 0x33); + gc2145_write_register(ViPipe, 0x95, 0x84); + gc2145_write_register(ViPipe, 0x97, 0x65); + gc2145_write_register(ViPipe, 0xa2, 0x11); + gc2145_write_register(ViPipe, 0xfe, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0x80, 0xc1); + gc2145_write_register(ViPipe, 0x81, 0x08); + gc2145_write_register(ViPipe, 0x82, 0x05); + gc2145_write_register(ViPipe, 0x83, 0x08); + gc2145_write_register(ViPipe, 0x84, 0x0a); + gc2145_write_register(ViPipe, 0x86, 0xf0); + gc2145_write_register(ViPipe, 0x87, 0x50); + gc2145_write_register(ViPipe, 0x88, 0x15); + gc2145_write_register(ViPipe, 0x89, 0xb0); + gc2145_write_register(ViPipe, 0x8a, 0x30); + gc2145_write_register(ViPipe, 0x8b, 0x10); + + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x21, 0x04); + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0xa3, 0x50); + gc2145_write_register(ViPipe, 0xa4, 0x20); + gc2145_write_register(ViPipe, 0xa5, 0x40); + gc2145_write_register(ViPipe, 0xa6, 0x80); + gc2145_write_register(ViPipe, 0xab, 0x40); + gc2145_write_register(ViPipe, 0xae, 0x0c); + gc2145_write_register(ViPipe, 0xb3, 0x46); + gc2145_write_register(ViPipe, 0xb4, 0x64); + gc2145_write_register(ViPipe, 0xb6, 0x38); + gc2145_write_register(ViPipe, 0xb7, 0x01); + gc2145_write_register(ViPipe, 0xb9, 0x2b); + gc2145_write_register(ViPipe, 0x3c, 0x04); + gc2145_write_register(ViPipe, 0x3d, 0x15); + gc2145_write_register(ViPipe, 0x4b, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x20); + gc2145_write_register(ViPipe, 0xfe, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0x10, 0x09); + gc2145_write_register(ViPipe, 0x11, 0x0d); + gc2145_write_register(ViPipe, 0x12, 0x13); + gc2145_write_register(ViPipe, 0x13, 0x19); + gc2145_write_register(ViPipe, 0x14, 0x27); + gc2145_write_register(ViPipe, 0x15, 0x37); + gc2145_write_register(ViPipe, 0x16, 0x45); + gc2145_write_register(ViPipe, 0x17, 0x53); + gc2145_write_register(ViPipe, 0x18, 0x69); + gc2145_write_register(ViPipe, 0x19, 0x7d); + gc2145_write_register(ViPipe, 0x1a, 0x8f); + gc2145_write_register(ViPipe, 0x1b, 0x9d); + gc2145_write_register(ViPipe, 0x1c, 0xa9); + gc2145_write_register(ViPipe, 0x1d, 0xbd); + gc2145_write_register(ViPipe, 0x1e, 0xcd); + gc2145_write_register(ViPipe, 0x1f, 0xd9); + gc2145_write_register(ViPipe, 0x20, 0xe3); + gc2145_write_register(ViPipe, 0x21, 0xea); + gc2145_write_register(ViPipe, 0x22, 0xef); + gc2145_write_register(ViPipe, 0x23, 0xf5); + gc2145_write_register(ViPipe, 0x24, 0xf9); + gc2145_write_register(ViPipe, 0x25, 0xff); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0xc6, 0x20); + gc2145_write_register(ViPipe, 0xc7, 0x2b); + + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0x26, 0x0f); + gc2145_write_register(ViPipe, 0x27, 0x14); + gc2145_write_register(ViPipe, 0x28, 0x19); + gc2145_write_register(ViPipe, 0x29, 0x1e); + gc2145_write_register(ViPipe, 0x2a, 0x27); + gc2145_write_register(ViPipe, 0x2b, 0x33); + gc2145_write_register(ViPipe, 0x2c, 0x3b); + gc2145_write_register(ViPipe, 0x2d, 0x45); + gc2145_write_register(ViPipe, 0x2e, 0x59); + gc2145_write_register(ViPipe, 0x2f, 0x69); + gc2145_write_register(ViPipe, 0x30, 0x7c); + gc2145_write_register(ViPipe, 0x31, 0x89); + gc2145_write_register(ViPipe, 0x32, 0x98); + gc2145_write_register(ViPipe, 0x33, 0xae); + gc2145_write_register(ViPipe, 0x34, 0xc0); + gc2145_write_register(ViPipe, 0x35, 0xcf); + gc2145_write_register(ViPipe, 0x36, 0xda); + gc2145_write_register(ViPipe, 0x37, 0xe2); + gc2145_write_register(ViPipe, 0x38, 0xe9); + gc2145_write_register(ViPipe, 0x39, 0xf3); + gc2145_write_register(ViPipe, 0x3a, 0xf9); + gc2145_write_register(ViPipe, 0x3b, 0xff); + + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0xd1, 0x32); + gc2145_write_register(ViPipe, 0xd2, 0x32); + gc2145_write_register(ViPipe, 0xd3, 0x40); + gc2145_write_register(ViPipe, 0xd6, 0xf0); + gc2145_write_register(ViPipe, 0xd7, 0x10); + gc2145_write_register(ViPipe, 0xd8, 0xda); + gc2145_write_register(ViPipe, 0xdd, 0x14); + gc2145_write_register(ViPipe, 0xde, 0x86); + gc2145_write_register(ViPipe, 0xed, 0x80); + gc2145_write_register(ViPipe, 0xee, 0x00); + gc2145_write_register(ViPipe, 0xef, 0x3f); + gc2145_write_register(ViPipe, 0xd8, 0xd8); + + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x9f, 0x40); + + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0xc2, 0x14); + gc2145_write_register(ViPipe, 0xc3, 0x0d); + gc2145_write_register(ViPipe, 0xc4, 0x0c); + gc2145_write_register(ViPipe, 0xc8, 0x15); + gc2145_write_register(ViPipe, 0xc9, 0x0d); + gc2145_write_register(ViPipe, 0xca, 0x0a); + gc2145_write_register(ViPipe, 0xbc, 0x24); + gc2145_write_register(ViPipe, 0xbd, 0x10); + gc2145_write_register(ViPipe, 0xbe, 0x0b); + gc2145_write_register(ViPipe, 0xb6, 0x25); + gc2145_write_register(ViPipe, 0xb7, 0x16); + gc2145_write_register(ViPipe, 0xb8, 0x15); + gc2145_write_register(ViPipe, 0xc5, 0x00); + gc2145_write_register(ViPipe, 0xc6, 0x00); + gc2145_write_register(ViPipe, 0xc7, 0x00); + gc2145_write_register(ViPipe, 0xcb, 0x00); + gc2145_write_register(ViPipe, 0xcc, 0x00); + gc2145_write_register(ViPipe, 0xcd, 0x00); + gc2145_write_register(ViPipe, 0xbf, 0x07); + gc2145_write_register(ViPipe, 0xc0, 0x00); + gc2145_write_register(ViPipe, 0xc1, 0x00); + gc2145_write_register(ViPipe, 0xb9, 0x00); + gc2145_write_register(ViPipe, 0xba, 0x00); + gc2145_write_register(ViPipe, 0xbb, 0x00); + gc2145_write_register(ViPipe, 0xaa, 0x01); + gc2145_write_register(ViPipe, 0xab, 0x01); + gc2145_write_register(ViPipe, 0xac, 0x00); + gc2145_write_register(ViPipe, 0xad, 0x05); + gc2145_write_register(ViPipe, 0xae, 0x06); + gc2145_write_register(ViPipe, 0xaf, 0x0e); + gc2145_write_register(ViPipe, 0xb0, 0x0b); + gc2145_write_register(ViPipe, 0xb1, 0x07); + gc2145_write_register(ViPipe, 0xb2, 0x06); + gc2145_write_register(ViPipe, 0xb3, 0x17); + gc2145_write_register(ViPipe, 0xb4, 0x0e); + gc2145_write_register(ViPipe, 0xb5, 0x0e); + gc2145_write_register(ViPipe, 0xd0, 0x09); + gc2145_write_register(ViPipe, 0xd1, 0x00); + gc2145_write_register(ViPipe, 0xd2, 0x00); + gc2145_write_register(ViPipe, 0xd6, 0x08); + gc2145_write_register(ViPipe, 0xd7, 0x00); + gc2145_write_register(ViPipe, 0xd8, 0x00); + gc2145_write_register(ViPipe, 0xd9, 0x00); + gc2145_write_register(ViPipe, 0xda, 0x00); + gc2145_write_register(ViPipe, 0xdb, 0x00); + gc2145_write_register(ViPipe, 0xd3, 0x0a); + gc2145_write_register(ViPipe, 0xd4, 0x00); + gc2145_write_register(ViPipe, 0xd5, 0x00); + gc2145_write_register(ViPipe, 0xa4, 0x00); + gc2145_write_register(ViPipe, 0xa5, 0x00); + gc2145_write_register(ViPipe, 0xa6, 0x77); + gc2145_write_register(ViPipe, 0xa7, 0x77); + gc2145_write_register(ViPipe, 0xa8, 0x77); + gc2145_write_register(ViPipe, 0xa9, 0x77); + gc2145_write_register(ViPipe, 0xa1, 0x80); + gc2145_write_register(ViPipe, 0xa2, 0x80); + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0xdf, 0x0d); + gc2145_write_register(ViPipe, 0xdc, 0x25); + gc2145_write_register(ViPipe, 0xdd, 0x30); + gc2145_write_register(ViPipe, 0xe0, 0x77); + gc2145_write_register(ViPipe, 0xe1, 0x80); + gc2145_write_register(ViPipe, 0xe2, 0x77); + gc2145_write_register(ViPipe, 0xe3, 0x90); + gc2145_write_register(ViPipe, 0xe6, 0x90); + gc2145_write_register(ViPipe, 0xe7, 0xa0); + gc2145_write_register(ViPipe, 0xe8, 0x90); + gc2145_write_register(ViPipe, 0xe9, 0xa0); + gc2145_write_register(ViPipe, 0xfe, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x4f, 0x00); + gc2145_write_register(ViPipe, 0x4f, 0x00); + gc2145_write_register(ViPipe, 0x4b, 0x01); + gc2145_write_register(ViPipe, 0x4f, 0x00); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x71); + gc2145_write_register(ViPipe, 0x4e, 0x01); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x91); + gc2145_write_register(ViPipe, 0x4e, 0x01); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x70); + gc2145_write_register(ViPipe, 0x4e, 0x01); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x90); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xb0); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x8f); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x6f); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xaf); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xd0); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xf0); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xcf); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xef); + gc2145_write_register(ViPipe, 0x4e, 0x02); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x6e); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x8e); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xae); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xce); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x4d); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x6d); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x8d); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xad); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xcd); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x4c); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x6c); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x8c); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xac); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xcc); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xcb); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x4b); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x6b); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x8b); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xab); + gc2145_write_register(ViPipe, 0x4e, 0x03); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x8a); + gc2145_write_register(ViPipe, 0x4e, 0x04); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xaa); + gc2145_write_register(ViPipe, 0x4e, 0x04); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xca); + gc2145_write_register(ViPipe, 0x4e, 0x04); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xca); + gc2145_write_register(ViPipe, 0x4e, 0x04); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xc9); + gc2145_write_register(ViPipe, 0x4e, 0x04); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x8a); + gc2145_write_register(ViPipe, 0x4e, 0x04); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0x89); + gc2145_write_register(ViPipe, 0x4e, 0x04); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xa9); + gc2145_write_register(ViPipe, 0x4e, 0x04); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x0b); + gc2145_write_register(ViPipe, 0x4e, 0x05); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x0a); + gc2145_write_register(ViPipe, 0x4e, 0x05); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xeb); + gc2145_write_register(ViPipe, 0x4e, 0x05); + gc2145_write_register(ViPipe, 0x4c, 0x01); + gc2145_write_register(ViPipe, 0x4d, 0xea); + gc2145_write_register(ViPipe, 0x4e, 0x05); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x09); + gc2145_write_register(ViPipe, 0x4e, 0x05); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x29); + gc2145_write_register(ViPipe, 0x4e, 0x05); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x2a); + gc2145_write_register(ViPipe, 0x4e, 0x05); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x4a); + gc2145_write_register(ViPipe, 0x4e, 0x05); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x8a); + gc2145_write_register(ViPipe, 0x4e, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x49); + gc2145_write_register(ViPipe, 0x4e, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x69); + gc2145_write_register(ViPipe, 0x4e, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x89); + gc2145_write_register(ViPipe, 0x4e, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xa9); + gc2145_write_register(ViPipe, 0x4e, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x48); + gc2145_write_register(ViPipe, 0x4e, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x68); + gc2145_write_register(ViPipe, 0x4e, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0x69); + gc2145_write_register(ViPipe, 0x4e, 0x06); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xca); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xc9); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xe9); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x03); + gc2145_write_register(ViPipe, 0x4d, 0x09); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xc8); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xe8); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xa7); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xc7); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x02); + gc2145_write_register(ViPipe, 0x4d, 0xe7); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4c, 0x03); + gc2145_write_register(ViPipe, 0x4d, 0x07); + gc2145_write_register(ViPipe, 0x4e, 0x07); + gc2145_write_register(ViPipe, 0x4f, 0x01); + gc2145_write_register(ViPipe, 0x50, 0x80); + gc2145_write_register(ViPipe, 0x51, 0xa8); + gc2145_write_register(ViPipe, 0x52, 0x47); + gc2145_write_register(ViPipe, 0x53, 0x38); + gc2145_write_register(ViPipe, 0x54, 0xc7); + gc2145_write_register(ViPipe, 0x56, 0x0e); + gc2145_write_register(ViPipe, 0x58, 0x08); + gc2145_write_register(ViPipe, 0x5b, 0x00); + gc2145_write_register(ViPipe, 0x5c, 0x74); + gc2145_write_register(ViPipe, 0x5d, 0x8b); + gc2145_write_register(ViPipe, 0x61, 0xdb); + gc2145_write_register(ViPipe, 0x62, 0xb8); + gc2145_write_register(ViPipe, 0x63, 0x86); + gc2145_write_register(ViPipe, 0x64, 0xc0); + gc2145_write_register(ViPipe, 0x65, 0x04); + gc2145_write_register(ViPipe, 0x67, 0xa8); + gc2145_write_register(ViPipe, 0x68, 0xb0); + gc2145_write_register(ViPipe, 0x69, 0x00); + gc2145_write_register(ViPipe, 0x6a, 0xa8); + gc2145_write_register(ViPipe, 0x6b, 0xb0); + gc2145_write_register(ViPipe, 0x6c, 0xaf); + gc2145_write_register(ViPipe, 0x6d, 0x8b); + gc2145_write_register(ViPipe, 0x6e, 0x50); + gc2145_write_register(ViPipe, 0x6f, 0x18); + gc2145_write_register(ViPipe, 0x73, 0xf0); + gc2145_write_register(ViPipe, 0x70, 0x0d); + gc2145_write_register(ViPipe, 0x71, 0x60); + gc2145_write_register(ViPipe, 0x72, 0x80); + gc2145_write_register(ViPipe, 0x74, 0x01); + gc2145_write_register(ViPipe, 0x75, 0x01); + gc2145_write_register(ViPipe, 0x7f, 0x0c); + gc2145_write_register(ViPipe, 0x76, 0x70); + gc2145_write_register(ViPipe, 0x77, 0x58); + gc2145_write_register(ViPipe, 0x78, 0xa0); + gc2145_write_register(ViPipe, 0x79, 0x5e); + gc2145_write_register(ViPipe, 0x7a, 0x54); + gc2145_write_register(ViPipe, 0x7b, 0x58); + gc2145_write_register(ViPipe, 0xfe, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0xc0, 0x01); + gc2145_write_register(ViPipe, 0xc1, 0x44); + gc2145_write_register(ViPipe, 0xc2, 0xfd); + gc2145_write_register(ViPipe, 0xc3, 0x04); + gc2145_write_register(ViPipe, 0xc4, 0xF0); + gc2145_write_register(ViPipe, 0xc5, 0x48); + gc2145_write_register(ViPipe, 0xc6, 0xfd); + gc2145_write_register(ViPipe, 0xc7, 0x46); + gc2145_write_register(ViPipe, 0xc8, 0xfd); + gc2145_write_register(ViPipe, 0xc9, 0x02); + gc2145_write_register(ViPipe, 0xca, 0xe0); + gc2145_write_register(ViPipe, 0xcb, 0x45); + gc2145_write_register(ViPipe, 0xcc, 0xec); + gc2145_write_register(ViPipe, 0xcd, 0x48); + gc2145_write_register(ViPipe, 0xce, 0xf0); + gc2145_write_register(ViPipe, 0xcf, 0xf0); + gc2145_write_register(ViPipe, 0xe3, 0x0c); + gc2145_write_register(ViPipe, 0xe4, 0x4b); + gc2145_write_register(ViPipe, 0xe5, 0xe0); + + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x9f, 0x40); + gc2145_write_register(ViPipe, 0xfe, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0xf2, 0x0f); + + gc2145_write_register(ViPipe, 0xfe, 0x02); + gc2145_write_register(ViPipe, 0x40, 0xbf); + gc2145_write_register(ViPipe, 0x46, 0xcf); + gc2145_write_register(ViPipe, 0xfe, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0x05, 0x01); + gc2145_write_register(ViPipe, 0x06, 0x56); + gc2145_write_register(ViPipe, 0x07, 0x00); + gc2145_write_register(ViPipe, 0x08, 0x32); + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x25, 0x00); + gc2145_write_register(ViPipe, 0x26, 0xfa); + gc2145_write_register(ViPipe, 0x27, 0x04); + gc2145_write_register(ViPipe, 0x28, 0xe2); + gc2145_write_register(ViPipe, 0x29, 0x06); + gc2145_write_register(ViPipe, 0x2a, 0xd6); + gc2145_write_register(ViPipe, 0x2b, 0x07); + gc2145_write_register(ViPipe, 0x2c, 0xd0); + gc2145_write_register(ViPipe, 0x2d, 0x0b); + gc2145_write_register(ViPipe, 0x2e, 0xb8); + gc2145_write_register(ViPipe, 0xfe, 0x00); + + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0xfd, 0x00); + gc2145_write_register(ViPipe, 0xf8, 0x82); + gc2145_write_register(ViPipe, 0xfa, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0x90, 0x01); + gc2145_write_register(ViPipe, 0x91, 0x00); + gc2145_write_register(ViPipe, 0x92, 0x00); + gc2145_write_register(ViPipe, 0x93, 0x00); + gc2145_write_register(ViPipe, 0x94, 0x00); + gc2145_write_register(ViPipe, 0x95, 0x04); + gc2145_write_register(ViPipe, 0x96, 0xb0); + gc2145_write_register(ViPipe, 0x97, 0x06); + gc2145_write_register(ViPipe, 0x98, 0x40); + gc2145_write_register(ViPipe, 0x99, 0x11); + gc2145_write_register(ViPipe, 0x9a, 0x06); + gc2145_write_register(ViPipe, 0x9b, 0x00); + gc2145_write_register(ViPipe, 0x9c, 0x00); + gc2145_write_register(ViPipe, 0x9d, 0x00); + gc2145_write_register(ViPipe, 0x9e, 0x00); + gc2145_write_register(ViPipe, 0x9f, 0x00); + gc2145_write_register(ViPipe, 0xa0, 0x00); + gc2145_write_register(ViPipe, 0xa1, 0x00); + gc2145_write_register(ViPipe, 0xa2, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0xec, 0x06); + gc2145_write_register(ViPipe, 0xed, 0x04); + gc2145_write_register(ViPipe, 0xee, 0x60); + gc2145_write_register(ViPipe, 0xef, 0x90); + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x74, 0x01); + + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x01, 0x04); + gc2145_write_register(ViPipe, 0x02, 0xc0); + gc2145_write_register(ViPipe, 0x03, 0x04); + gc2145_write_register(ViPipe, 0x04, 0x90); + gc2145_write_register(ViPipe, 0x05, 0x30); + gc2145_write_register(ViPipe, 0x06, 0x90); + gc2145_write_register(ViPipe, 0x07, 0x30); + gc2145_write_register(ViPipe, 0x08, 0x80); + gc2145_write_register(ViPipe, 0x0a, 0x82); + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x21, 0x15); + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0x20, 0x15); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + gc2145_write_register(ViPipe, 0x05, 0x01); + gc2145_write_register(ViPipe, 0x06, 0x2f); + gc2145_write_register(ViPipe, 0x07, 0x00); + gc2145_write_register(ViPipe, 0x08, 0x64); + gc2145_write_register(ViPipe, 0xfe, 0x01); + gc2145_write_register(ViPipe, 0x25, 0x00); + gc2145_write_register(ViPipe, 0x26, 0xa0); + gc2145_write_register(ViPipe, 0x27, 0x05); + gc2145_write_register(ViPipe, 0x28, 0x00); + gc2145_write_register(ViPipe, 0x29, 0x05); + gc2145_write_register(ViPipe, 0x2a, 0x00); + gc2145_write_register(ViPipe, 0x2b, 0x05); + gc2145_write_register(ViPipe, 0x2c, 0x00); + gc2145_write_register(ViPipe, 0x2d, 0x05); + gc2145_write_register(ViPipe, 0x2e, 0x00); + + gc2145_write_register(ViPipe, 0xfe, 0x00); + + delay_ms(100); + + printf("ViPipe:%d,===GC2145 1200P 12fps YUV Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc4023/Makefile b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4023/Makefile new file mode 100644 index 000000000..cd2e0182f --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4023/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc4023.a +TARGET_SO = $(MW_LIB)/libsns_gc4023.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc4023/gc4023_cmos.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4023/gc4023_cmos.c new file mode 100644 index 000000000..ad5ce6ff9 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4023/gc4023_cmos.c @@ -0,0 +1,934 @@ +#include +#include +#include +#include +#include +#include +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" +#include "gc4023_cmos_ex.h" +#include "gc4023_cmos_param.h" +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#include "cvi_type.h" +#else +#include +#include +#include +#endif + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define GC4023_ID 4023 +#define GC4023_I2C_ADDR_1 0x21 +#define GC4023_I2C_ADDR_2 0x29 +#define GC4023_I2C_ADDR_IS_VALID(addr) ((addr) == GC4023_I2C_ADDR_1 || (addr) == GC4023_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ***************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc4023[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC4023_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc4023[dev]) +#define GC4023_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc4023[dev] = pstCtx) +#define GC4023_SENSOR_RESET_CTX(dev) (g_pastGc4023[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc4023_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 3}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc4023_MirrorFip[VI_MAX_PIPE_NUM] = {ISP_SNS_NORMAL}; + +CVI_U16 g_au16Gc4023_GainMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ***************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Gc4023 Lines Range*****/ +#define GC4023_FULL_LINES_MAX (0x3fff) + +/*****Gc4023 Register Address*****/ +#define GC4023_EXP_H_ADDR 0x0202 //bit[13:8] +#define GC4023_EXP_L_ADDR 0x0203 + +#define GC4023_AGAIN_H_ADDR 0x0615 //bit[11:8] +#define GC4023_AGAIN_L_ADDR 0x0614 +#define GC4023_COL_AGAIN_H_ADDR 0x00b8 //bit[13:8] +#define GC4023_COL_AGAIN_L_ADDR 0x00b9 + + +#define GC4023_AGAIN_MAG1_ADDR 0x0218 +#define GC4023_AGAIN_MAG2_ADDR 0x1467 +#define GC4023_AGAIN_MAG3_ADDR 0x1468 + + +#define GC4023_VTS_H_ADDR 0x0340 //bit[13:8] +#define GC4023_VTS_L_ADDR 0x0341 + +#define GC4023_MIRROR_FLIP_ADDR 0x022c +#define GC4023_OTP_MIRROR_FLIP_ADDR 0x0a73 + +#define GC4023_RES_IS_1440P(w, h) ((w) <= 2560 && (h) <= 1440) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC4023_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astGc4023_mode[GC4023_MODE_2560X1440P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astGc4023_mode[GC4023_MODE_2560X1440P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 60880; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 1024; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? + g_au32InitExposure[ViPipe] : g_astGc4023_mode[GC4023_MODE_2560X1440P30].stExp[0].u16Def; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstAeSnsDft->u32MinIntTime = g_astGc4023_mode[GC4023_MODE_2560X1440P30].stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astGc4023_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astGc4023_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astGc4023_mode[pstSnsState->u8ImgMode].f32MinFps; + + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + + u32VMAX = (u32VMAX > GC4023_FULL_LINES_MAX) ? GC4023_FULL_LINES_MAX : u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = (u32IntTime[0] >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_U32 regValTable[25][7] = { + /*[reg] 0x0614 0x0615 0x0218 0x1467 0x1468 0x00b8 0x00b9*/ + {0x00, 0x00, 0x00, 0x0D, 0x15, 0x01, 0x00}, + {0x80, 0x02, 0x00, 0x0D, 0x15, 0x01, 0x0B}, + {0x01, 0x00, 0x00, 0x0D, 0x15, 0x01, 0x19}, + {0x81, 0x02, 0x00, 0x0E, 0x16, 0x01, 0x2A}, + {0x02, 0x00, 0x00, 0x0E, 0x16, 0x02, 0x00}, + {0x82, 0x02, 0x00, 0x0F, 0x17, 0x02, 0x17}, + {0x03, 0x00, 0x00, 0x10, 0x18, 0x02, 0x33}, + {0x83, 0x02, 0x00, 0x11, 0x19, 0x03, 0x14}, + {0x04, 0x00, 0x00, 0x12, 0x1a, 0x04, 0x00}, + {0x80, 0x02, 0x20, 0x13, 0x1b, 0x04, 0x2F}, + {0x01, 0x00, 0x20, 0x14, 0x1c, 0x05, 0x26}, + {0x81, 0x02, 0x20, 0x15, 0x1d, 0x06, 0x28}, + {0x02, 0x00, 0x20, 0x16, 0x1e, 0x08, 0x00}, + {0x82, 0x02, 0x20, 0x16, 0x1e, 0x09, 0x1E}, + {0x03, 0x00, 0x20, 0x18, 0x20, 0x0B, 0x0C}, + {0x83, 0x02, 0x20, 0x18, 0x20, 0x0D, 0x11}, + {0x04, 0x00, 0x20, 0x18, 0x20, 0x10, 0x00}, + {0x84, 0x02, 0x20, 0x19, 0x21, 0x12, 0x3D}, + {0x05, 0x00, 0x20, 0x19, 0x21, 0x16, 0x19}, + {0x85, 0x02, 0x20, 0x1A, 0x22, 0x1A, 0x22}, + {0xb5, 0x04, 0x20, 0x1B, 0x23, 0x20, 0x00}, + {0x85, 0x05, 0x20, 0x1B, 0x23, 0x25, 0x3A}, + {0x05, 0x08, 0x20, 0x1C, 0x24, 0x2C, 0x33}, + {0x45, 0x09, 0x20, 0x1D, 0x25, 0x35, 0x05}, + {0x55, 0x0a, 0x20, 0x1F, 0x27, 0x40, 0x00}, +}; + +static CVI_U32 gain_table[25] = { + 16*64, + 16*76, + 16*90, + 16*107, + 16*125, + 16*148, + 16*177, + 16*211, + 16*245, + 16*301, + 16*362, + 16*439, + 16*526, + 16*634, + 16*756, + 16*891, + 16*1026, + 16*1205, + 16*1408, + 16*1655, + 16*1962, + 16*2106, + 16*2733, + 16*3222, + 16*3805, +}; + +int total = sizeof(gain_table) / sizeof(CVI_U32); + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + UNUSED(ViPipe); + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[total - 1]) { + *pu32AgainDb = total - 1; + *pu32AgainLin = gain_table[total - 1]; + return CVI_SUCCESS; + } + + for (i = 0; i < total; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainDb = i - 1; + break; + } + } + *pu32AgainLin = gain_table[i - 1]; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + UNUSED(ViPipe); + + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + /* only surpport linear mode */ + u32Again = pu32Again[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][0]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][1]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG1].u32Data = regValTable[u32Again][2]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG2].u32Data = regValTable[u32Again][3]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG3].u32Data = regValTable[u32Again][4]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][5]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][6]; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + UNUSED(ViPipe); + UNUSED(u16ManRatioEnable); + UNUSED(au32Ratio); + UNUSED(au32IntTimeMax); + UNUSED(au32IntTimeMin); + UNUSED(pu32LFMaxIntTime); + + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode\n"); + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + UNUSED(ViPipe); + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + UNUSED(ViPipe); + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + CMOS_CHECK_POINTER(pstBlc); + UNUSED(ViPipe); + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC4023_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astGc4023_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + UNUSED(ViPipe); + UNUSED(u8Mode); + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunGc4023_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = gc4023_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc4023_addr_byte; + pstI2c_data[i].u32DataByteNum = gc4023_data_byte; + } + + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC4023_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC4023_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC4023_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC4023_AGAIN_L_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG1].u32RegAddr = GC4023_AGAIN_MAG1_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG2].u32RegAddr = GC4023_AGAIN_MAG2_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG3].u32RegAddr = GC4023_AGAIN_MAG3_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC4023_COL_AGAIN_H_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC4023_COL_AGAIN_L_ADDR; + + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC4023_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC4023_VTS_L_ADDR; + pstI2c_data[LINEAR_MIRROR_FLIP].u32RegAddr = GC4023_MIRROR_FLIP_ADDR; + pstI2c_data[LINEAR_OTP_MIRROR_FLIP].u32RegAddr = GC4023_OTP_MIRROR_FLIP_ADDR; + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + + CVI_U32 gainsUpdate = 0, shutterUpdate = 0, vtsUpdate = 0; + + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + + //if ((i >= LINEAR_AGAIN_H) && (i <= LINEAR_DGAIN_L)) + if ((i >= LINEAR_AGAIN_H) && (i <= LINEAR_COL_AGAIN_L)) + gainsUpdate = 1; + + if (i <= LINEAR_EXP_L) + shutterUpdate = 1; + + if ((i >= LINEAR_VTS_H) && (i <= LINEAR_VTS_L)) + vtsUpdate = 1; + + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (gainsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG1].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG2].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG3].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_L].bUpdate = CVI_TRUE; + } + if (shutterUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_L].bUpdate = CVI_TRUE; + } + if (vtsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_VTS_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_VTS_L].bUpdate = CVI_TRUE; + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + pstCfg0->snsCfg.astI2cData[LINEAR_MIRROR_FLIP].bDropFrm = CVI_FALSE; + pstCfg0->snsCfg.astI2cData[LINEAR_OTP_MIRROR_FLIP].bDropFrm = CVI_FALSE; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC4023_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC4023_MODE_2560X1440P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U8 value, otp_value; + + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc4023_MirrorFip[ViPipe] != eSnsMirrorFlip) { + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + value = 0; + otp_value = 0x60; + break; + case ISP_SNS_MIRROR: + value = 0x01; + otp_value = 0x61; + break; + case ISP_SNS_FLIP: + value = 0x02; + otp_value = 0x62; + break; + case ISP_SNS_MIRROR_FLIP: + value = 0x03; + otp_value = 0x63; + break; + default: + return; + } + + pstSnsRegsInfo->astI2cData[LINEAR_MIRROR_FLIP].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_OTP_MIRROR_FLIP].u32Data = otp_value; + pstSnsRegsInfo->astI2cData[LINEAR_MIRROR_FLIP].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_MIRROR_FLIP].u8DropFrmNum = 1; + pstSnsRegsInfo->astI2cData[LINEAR_OTP_MIRROR_FLIP].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_OTP_MIRROR_FLIP].u8DropFrmNum = 1; + g_aeGc4023_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC4023_MODE_2560X1440P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astGc4023_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astGc4023_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astGc4023_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC4023_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc4023_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astGc4023_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astGc4023_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc4023_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc4023_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc4023_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (GC4023_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc4023_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc4023_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc4023_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC4023_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC4023_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC4023_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC4023_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC4023_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC4023_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC4023_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC4023_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Gc4023_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc4023_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc4023_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc4023_standby, + .pfnRestart = gc4023_restart, + .pfnWriteReg = gc4023_write_register, + .pfnReadReg = gc4023_read_register, + .pfnSetBusInfo = gc4023_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc4023/gc4023_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4023/gc4023_cmos_ex.h new file mode 100644 index 000000000..924944c9c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4023/gc4023_cmos_ex.h @@ -0,0 +1,90 @@ +#ifndef __GC4023_CMOS_EX_H_ +#define __GC4023_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum gc4023_linear_regs_e { + LINEAR_EXP_H, + LINEAR_EXP_L, + LINEAR_AGAIN_L, + LINEAR_AGAIN_H, + LINEAR_AGAIN_MAG1, + LINEAR_AGAIN_MAG2, + LINEAR_AGAIN_MAG3, + LINEAR_COL_AGAIN_H, + LINEAR_COL_AGAIN_L, + LINEAR_VTS_H, + LINEAR_VTS_L, + LINEAR_MIRROR_FLIP, + LINEAR_OTP_MIRROR_FLIP, + LINEAR_REGS_NUM +}; + +typedef enum _GC4023_MODE_E { + GC4023_MODE_2560X1440P30 = 0, + GC4023_MODE_LINEAR_NUM, + GC4023_MODE_NUM +} GC4023_MODE_E; + +typedef struct _GC4023_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC4023_STATE_S; + +typedef struct _GC4023_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} GC4023_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc4023[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc4023_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc4023_MirrorFip[VI_MAX_PIPE_NUM]; +extern CVI_U8 gc4023_i2c_addr; +extern const CVI_U32 gc4023_addr_byte; +extern const CVI_U32 gc4023_data_byte; +extern void gc4023_init(VI_PIPE ViPipe); +extern void gc4023_exit(VI_PIPE ViPipe); +extern void gc4023_standby(VI_PIPE ViPipe); +extern void gc4023_restart(VI_PIPE ViPipe); +extern int gc4023_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc4023_read_register(VI_PIPE ViPipe, int addr); +extern int gc4023_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC4023_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc4023/gc4023_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4023/gc4023_cmos_param.h new file mode 100644 index 000000000..a7de56790 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4023/gc4023_cmos_param.h @@ -0,0 +1,223 @@ +#ifndef __GC4023_CMOS_PARAM_H_ +#define __GC4023_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif + +#include "cvi_sns_ctrl.h" +#include "gc4023_cmos_ex.h" + +static const GC4023_MODE_S g_astGc4023_mode[GC4023_MODE_NUM] = { + [GC4023_MODE_2560X1440P30] = { + .name = "2560X1440P30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 5.49, /* 1500 * 30 / 8191*/ + .u32HtsDef = 2400, + .u32VtsDef = 1500, + .stExp[0] = { + .u16Min = 1, + .u16Max = 0x3fff, + .u16Def = 100, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 16*3805, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 1024, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.04006369039416313171, 5.73531675338745117188}, //B: slope, intercept + {0.03064448758959770203, 8.56994438171386718750}, //Gb: slope, intercept + {0.03068985790014266968, 8.82220363616943359375}, //Gr: slope, intercept + {0.03361049667000770569, 7.20687675476074218750}, //R: slope, intercept + }, + { //iso 200 + {0.05054308474063873291, 7.91628408432006835938}, //B: slope, intercept + {0.03632996603846549988, 13.05291843414306640625}, //Gb: slope, intercept + {0.03697143867611885071, 12.49540805816650390625}, //Gr: slope, intercept + {0.04156460240483283997, 10.44298553466796875000}, //R: slope, intercept + }, + { //iso 400 + {0.06805337965488433838, 11.55693244934082031250}, //B: slope, intercept + {0.04390667378902435303, 18.59673881530761718750}, //Gb: slope, intercept + {0.04630871489644050598, 17.90183258056640625000}, //Gr: slope, intercept + {0.05292420834302902222, 15.17318439483642578125}, //R: slope, intercept + }, + { //iso 800 + {0.08635756373405456543, 17.79124641418457031250}, //B: slope, intercept + {0.05776864662766456604, 26.76541900634765625000}, //Gb: slope, intercept + {0.05839699879288673401, 26.44194030761718750000}, //Gr: slope, intercept + {0.06750740110874176025, 22.42554473876953125000}, //R: slope, intercept + }, + { //iso 1600 + {0.12254384160041809082, 26.20610046386718750000}, //B: slope, intercept + {0.07916855812072753906, 39.39273834228515625000}, //Gb: slope, intercept + {0.07857896387577056885, 39.03499984741210937500}, //Gr: slope, intercept + {0.09273355454206466675, 33.09597778320312500000}, //R: slope, intercept + }, + { //iso 3200 + {0.18002016842365264893, 34.86975860595703125000}, //B: slope, intercept + {0.10951708257198333740, 54.58878326416015625000}, //Gb: slope, intercept + {0.10485322028398513794, 57.16654205322265625000}, //Gr: slope, intercept + {0.13257601857185363770, 46.27093505859375000000}, //R: slope, intercept + }, + { //iso 6400 + {0.24713687598705291748, 48.62341690063476562500}, //B: slope, intercept + {0.14974890649318695068, 77.06428527832031250000}, //Gb: slope, intercept + {0.14544390141963958740, 76.57913970947265625000}, //Gr: slope, intercept + {0.19056233763694763184, 62.13500213623046875000}, //R: slope, intercept + }, + { //iso 12800 + {0.37728109955787658691, 58.15543365478515625000}, //B: slope, intercept + {0.20440576970577239990, 100.45700073242187500000}, //Gb: slope, intercept + {0.20059910416603088379, 102.35488891601562500000}, //Gr: slope, intercept + {0.27388775348663330078, 79.65499877929687500000}, //R: slope, intercept + }, + { //iso 25600 + {0.36612421274185180664, 115.28938293457031250000}, //B: slope, intercept + {0.22633622586727142334, 164.58416748046875000000}, //Gb: slope, intercept + {0.21590474247932434082, 168.92042541503906250000}, //Gr: slope, intercept + {0.33193346858024597168, 127.92090606689453125000}, //R: slope, intercept + }, + { //iso 51200 + {0.48242908716201782227, 147.39015197753906250000}, //B: slope, intercept + {0.28994381427764892578, 223.02711486816406250000}, //Gb: slope, intercept + {0.29200506210327148438, 220.64030456542968750000}, //Gr: slope, intercept + {0.42304891347885131836, 173.74638366699218750000}, //R: slope, intercept + }, + { //iso 102400 + {0.62099909782409667969, 130.97862243652343750000}, //B: slope, intercept + {0.39534106850624084473, 219.74490356445312500000}, //Gb: slope, intercept + {0.39458695054054260254, 213.37374877929687500000}, //Gr: slope, intercept + {0.55690109729766845703, 158.37773132324218750000}, //R: slope, intercept + }, + { //iso 204800 + {0.75350415706634521484, 77.81707000732421875000}, //B: slope, intercept + {0.52716732025146484375, 148.77879333496093750000}, //Gb: slope, intercept + {0.51073729991912841797, 153.86495971679687500000}, //Gr: slope, intercept + {0.68910604715347290039, 102.12422180175781250000}, //R: slope, intercept + }, + { //iso 409600 + {0.90276730060577392578, 43.78258514404296875000}, //B: slope, intercept + {0.62851423025131225586, 119.41429138183593750000}, //Gb: slope, intercept + {0.64918899536132812500, 110.74241638183593750000}, //Gr: slope, intercept + {0.80880594253540039063, 68.89983367919921875000}, //R: slope, intercept + }, + { //iso 819200 + {0.90276730060577392578, 43.78258514404296875000}, //B: slope, intercept + {0.62851423025131225586, 119.41429138183593750000}, //Gb: slope, intercept + {0.64918899536132812500, 110.74241638183593750000}, //Gr: slope, intercept + {0.80880594253540039063, 68.89983367919921875000}, //R: slope, intercept + }, + { //iso 1638400 + {0.90276730060577392578, 43.78258514404296875000}, //B: slope, intercept + {0.62851423025131225586, 119.41429138183593750000}, //Gb: slope, intercept + {0.64918899536132812500, 110.74241638183593750000}, //Gr: slope, intercept + {0.80880594253540039063, 68.89983367919921875000}, //R: slope, intercept + }, + { //iso 3276800 + {0.90276730060577392578, 43.78258514404296875000}, //B: slope, intercept + {0.62851423025131225586, 119.41429138183593750000}, //Gb: slope, intercept + {0.64918899536132812500, 110.74241638183593750000}, //Gr: slope, intercept + {0.80880594253540039063, 68.89983367919921875000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {252, 252, 252, 252, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1091, 1091, 1091, 1091 +#endif + }, + .stAuto = { + {252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 }, + {252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 }, + {252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 }, + {252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, + 1091, 1091}, + {1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, + 1091, 1091}, + {1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, + 1091, 1091}, + {1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, + 1091, 1091}, +#endif + }, + }, +}; + +struct combo_dev_attr_s gc4023_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 1, 3, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC4023_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc4023/gc4023_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4023/gc4023_sensor_ctl.c new file mode 100644 index 000000000..3e1383686 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4023/gc4023_sensor_ctl.c @@ -0,0 +1,397 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc4023_cmos_ex.h" +#define GC4023_CHIP_ID_ADDR_H 0x03f0 +#define GC4023_CHIP_ID_ADDR_L 0x03f1 +#define GC4023_CHIP_ID 0x4023 + +#define GC4023_MIRROR_NORMAL + +#if defined(GC4023_MIRROR_NORMAL) +#define MIRROR 0x00 +#define OTP_MIRROR 0x60 +#elif defined(GC4023_MIRROR_H) +#define MIRROR 0x01 +#define OTP_MIRROR 0x61 +#elif defined(GC4023_MIRROR_V) +#define MIRROR 0x02 +#define OTP_MIRROR 0x62 +#elif defined(GC4023_MIRROR_HV) +#define MIRROR 0x03 +#define OTP_MIRROR 0x63 +#else +#define MIRROR 0x00 +#define OTP_MIRROR 0x60 +#endif + +static void gc4023_linear_1440p30_init(VI_PIPE ViPipe); + +CVI_U8 gc4023_i2c_addr = 0x29; +const CVI_U32 gc4023_addr_byte = 2; +const CVI_U32 gc4023_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc4023_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc4023_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc4023_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc4023_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc4023_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (gc4023_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc4023_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, gc4023_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc4023_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_INFO, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int gc4023_write_register(VI_PIPE ViPipe, int addr, int data) +{ + int idx = 0; + int ret; + char buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc4023_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + if (gc4023_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc4023_addr_byte + gc4023_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + ret = read(g_fd[ViPipe], buf, gc4023_addr_byte + gc4023_data_byte); + syslog(LOG_INFO, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void gc4023_prog(VI_PIPE ViPipe, int *rom) +{ + int i = 0; + + while (1) { + int lookup = rom[i++]; + int addr = (lookup >> 16) & 0xFFFF; + int data = lookup & 0xFFFF; + + if (addr == 0xFFFE) + delay_ms(data); + else if (addr != 0xFFFF) + gc4023_write_register(ViPipe, addr, data); + } +} + +void gc4023_standby(VI_PIPE ViPipe) +{ + gc4023_write_register(ViPipe, 0x0100, 0x00); + gc4023_write_register(ViPipe, 0x0a34, 0x00); + gc4023_write_register(ViPipe, 0x061c, 0x10); + gc4023_write_register(ViPipe, 0x031c, 0x01); + gc4023_write_register(ViPipe, 0x0a38, 0x00); +} + +void gc4023_restart(VI_PIPE ViPipe) +{ + gc4023_write_register(ViPipe, 0x0a38, 0x01); + gc4023_write_register(ViPipe, 0x0a34, 0x40); + gc4023_write_register(ViPipe, 0x061c, 0x50); + gc4023_write_register(ViPipe, 0x031c, 0xce); + gc4023_write_register(ViPipe, 0x0100, 0x09); +} + +void gc4023_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc4023[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc4023_write_register(ViPipe, + g_pastGc4023[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc4023[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} +int gc4023_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc4023_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc4023_read_register(ViPipe, GC4023_CHIP_ID_ADDR_H); + nVal2 = gc4023_read_register(ViPipe, GC4023_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC4023_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc4023_init(VI_PIPE ViPipe) +{ + gc4023_i2c_init(ViPipe); + + gc4023_linear_1440p30_init(ViPipe); + + g_pastGc4023[ViPipe]->bInit = CVI_TRUE; +} + +void gc4023_exit(VI_PIPE ViPipe) +{ + gc4023_i2c_exit(ViPipe); +} + +static void gc4023_linear_1440p30_init(VI_PIPE ViPipe) +{ + usleep(10*1000); + gc4023_write_register(ViPipe, 0x03fe, 0xf0); + gc4023_write_register(ViPipe, 0x03fe, 0x00); + gc4023_write_register(ViPipe, 0x03fe, 0x10); + gc4023_write_register(ViPipe, 0x03fe, 0x00); + gc4023_write_register(ViPipe, 0x0a38, 0x00); + gc4023_write_register(ViPipe, 0x0a38, 0x01); + gc4023_write_register(ViPipe, 0x0a20, 0x07); + gc4023_write_register(ViPipe, 0x061c, 0x50); + gc4023_write_register(ViPipe, 0x061d, 0x22); + gc4023_write_register(ViPipe, 0x061e, 0x78); + gc4023_write_register(ViPipe, 0x061f, 0x06); + gc4023_write_register(ViPipe, 0x0a21, 0x10); + gc4023_write_register(ViPipe, 0x0a34, 0x40); + gc4023_write_register(ViPipe, 0x0a35, 0x01); + gc4023_write_register(ViPipe, 0x0a36, 0x4e); + gc4023_write_register(ViPipe, 0x0a37, 0x06); + gc4023_write_register(ViPipe, 0x0314, 0x50); + gc4023_write_register(ViPipe, 0x0315, 0x00); + gc4023_write_register(ViPipe, 0x031c, 0xce); + gc4023_write_register(ViPipe, 0x0219, 0x47); + gc4023_write_register(ViPipe, 0x0342, 0x04); + gc4023_write_register(ViPipe, 0x0343, 0xb0); + gc4023_write_register(ViPipe, 0x0259, 0x05); + gc4023_write_register(ViPipe, 0x025a, 0xa0); + gc4023_write_register(ViPipe, 0x0340, 0x05); + gc4023_write_register(ViPipe, 0x0341, 0xdc); + gc4023_write_register(ViPipe, 0x0347, 0x02); + gc4023_write_register(ViPipe, 0x0348, 0x0a); + gc4023_write_register(ViPipe, 0x0349, 0x08); + gc4023_write_register(ViPipe, 0x034a, 0x05); + gc4023_write_register(ViPipe, 0x034b, 0xa8); + gc4023_write_register(ViPipe, 0x0094, 0x0a); + gc4023_write_register(ViPipe, 0x0095, 0x00); + gc4023_write_register(ViPipe, 0x0096, 0x05); + gc4023_write_register(ViPipe, 0x0097, 0xa0); + gc4023_write_register(ViPipe, 0x0099, 0x04); + gc4023_write_register(ViPipe, 0x009b, 0x04); + gc4023_write_register(ViPipe, 0x060c, 0x01); + gc4023_write_register(ViPipe, 0x060e, 0x08); + gc4023_write_register(ViPipe, 0x060f, 0x05); + gc4023_write_register(ViPipe, 0x070c, 0x01); + gc4023_write_register(ViPipe, 0x070e, 0x08); + gc4023_write_register(ViPipe, 0x070f, 0x05); + gc4023_write_register(ViPipe, 0x0909, 0x03); + gc4023_write_register(ViPipe, 0x0902, 0x04); + gc4023_write_register(ViPipe, 0x0904, 0x0b); + gc4023_write_register(ViPipe, 0x0907, 0x54); + gc4023_write_register(ViPipe, 0x0908, 0x06); + gc4023_write_register(ViPipe, 0x0903, 0x9d); + gc4023_write_register(ViPipe, 0x072a, 0x18); + gc4023_write_register(ViPipe, 0x0724, 0x0a); + gc4023_write_register(ViPipe, 0x0727, 0x0a); + gc4023_write_register(ViPipe, 0x072a, 0x1c); + gc4023_write_register(ViPipe, 0x072b, 0x0a); + gc4023_write_register(ViPipe, 0x1466, 0x10); + gc4023_write_register(ViPipe, 0x1468, 0x0b); + gc4023_write_register(ViPipe, 0x1467, 0x13); + gc4023_write_register(ViPipe, 0x1469, 0x80); + gc4023_write_register(ViPipe, 0x146a, 0xe8); + gc4023_write_register(ViPipe, 0x0707, 0x07); + gc4023_write_register(ViPipe, 0x0737, 0x0f); + gc4023_write_register(ViPipe, 0x0704, 0x01); + gc4023_write_register(ViPipe, 0x0706, 0x03); + gc4023_write_register(ViPipe, 0x0716, 0x03); + gc4023_write_register(ViPipe, 0x0708, 0xc8); + gc4023_write_register(ViPipe, 0x0718, 0xc8); + gc4023_write_register(ViPipe, 0x061a, 0x00); + gc4023_write_register(ViPipe, 0x1430, 0x80); + gc4023_write_register(ViPipe, 0x1407, 0x10); + gc4023_write_register(ViPipe, 0x1408, 0x16); + gc4023_write_register(ViPipe, 0x1409, 0x03); + gc4023_write_register(ViPipe, 0x146d, 0x0e); + gc4023_write_register(ViPipe, 0x146e, 0x42); + gc4023_write_register(ViPipe, 0x146f, 0x43); + gc4023_write_register(ViPipe, 0x1470, 0x3c); + gc4023_write_register(ViPipe, 0x1471, 0x3d); + gc4023_write_register(ViPipe, 0x1472, 0x3a); + gc4023_write_register(ViPipe, 0x1473, 0x3a); + gc4023_write_register(ViPipe, 0x1474, 0x40); + gc4023_write_register(ViPipe, 0x1475, 0x46); + gc4023_write_register(ViPipe, 0x1420, 0x14); + gc4023_write_register(ViPipe, 0x1464, 0x15); + gc4023_write_register(ViPipe, 0x146c, 0x40); + gc4023_write_register(ViPipe, 0x146d, 0x40); + gc4023_write_register(ViPipe, 0x1423, 0x08); + gc4023_write_register(ViPipe, 0x1428, 0x10); + gc4023_write_register(ViPipe, 0x1462, 0x18); + gc4023_write_register(ViPipe, 0x02ce, 0x04); + gc4023_write_register(ViPipe, 0x143a, 0x0f); + gc4023_write_register(ViPipe, 0x142b, 0x88); + gc4023_write_register(ViPipe, 0x0245, 0xc9); + gc4023_write_register(ViPipe, 0x023a, 0x08); + gc4023_write_register(ViPipe, 0x02cd, 0x99); + gc4023_write_register(ViPipe, 0x0612, 0x02); + gc4023_write_register(ViPipe, 0x0613, 0xc7); + gc4023_write_register(ViPipe, 0x0243, 0x03); + gc4023_write_register(ViPipe, 0x021b, 0x09); + gc4023_write_register(ViPipe, 0x0089, 0x03); + gc4023_write_register(ViPipe, 0x0040, 0xa3); + gc4023_write_register(ViPipe, 0x0075, 0x64); + gc4023_write_register(ViPipe, 0x0004, 0x0f); + gc4023_write_register(ViPipe, 0x0002, 0xab); + gc4023_write_register(ViPipe, 0x0053, 0x0a); + gc4023_write_register(ViPipe, 0x0205, 0x0c); + gc4023_write_register(ViPipe, 0x0202, 0x06); + gc4023_write_register(ViPipe, 0x0203, 0x27); + gc4023_write_register(ViPipe, 0x0614, 0x00); + gc4023_write_register(ViPipe, 0x0615, 0x00); + gc4023_write_register(ViPipe, 0x0181, 0x0c); + gc4023_write_register(ViPipe, 0x0182, 0x05); + gc4023_write_register(ViPipe, 0x0185, 0x01); + gc4023_write_register(ViPipe, 0x0180, 0x46); + gc4023_write_register(ViPipe, 0x0100, 0x08); + gc4023_write_register(ViPipe, 0x0106, 0x38); + gc4023_write_register(ViPipe, 0x010d, 0x80); + gc4023_write_register(ViPipe, 0x010e, 0x0c); + gc4023_write_register(ViPipe, 0x0113, 0x02); + gc4023_write_register(ViPipe, 0x0114, 0x01); + gc4023_write_register(ViPipe, 0x0115, 0x10); + gc4023_write_register(ViPipe, 0x022c, MIRROR); + gc4023_write_register(ViPipe, 0x0100, 0x09); + + gc4023_write_register(ViPipe, 0x0a67, 0x80); + gc4023_write_register(ViPipe, 0x0a54, 0x0e); + gc4023_write_register(ViPipe, 0x0a65, 0x10); + gc4023_write_register(ViPipe, 0x0a98, 0x10); + gc4023_write_register(ViPipe, 0x05be, 0x00); + gc4023_write_register(ViPipe, 0x05a9, 0x01); + gc4023_write_register(ViPipe, 0x0029, 0x08); + gc4023_write_register(ViPipe, 0x002b, 0xa8); + gc4023_write_register(ViPipe, 0x0a83, 0xe0); + gc4023_write_register(ViPipe, 0x0a72, 0x02); + gc4023_write_register(ViPipe, 0x0a73, OTP_MIRROR); + gc4023_write_register(ViPipe, 0x0a75, 0x41); + gc4023_write_register(ViPipe, 0x0a70, 0x03); + gc4023_write_register(ViPipe, 0x0a5a, 0x80); + usleep(20*1000); + gc4023_write_register(ViPipe, 0x05be, 0x01); + gc4023_write_register(ViPipe, 0x0a70, 0x00); + gc4023_write_register(ViPipe, 0x0080, 0x02); + gc4023_write_register(ViPipe, 0x0a67, 0x00); + + gc4023_default_reg_init(ViPipe); + usleep(10*1000); + + printf("ViPipe:%d,===GC4023 1440P 30fps 10bit LINEAR Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc4653/Makefile b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4653/Makefile new file mode 100644 index 000000000..553faf605 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4653/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc4653.a +TARGET_SO = $(MW_LIB)/libsns_gc4653.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc4653/gc4653_cmos.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4653/gc4653_cmos.c new file mode 100644 index 000000000..d09bdc86e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4653/gc4653_cmos.c @@ -0,0 +1,960 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "gc4653_cmos_ex.h" +#include "gc4653_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define GC4653_ID 4653 +#define GC4653_I2C_ADDR_1 0x10 +#define GC4653_I2C_ADDR_2 0x29 +#define GC4653_I2C_ADDR_IS_VALID(addr) ((addr) == GC4653_I2C_ADDR_1 || (addr) == GC4653_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ***************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc4653[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC4653_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc4653[dev]) +#define GC4653_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc4653[dev] = pstCtx) +#define GC4653_SENSOR_RESET_CTX(dev) (g_pastGc4653[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc4653_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 3}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc4653_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16Gc4653_GainMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ***************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Gc4653 Lines Range*****/ +#define GC4653_FULL_LINES_MAX (0x3fff) + +/*****Gc4653 Register Address*****/ +#define GC4653_EXP_H_ADDR 0x0202 //bit[13:8] +#define GC4653_EXP_L_ADDR 0x0203 + +#define GC4653_AGAIN_H_ADDR 0x02b4 //bit[10:8] +#define GC4653_AGAIN_L_ADDR 0x02b3 +#define GC4653_COL_AGAIN_H_ADDR 0x02b8 //bit[13:8] +#define GC4653_COL_AGAIN_L_ADDR 0x02b9 +#define GC4653_DGAIN_H_ADDR 0x020e //bit[9:6] +#define GC4653_DGAIN_L_ADDR 0x020f //bit[5:0] +#define GC4653_AGAIN_MAG1_ADDR 0x0515 +#define GC4653_AGAIN_MAG2_ADDR 0x0519 +#define GC4653_AGAIN_MAG3_ADDR 0x02d9 + +#define GC4653_VTS_H_ADDR 0x0340 //bit[13:8] +#define GC4653_VTS_L_ADDR 0x0341 + +#define GC4653_FLIP_MIRROR_ADDR 0x0101 +#define GC4653_FRAME_BUF_ADDR 0x031D + +#define GC4653_RES_IS_1440P(w, h) ((w) <= 2560 && (h) <= 1440) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC4653_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astGc4653_mode[GC4653_MODE_2560X1440P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astGc4653_mode[GC4653_MODE_2560X1440P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 77648; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 10240; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 2; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? + g_au32InitExposure[ViPipe] : g_astGc4653_mode[GC4653_MODE_2560X1440P30].stExp[0].u16Def; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstAeSnsDft->u32MinIntTime = g_astGc4653_mode[GC4653_MODE_2560X1440P30].stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astGc4653_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astGc4653_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astGc4653_mode[pstSnsState->u8ImgMode].f32MinFps; + + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + + u32VMAX = (u32VMAX > GC4653_FULL_LINES_MAX) ? GC4653_FULL_LINES_MAX : u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = ((u32IntTime[0] >> 8) & 0x3F); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_U32 regValTable[26][7] = { + /* [reg] 0x2b3, 0x2b4, 0x2b8, 0x2b9, 0x515, 0x519, 0x2d9 + * [name] AGAIN_L AGAIN_H COLGA_H COLGA_L MAG1 MAG2 MAG3 + */ + {0x00, 0x00, 0x01, 0x00, 0x30, 0x1e, 0x5C}, + {0x20, 0x00, 0x01, 0x0B, 0x30, 0x1e, 0x5C}, + {0x01, 0x00, 0x01, 0x19, 0x30, 0x1d, 0x5B}, + {0x21, 0x00, 0x01, 0x2A, 0x30, 0x1e, 0x5C}, + {0x02, 0x00, 0x02, 0x00, 0x30, 0x1e, 0x5C}, + {0x22, 0x00, 0x02, 0x17, 0x30, 0x1d, 0x5B}, + {0x03, 0x00, 0x02, 0x33, 0x20, 0x16, 0x54}, + {0x23, 0x00, 0x03, 0x14, 0x20, 0x17, 0x55}, + {0x04, 0x00, 0x04, 0x00, 0x20, 0x17, 0x55}, + {0x24, 0x00, 0x04, 0x2F, 0x20, 0x19, 0x57}, + {0x05, 0x00, 0x05, 0x26, 0x20, 0x19, 0x57}, + {0x25, 0x00, 0x06, 0x28, 0x20, 0x1b, 0x59}, + {0x0c, 0x00, 0x08, 0x00, 0x20, 0x1d, 0x5B}, + {0x2C, 0x00, 0x09, 0x1E, 0x20, 0x1f, 0x5D}, + {0x0D, 0x00, 0x0B, 0x0C, 0x20, 0x21, 0x5F}, + {0x2D, 0x00, 0x0D, 0x11, 0x20, 0x24, 0x62}, + {0x1C, 0x00, 0x10, 0x00, 0x20, 0x26, 0x64}, + {0x3C, 0x00, 0x12, 0x3D, 0x18, 0x2a, 0x68}, + {0x5C, 0x00, 0x16, 0x19, 0x18, 0x2c, 0x6A}, + {0x7C, 0x00, 0x1A, 0x22, 0x18, 0x2e, 0x6C}, + {0x9C, 0x00, 0x20, 0x00, 0x18, 0x32, 0x70}, + {0xBC, 0x00, 0x25, 0x3A, 0x18, 0x35, 0x73}, + {0xDC, 0x00, 0x2C, 0x33, 0x10, 0x36, 0x74}, + {0xFC, 0x00, 0x35, 0x05, 0x10, 0x38, 0x76}, + {0x1C, 0x01, 0x40, 0x00, 0x10, 0x3c, 0x7A}, + {0x3C, 0x01, 0x4B, 0x35, 0x10, 0x42, 0x80}, +}; + +static CVI_U32 gain_table[26] = { + 1024, 1200, 1424, 1696, 2048, 2416, 2864, 3392, 4096, 4848, 5728, + 6784, 8192, 9696, 11456, 13584, 16384, 19408, 22928, 27168, 32768, + 38816, 45872, 54352, 65536, 77648 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i, total; + CVI_U32 pregain; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + UNUSED(ViPipe); + total = sizeof(gain_table) / sizeof(CVI_U32); + + if (*pu32AgainLin >= gain_table[total - 1]) { + *pu32AgainLin = *pu32AgainDb = gain_table[total - 1]; + return CVI_SUCCESS; + } + + for (i = 1; i < total; i++) { + if (*pu32AgainLin < gain_table[i]) + break; + } + i--; + // find the pregain + pregain = *pu32AgainLin * 64 / gain_table[i]; + // set the Db as the AE algo gain, we need this to do gain update + *pu32AgainDb = *pu32AgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32AgainLin = pregain * gain_table[i] / 64; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 pregain; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + UNUSED(ViPipe); + // find the pregain + pregain = *pu32DgainLin * 64 / 1024; + // set the Db as the AE algo gain, we need this to do gain update + *pu32DgainDb = *pu32DgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32DgainLin = pregain * 16; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + int i, total; + + total = sizeof(gain_table) / sizeof(CVI_U32); + + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* only surpport linear mode */ + u32Again = pu32Again[0]; + /* To kepp the linearity. we assume AE algo adjusts the dgain only when the again reachs the maximum value */ + if (u32Again < (77648)) { + for (i = 1; i < total; i++) { + if (*pu32Again < gain_table[i]) + break; + } + i--; + // find the pregain + u32Dgain = u32Again * 64 / gain_table[i]; + u32Again = i; + } else { + u32Again = total - 1; + // find the pregain + u32Dgain = pu32Dgain[0] * 64 / 1024; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][0]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][1]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][2]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][3]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG1].u32Data = regValTable[u32Again][4]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG2].u32Data = regValTable[u32Again][5]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG3].u32Data = regValTable[u32Again][6]; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 6); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + UNUSED(ViPipe); + UNUSED(u16ManRatioEnable); + UNUSED(au32Ratio); + UNUSED(au32IntTimeMax); + UNUSED(au32IntTimeMin); + UNUSED(pu32LFMaxIntTime); + + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode\n"); + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + UNUSED(ViPipe); + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + UNUSED(ViPipe); + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + CMOS_CHECK_POINTER(pstBlc); + UNUSED(ViPipe); + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC4653_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astGc4653_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + UNUSED(ViPipe); + UNUSED(u8Mode); + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunGc4653_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = gc4653_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc4653_addr_byte; + pstI2c_data[i].u32DataByteNum = gc4653_data_byte; + } + + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC4653_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC4653_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC4653_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC4653_AGAIN_L_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC4653_COL_AGAIN_H_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC4653_COL_AGAIN_L_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG1].u32RegAddr = GC4653_AGAIN_MAG1_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG2].u32RegAddr = GC4653_AGAIN_MAG2_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG3].u32RegAddr = GC4653_AGAIN_MAG3_ADDR; + pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC4653_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC4653_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC4653_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC4653_VTS_L_ADDR; + pstI2c_data[LINEAR_FLIP_MIRROR].u32RegAddr = GC4653_FLIP_MIRROR_ADDR; + pstI2c_data[LINEAR_FRAME_BUF_ON].u32RegAddr = GC4653_FRAME_BUF_ADDR; + pstI2c_data[LINEAR_FRAME_BUF_ON].u32Data = 0x2D; + pstI2c_data[LINEAR_FRAME_BUF_OFF].u32RegAddr = GC4653_FRAME_BUF_ADDR; + pstI2c_data[LINEAR_FRAME_BUF_OFF].u32Data = 0x28; + + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + + CVI_U32 gainsUpdate = 0, shutterUpdate = 0, vtsUpdate = 0; + + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + + if ((i >= LINEAR_AGAIN_H) && (i <= LINEAR_DGAIN_L)) + gainsUpdate = 1; + + if (i <= LINEAR_EXP_L) + shutterUpdate = 1; + + if ((i >= LINEAR_VTS_H) && (i <= LINEAR_VTS_L)) + vtsUpdate = 1; + + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (gainsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG1].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG2].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG3].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L].bUpdate = CVI_TRUE; + } + if (shutterUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_L].bUpdate = CVI_TRUE; + } + if (vtsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_VTS_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_VTS_L].bUpdate = CVI_TRUE; + } + if (pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR].bUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_FRAME_BUF_ON].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_FRAME_BUF_OFF].bUpdate = CVI_TRUE; + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = CVI_FALSE; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC4653_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC4653_MODE_2560X1440P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U8 value; + + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc4653_MirrorFip[ViPipe] != eSnsMirrorFlip) { + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + value = 0; + break; + case ISP_SNS_MIRROR: + value = 1; + break; + case ISP_SNS_FLIP: + value = 2; + break; + case ISP_SNS_MIRROR_FLIP: + value = 3; + break; + default: + return; + } + + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u8DropFrmNum = 2; + g_aeGc4653_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC4653_MODE_2560X1440P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astGc4653_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astGc4653_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astGc4653_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc4653_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astGc4653_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astGc4653_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc4653_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc4653_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc4653_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (GC4653_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc4653_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc4653_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc4653_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC4653_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC4653_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC4653_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC4653_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC4653_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC4653_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC4653_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC4653_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Gc4653_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc4653_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc4653_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc4653_standby, + .pfnRestart = gc4653_restart, + .pfnWriteReg = gc4653_write_register, + .pfnReadReg = gc4653_read_register, + .pfnSetBusInfo = gc4653_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc4653/gc4653_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4653/gc4653_cmos_ex.h new file mode 100644 index 000000000..eb04a9fb5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4653/gc4653_cmos_ex.h @@ -0,0 +1,93 @@ +#ifndef __GC4653_CMOS_EX_H_ +#define __GC4653_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum gc4653_linear_regs_e { + LINEAR_EXP_H, //0x0202 bit[13:8] + LINEAR_EXP_L, //0x0203 + LINEAR_AGAIN_L, //0x02b3 + LINEAR_AGAIN_H, //0x02b4 bit[10:8] + LINEAR_COL_AGAIN_H, //0x02b8 bit[13:8] + LINEAR_COL_AGAIN_L, //0x02b9 + LINEAR_AGAIN_MAG1, //0x0515 + LINEAR_AGAIN_MAG2, //0x0519 + LINEAR_AGAIN_MAG3, //0x02d9 + LINEAR_DGAIN_H, //0x020e bit[9:6] + LINEAR_DGAIN_L, //0x020f bit[5:0] + LINEAR_VTS_H, //0x0341 bit[13:8] + LINEAR_VTS_L, //0x0342 + LINEAR_FRAME_BUF_ON,//0x031D + LINEAR_FLIP_MIRROR, + LINEAR_FRAME_BUF_OFF,//0x031D + LINEAR_REGS_NUM +}; + +typedef enum _GC4653_MODE_E { + GC4653_MODE_2560X1440P30 = 0, + GC4653_MODE_LINEAR_NUM, + GC4653_MODE_NUM +} GC4653_MODE_E; + +typedef struct _GC4653_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC4653_STATE_S; + +typedef struct _GC4653_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} GC4653_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc4653[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc4653_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc4653_MirrorFip[VI_MAX_PIPE_NUM]; +extern CVI_U8 gc4653_i2c_addr; +extern const CVI_U32 gc4653_addr_byte; +extern const CVI_U32 gc4653_data_byte; +extern void gc4653_init(VI_PIPE ViPipe); +extern void gc4653_exit(VI_PIPE ViPipe); +extern void gc4653_standby(VI_PIPE ViPipe); +extern void gc4653_restart(VI_PIPE ViPipe); +extern int gc4653_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc4653_read_register(VI_PIPE ViPipe, int addr); +extern int gc4653_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC4653_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc4653/gc4653_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4653/gc4653_cmos_param.h new file mode 100644 index 000000000..72cab59d5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4653/gc4653_cmos_param.h @@ -0,0 +1,222 @@ +#ifndef __GC4653_CMOS_PARAM_H_ +#define __GC4653_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc4653_cmos_ex.h" + +static const GC4653_MODE_S g_astGc4653_mode[GC4653_MODE_NUM] = { + [GC4653_MODE_2560X1440P30] = { + .name = "2560X1440P30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.75, /* 1500 * 30 / 16383 */ + .u32HtsDef = 2200, + .u32VtsDef = 1500, + .stExp[0] = { + .u16Min = 1, + .u16Max = 0x3fff, + .u16Def = 0x2000, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 77648, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16368, + .u32Def = 1024, + .u32Step = 64, + }, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.04006369039416313171, 5.73531675338745117188}, //B: slope, intercept + {0.03064448758959770203, 8.56994438171386718750}, //Gb: slope, intercept + {0.03068985790014266968, 8.82220363616943359375}, //Gr: slope, intercept + {0.03361049667000770569, 7.20687675476074218750}, //R: slope, intercept + }, + { //iso 200 + {0.05054308474063873291, 7.91628408432006835938}, //B: slope, intercept + {0.03632996603846549988, 13.05291843414306640625}, //Gb: slope, intercept + {0.03697143867611885071, 12.49540805816650390625}, //Gr: slope, intercept + {0.04156460240483283997, 10.44298553466796875000}, //R: slope, intercept + }, + { //iso 400 + {0.06805337965488433838, 11.55693244934082031250}, //B: slope, intercept + {0.04390667378902435303, 18.59673881530761718750}, //Gb: slope, intercept + {0.04630871489644050598, 17.90183258056640625000}, //Gr: slope, intercept + {0.05292420834302902222, 15.17318439483642578125}, //R: slope, intercept + }, + { //iso 800 + {0.08635756373405456543, 17.79124641418457031250}, //B: slope, intercept + {0.05776864662766456604, 26.76541900634765625000}, //Gb: slope, intercept + {0.05839699879288673401, 26.44194030761718750000}, //Gr: slope, intercept + {0.06750740110874176025, 22.42554473876953125000}, //R: slope, intercept + }, + { //iso 1600 + {0.12254384160041809082, 26.20610046386718750000}, //B: slope, intercept + {0.07916855812072753906, 39.39273834228515625000}, //Gb: slope, intercept + {0.07857896387577056885, 39.03499984741210937500}, //Gr: slope, intercept + {0.09273355454206466675, 33.09597778320312500000}, //R: slope, intercept + }, + { //iso 3200 + {0.18002016842365264893, 34.86975860595703125000}, //B: slope, intercept + {0.10951708257198333740, 54.58878326416015625000}, //Gb: slope, intercept + {0.10485322028398513794, 57.16654205322265625000}, //Gr: slope, intercept + {0.13257601857185363770, 46.27093505859375000000}, //R: slope, intercept + }, + { //iso 6400 + {0.24713687598705291748, 48.62341690063476562500}, //B: slope, intercept + {0.14974890649318695068, 77.06428527832031250000}, //Gb: slope, intercept + {0.14544390141963958740, 76.57913970947265625000}, //Gr: slope, intercept + {0.19056233763694763184, 62.13500213623046875000}, //R: slope, intercept + }, + { //iso 12800 + {0.37728109955787658691, 58.15543365478515625000}, //B: slope, intercept + {0.20440576970577239990, 100.45700073242187500000}, //Gb: slope, intercept + {0.20059910416603088379, 102.35488891601562500000}, //Gr: slope, intercept + {0.27388775348663330078, 79.65499877929687500000}, //R: slope, intercept + }, + { //iso 25600 + {0.36612421274185180664, 115.28938293457031250000}, //B: slope, intercept + {0.22633622586727142334, 164.58416748046875000000}, //Gb: slope, intercept + {0.21590474247932434082, 168.92042541503906250000}, //Gr: slope, intercept + {0.33193346858024597168, 127.92090606689453125000}, //R: slope, intercept + }, + { //iso 51200 + {0.48242908716201782227, 147.39015197753906250000}, //B: slope, intercept + {0.28994381427764892578, 223.02711486816406250000}, //Gb: slope, intercept + {0.29200506210327148438, 220.64030456542968750000}, //Gr: slope, intercept + {0.42304891347885131836, 173.74638366699218750000}, //R: slope, intercept + }, + { //iso 102400 + {0.62099909782409667969, 130.97862243652343750000}, //B: slope, intercept + {0.39534106850624084473, 219.74490356445312500000}, //Gb: slope, intercept + {0.39458695054054260254, 213.37374877929687500000}, //Gr: slope, intercept + {0.55690109729766845703, 158.37773132324218750000}, //R: slope, intercept + }, + { //iso 204800 + {0.75350415706634521484, 77.81707000732421875000}, //B: slope, intercept + {0.52716732025146484375, 148.77879333496093750000}, //Gb: slope, intercept + {0.51073729991912841797, 153.86495971679687500000}, //Gr: slope, intercept + {0.68910604715347290039, 102.12422180175781250000}, //R: slope, intercept + }, + { //iso 409600 + {0.90276730060577392578, 43.78258514404296875000}, //B: slope, intercept + {0.62851423025131225586, 119.41429138183593750000}, //Gb: slope, intercept + {0.64918899536132812500, 110.74241638183593750000}, //Gr: slope, intercept + {0.80880594253540039063, 68.89983367919921875000}, //R: slope, intercept + }, + { //iso 819200 + {0.90276730060577392578, 43.78258514404296875000}, //B: slope, intercept + {0.62851423025131225586, 119.41429138183593750000}, //Gb: slope, intercept + {0.64918899536132812500, 110.74241638183593750000}, //Gr: slope, intercept + {0.80880594253540039063, 68.89983367919921875000}, //R: slope, intercept + }, + { //iso 1638400 + {0.90276730060577392578, 43.78258514404296875000}, //B: slope, intercept + {0.62851423025131225586, 119.41429138183593750000}, //Gb: slope, intercept + {0.64918899536132812500, 110.74241638183593750000}, //Gr: slope, intercept + {0.80880594253540039063, 68.89983367919921875000}, //R: slope, intercept + }, + { //iso 3276800 + {0.90276730060577392578, 43.78258514404296875000}, //B: slope, intercept + {0.62851423025131225586, 119.41429138183593750000}, //Gb: slope, intercept + {0.64918899536132812500, 110.74241638183593750000}, //Gr: slope, intercept + {0.80880594253540039063, 68.89983367919921875000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {255, 256, 256, 257, 260, 264, 272, 289, 324, 400, 468, 474, 475, 476, 466, 496 }, + {255, 256, 256, 257, 260, 264, 272, 289, 325, 404, 469, 476, 477, 477, 467, 493 }, + {255, 256, 256, 257, 260, 264, 272, 289, 325, 401, 468, 477, 476, 477, 467, 495 }, + {255, 256, 256, 257, 260, 264, 272, 290, 325, 404, 471, 477, 478, 478, 468, 493 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1092, 1092, 1093, 1093, 1095, 1097, 1102, 1112, 1135, 1156, 1158, 1158, 1159, + 1155, 1165}, + {1092, 1092, 1092, 1093, 1093, 1095, 1097, 1102, 1112, 1136, 1156, 1159, 1159, 1159, + 1156, 1164}, + {1092, 1092, 1092, 1093, 1093, 1095, 1097, 1102, 1112, 1135, 1156, 1159, 1159, 1159, + 1156, 1165}, + {1092, 1092, 1092, 1093, 1093, 1095, 1097, 1102, 1112, 1136, 1157, 1159, 1159, 1159, + 1156, 1164}, +#endif + }, + }, +}; + +struct combo_dev_attr_s gc4653_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 1, 3, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC4653_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc4653/gc4653_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4653/gc4653_sensor_ctl.c new file mode 100644 index 000000000..99ab959d6 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc4653/gc4653_sensor_ctl.c @@ -0,0 +1,388 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc4653_cmos_ex.h" + +#define GC4653_CHIP_ID_ADDR_H 0x03f0 +#define GC4653_CHIP_ID_ADDR_L 0x03f1 +#define GC4653_CHIP_ID 0x4653 + +static void gc4653_linear_1440p30_init(VI_PIPE ViPipe); + +CVI_U8 gc4653_i2c_addr = 0x10; +const CVI_U32 gc4653_addr_byte = 2; +const CVI_U32 gc4653_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc4653_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc4653_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc4653_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc4653_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc4653_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (gc4653_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc4653_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, gc4653_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc4653_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int gc4653_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc4653_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + if (gc4653_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc4653_addr_byte + gc4653_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + ret = read(g_fd[ViPipe], buf, gc4653_addr_byte + gc4653_data_byte); + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void gc4653_standby(VI_PIPE ViPipe) +{ + gc4653_write_register(ViPipe, 0x0100, 0x00); + gc4653_write_register(ViPipe, 0x031c, 0xc7); + gc4653_write_register(ViPipe, 0x0317, 0x01); + + printf("gc4653_standby\n"); +} + +void gc4653_restart(VI_PIPE ViPipe) +{ + gc4653_write_register(ViPipe, 0x0317, 0x00); + gc4653_write_register(ViPipe, 0x031c, 0xc6); + gc4653_write_register(ViPipe, 0x0100, 0x09); + + printf("gc4653_restart\n"); +} + +void gc4653_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc4653[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc4653_write_register(ViPipe, + g_pastGc4653[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc4653[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +int gc4653_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc4653_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc4653_read_register(ViPipe, GC4653_CHIP_ID_ADDR_H); + nVal2 = gc4653_read_register(ViPipe, GC4653_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC4653_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc4653_init(VI_PIPE ViPipe) +{ + gc4653_i2c_init(ViPipe); + + gc4653_linear_1440p30_init(ViPipe); + + g_pastGc4653[ViPipe]->bInit = CVI_TRUE; +} + +void gc4653_exit(VI_PIPE ViPipe) +{ + gc4653_i2c_exit(ViPipe); +} + +static void gc4653_linear_1440p30_init(VI_PIPE ViPipe) +{ + delay_ms(10); + /****system****/ + gc4653_write_register(ViPipe, 0x03fe, 0xf0); + gc4653_write_register(ViPipe, 0x03fe, 0x00); + gc4653_write_register(ViPipe, 0x0317, 0x00); + gc4653_write_register(ViPipe, 0x0320, 0x77); + gc4653_write_register(ViPipe, 0x0324, 0xc8); + gc4653_write_register(ViPipe, 0x0325, 0x06); + gc4653_write_register(ViPipe, 0x0326, 0x60); + gc4653_write_register(ViPipe, 0x0327, 0x03); + gc4653_write_register(ViPipe, 0x0334, 0x40); + gc4653_write_register(ViPipe, 0x0336, 0x60); + gc4653_write_register(ViPipe, 0x0337, 0x82); + gc4653_write_register(ViPipe, 0x0315, 0x25); + gc4653_write_register(ViPipe, 0x031c, 0xc6); + /****************************************/ + /*frame structure*/ + /****************************************/ + gc4653_write_register(ViPipe, 0x0287, 0x18); + gc4653_write_register(ViPipe, 0x0084, 0x00); + gc4653_write_register(ViPipe, 0x0087, 0x50); + gc4653_write_register(ViPipe, 0x029d, 0x08); + gc4653_write_register(ViPipe, 0x0290, 0x00); + /**********AHD 30 other need change ******************/ + gc4653_write_register(ViPipe, 0x0340, 0x05); + gc4653_write_register(ViPipe, 0x0341, 0xdc); + gc4653_write_register(ViPipe, 0x0345, 0x06); + gc4653_write_register(ViPipe, 0x034b, 0xb0); + gc4653_write_register(ViPipe, 0x0352, 0x08); + gc4653_write_register(ViPipe, 0x0354, 0x08); + /****************************************/ + /*ANALOG CIRCUIT*/ + /****************************************/ + gc4653_write_register(ViPipe, 0x02d1, 0xe0); + gc4653_write_register(ViPipe, 0x0223, 0xf2); + gc4653_write_register(ViPipe, 0x0238, 0xa4); + gc4653_write_register(ViPipe, 0x02ce, 0x7f); + gc4653_write_register(ViPipe, 0x0232, 0xc4); + gc4653_write_register(ViPipe, 0x02d3, 0x05); + gc4653_write_register(ViPipe, 0x0243, 0x06); + gc4653_write_register(ViPipe, 0x02ee, 0x30); + gc4653_write_register(ViPipe, 0x026f, 0x70); + gc4653_write_register(ViPipe, 0x0257, 0x09); + gc4653_write_register(ViPipe, 0x0211, 0x02); + gc4653_write_register(ViPipe, 0x0219, 0x09); + gc4653_write_register(ViPipe, 0x023f, 0x2d); + gc4653_write_register(ViPipe, 0x0518, 0x00); + gc4653_write_register(ViPipe, 0x0519, 0x01); + gc4653_write_register(ViPipe, 0x0515, 0x08); + gc4653_write_register(ViPipe, 0x02d9, 0x3f); + gc4653_write_register(ViPipe, 0x02da, 0x02); + gc4653_write_register(ViPipe, 0x02db, 0xe8); + gc4653_write_register(ViPipe, 0x02e6, 0x20); + gc4653_write_register(ViPipe, 0x021b, 0x10); + gc4653_write_register(ViPipe, 0x0252, 0x22); + gc4653_write_register(ViPipe, 0x024e, 0x22); + gc4653_write_register(ViPipe, 0x02c4, 0x01); + gc4653_write_register(ViPipe, 0x021d, 0x17); + gc4653_write_register(ViPipe, 0x024a, 0x01); + gc4653_write_register(ViPipe, 0x02ca, 0x02); + gc4653_write_register(ViPipe, 0x0262, 0x10); + gc4653_write_register(ViPipe, 0x029a, 0x20); + gc4653_write_register(ViPipe, 0x021c, 0x0e); + gc4653_write_register(ViPipe, 0x0298, 0x03); + gc4653_write_register(ViPipe, 0x029c, 0x00); + gc4653_write_register(ViPipe, 0x027e, 0x14); + gc4653_write_register(ViPipe, 0x02c2, 0x10); + gc4653_write_register(ViPipe, 0x0540, 0x20); + gc4653_write_register(ViPipe, 0x0546, 0x01); + gc4653_write_register(ViPipe, 0x0548, 0x01); + gc4653_write_register(ViPipe, 0x0544, 0x01); + gc4653_write_register(ViPipe, 0x0242, 0x1b); + gc4653_write_register(ViPipe, 0x02c0, 0x1b); + gc4653_write_register(ViPipe, 0x02c3, 0x20); + gc4653_write_register(ViPipe, 0x02e4, 0x10); + gc4653_write_register(ViPipe, 0x022e, 0x00); + gc4653_write_register(ViPipe, 0x027b, 0x3f); + gc4653_write_register(ViPipe, 0x0269, 0x0f); + gc4653_write_register(ViPipe, 0x02d2, 0x40); + gc4653_write_register(ViPipe, 0x027c, 0x08); + gc4653_write_register(ViPipe, 0x023a, 0x2e); + gc4653_write_register(ViPipe, 0x0245, 0xce); + gc4653_write_register(ViPipe, 0x0530, 0x20); + gc4653_write_register(ViPipe, 0x0531, 0x02); + gc4653_write_register(ViPipe, 0x0228, 0x50); + gc4653_write_register(ViPipe, 0x02ab, 0x00); + gc4653_write_register(ViPipe, 0x0250, 0x00); + gc4653_write_register(ViPipe, 0x0221, 0x50); + gc4653_write_register(ViPipe, 0x02ac, 0x00); + gc4653_write_register(ViPipe, 0x02a5, 0x02); + gc4653_write_register(ViPipe, 0x0260, 0x0b); + gc4653_write_register(ViPipe, 0x0216, 0x04); + gc4653_write_register(ViPipe, 0x0299, 0x1C); + gc4653_write_register(ViPipe, 0x02bb, 0x0d); + gc4653_write_register(ViPipe, 0x02a3, 0x02); + gc4653_write_register(ViPipe, 0x02a4, 0x02); + gc4653_write_register(ViPipe, 0x021e, 0x02); + gc4653_write_register(ViPipe, 0x024f, 0x08); + gc4653_write_register(ViPipe, 0x028c, 0x08); + gc4653_write_register(ViPipe, 0x0532, 0x3f); + gc4653_write_register(ViPipe, 0x0533, 0x02); + gc4653_write_register(ViPipe, 0x0277, 0xc0); + gc4653_write_register(ViPipe, 0x0276, 0xc0); + gc4653_write_register(ViPipe, 0x0239, 0xc0); + /*exp*/ + gc4653_write_register(ViPipe, 0x0202, 0x05); + gc4653_write_register(ViPipe, 0x0203, 0x46); + /*gain*/ + gc4653_write_register(ViPipe, 0x0205, 0xc0); + gc4653_write_register(ViPipe, 0x02b0, 0x68); + /*dpc*/ + gc4653_write_register(ViPipe, 0x0002, 0xa9); + gc4653_write_register(ViPipe, 0x0004, 0x01); + /*dark_sun*/ + gc4653_write_register(ViPipe, 0x021a, 0x98); + gc4653_write_register(ViPipe, 0x0266, 0xa0); + gc4653_write_register(ViPipe, 0x0020, 0x01); + gc4653_write_register(ViPipe, 0x0021, 0x03); + gc4653_write_register(ViPipe, 0x0022, 0x00); + gc4653_write_register(ViPipe, 0x0023, 0x04); + /****************************************/ + /*mipi*/ + /****************************************/ + /*********** AHD 30 ******************/ + /*30fps*/ + gc4653_write_register(ViPipe, 0x0342, 0x06); + gc4653_write_register(ViPipe, 0x0343, 0x40); + /*30fps*/ + gc4653_write_register(ViPipe, 0x03fe, 0x10); + gc4653_write_register(ViPipe, 0x03fe, 0x00); + gc4653_write_register(ViPipe, 0x0106, 0x78); + gc4653_write_register(ViPipe, 0x0108, 0x0c); + gc4653_write_register(ViPipe, 0x0114, 0x01); + gc4653_write_register(ViPipe, 0x0115, 0x12); + gc4653_write_register(ViPipe, 0x0180, 0x46); + gc4653_write_register(ViPipe, 0x0181, 0x30); + gc4653_write_register(ViPipe, 0x0182, 0x05); + gc4653_write_register(ViPipe, 0x0185, 0x01); + gc4653_write_register(ViPipe, 0x03fe, 0x10); + gc4653_write_register(ViPipe, 0x03fe, 0x00); + gc4653_write_register(ViPipe, 0x0100, 0x09); + // 0x008e = 0x00, which means disabling bayer transformation when flip/mirroring + //gc4653_write_register(ViPipe, 0x008e, 0x00); + //fix FPN + gc4653_write_register(ViPipe, 0x0277, 0x38); + gc4653_write_register(ViPipe, 0x0276, 0xc0); + gc4653_write_register(ViPipe, 0x000f, 0x10); + gc4653_write_register(ViPipe, 0x0059, 0x00);//close dither + //otp + gc4653_write_register(ViPipe, 0x0080, 0x02); + gc4653_write_register(ViPipe, 0x0097, 0x0a); + gc4653_write_register(ViPipe, 0x0098, 0x10); + gc4653_write_register(ViPipe, 0x0099, 0x05); + gc4653_write_register(ViPipe, 0x009a, 0xb0); + gc4653_write_register(ViPipe, 0x0317, 0x08); + gc4653_write_register(ViPipe, 0x0a67, 0x80); + gc4653_write_register(ViPipe, 0x0a70, 0x03); + gc4653_write_register(ViPipe, 0x0a82, 0x00); + gc4653_write_register(ViPipe, 0x0a83, 0x10); + gc4653_write_register(ViPipe, 0x0a80, 0x2b); + gc4653_write_register(ViPipe, 0x05be, 0x00); + gc4653_write_register(ViPipe, 0x05a9, 0x01); + gc4653_write_register(ViPipe, 0x0313, 0x80); + gc4653_write_register(ViPipe, 0x05be, 0x01); + gc4653_write_register(ViPipe, 0x0317, 0x00); + gc4653_write_register(ViPipe, 0x0a67, 0x00); + + gc4653_default_reg_init(ViPipe); + delay_ms(10); + + printf("ViPipe:%d,===GC4653 1440P 30fps 10bit LINEAR Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/nextchip_n5/Makefile b/middleware/v2/component/isp/sensor/cv181x/nextchip_n5/Makefile new file mode 100644 index 000000000..a9cbf405d --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/nextchip_n5/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_n5.a +TARGET_SO = $(MW_LIB)/libsns_n5.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/nextchip_n5/n5_cmos.c b/middleware/v2/component/isp/sensor/cv181x/nextchip_n5/n5_cmos.c new file mode 100644 index 000000000..10f1f45e0 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/nextchip_n5/n5_cmos.c @@ -0,0 +1,290 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_isp.h" + +#include "n5_cmos_ex.h" +#include "n5_cmos_param.h" + +/**************************************************************************** + * global variables * + ****************************************************************************/ +ISP_SNS_COMMBUS_U g_aunN5_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_STATE_S *g_pastN5[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define N5_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastN5[dev]) +#define N5_SENSOR_SET_CTX(dev, pstCtx) (g_pastN5[dev] = pstCtx) +#define N5_SENSOR_RESET_CTX(dev) (g_pastN5[dev] = CVI_NULL) +#define N5_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) +#define N5_ID 0xE0 + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const N5_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + N5_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astN5_mode[pstSnsState->u8ImgMode]; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + N5_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstCfg0 = &pstSnsState->astSyncInfo[0]; + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + N5_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + + if (pstSensorImageMode->f32Fps <= 30) { + if (N5_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = N5_MODE_1080P_25P; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + N5_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->u8ImgMode = N5_MODE_1080P_25P; + pstSnsState->enWDRMode = WDR_MODE_NONE; +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + N5_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &n5_rx_attr, sizeof(*pstRxAttr)); + CVI_TRACE_SNS(CVI_DBG_ERR, "get n5_rx0_attr\n"); + + pstRxAttr->img_size.width = g_astN5_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astN5_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &n5_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = n5_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = n5_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 n5_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunN5_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + N5_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + N5_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + N5_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + N5_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + (void) pstAeLib; + (void) pstAwbLib; + + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = N5_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + (void) pstAeLib; + (void) pstAwbLib; + + CVI_S32 s32Ret; + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, N5_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsN5_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnMirrorFlip = CVI_NULL, + .pfnStandby = CVI_NULL, + .pfnRestart = CVI_NULL, + .pfnWriteReg = n5_write_register, + .pfnReadReg = n5_read_register, + .pfnSetBusInfo = n5_set_bus_info, + .pfnSetInit = CVI_NULL, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = CVI_NULL, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/nextchip_n5/n5_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/nextchip_n5/n5_cmos_ex.h new file mode 100644 index 000000000..1edfdcaa9 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/nextchip_n5/n5_cmos_ex.h @@ -0,0 +1,89 @@ +#ifndef __N5_CMOS_EX_H_ +#define __N5_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +typedef enum _N5_MODE_E { + N5_MODE_H720_NT = 1, + N5_MODE_H720_PAL, + N5_MODE_720P_30P, + N5_MODE_720P_25P, + N5_MODE_960P_30P, + N5_MODE_960P_25P, + N5_MODE_1080P_30P, + N5_MODE_1080P_25P, + N5_MODE_1080P_60P, + N5_MODE_1080P_50P, + N5_MODE_4M_30P, + N5_MODE_4M_25P, + N5_MODE_8M_15P, + N5_MODE_8M_12_5P, + N5_MODE_NUM +} N5_MODE_E; + +typedef enum _n5_outmode_sel { + N5_OUTMODE_1MUX_SD = 0, + N5_OUTMODE_1MUX_HD, + N5_OUTMODE_1MUX_FHD, + N5_OUTMODE_1MUX_FHD_HALF, + N5_OUTMODE_2MUX_SD, + N5_OUTMODE_2MUX_HD, + N5_OUTMODE_2MUX_FHD, + N5_OUTMODE_1MUX_BT1120S, + N5_OUTMODE_2MUX_BT1120S_720P, + N5_OUTMODE_2MUX_BT1120S_1080P, + N5_OUTMODE_BUTT +} N5_OUTMODE_SEL; + +typedef struct _N5_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + char name[64]; +} N5_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastN5[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunN5_BusInfo[]; +extern const CVI_U8 n5_i2c_addr; +extern const CVI_U32 n5_addr_byte; +extern const CVI_U32 n5_data_byte; +extern void n5_init(VI_PIPE ViPipe); +extern void n5_exit(VI_PIPE ViPipe); +extern void n5_standby(VI_PIPE ViPipe); +extern void n5_restart(VI_PIPE ViPipe); +extern int n5_write_register(VI_PIPE ViPipe, int addr, int data); +extern int n5_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __N5_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/nextchip_n5/n5_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/nextchip_n5/n5_cmos_param.h new file mode 100644 index 000000000..088dfe8c5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/nextchip_n5/n5_cmos_param.h @@ -0,0 +1,100 @@ +#ifndef __N5_CMOS_PARAM_H_ +#define __N5_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "n5_cmos_ex.h" + +static const N5_MODE_S g_astN5_mode[N5_MODE_NUM] = { + [N5_MODE_1080P_25P] = { + .name = "1080p25", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + }, +}; + +struct combo_dev_attr_s n5_rx_attr = { + .input_mode = INPUT_MODE_BT_DEMUX, + .mac_clk = RX_MAC_CLK_400M, + .mclk = { + .cam = 1, + .freq = CAMPLL_FREQ_27M, + }, + .bt_demux_attr = { + .func = { + -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, + -1, -1, -1, -1, + -1, -1, -1, -1 + }, + .v_fp = 0xF, + .h_fp = 0xF, + .v_bp = 0, + .h_bp = 0, + .mode = BT_DEMUX_2, + .sync_code_part_A = {0xFF, 0, 0}, + .sync_code_part_B[0] = { + .sav_vld = 0x80, + .sav_blk = 0xa0, + .eav_vld = 0x90, + .eav_blk = 0xb0, + }, + .sync_code_part_B[1] = { + .sav_vld = 0x81, + .sav_blk = 0xa1, + .eav_vld = 0x91, + .eav_blk = 0xb1, + }, + .sync_code_part_B[2] = { + .sav_vld = 0x82, + .sav_blk = 0xa2, + .eav_vld = 0x92, + .eav_blk = 0xb2, + }, + .sync_code_part_B[3] = { + .sav_vld = 0x83, + .sav_blk = 0xa3, + .eav_vld = 0x93, + .eav_blk = 0xb3, + }, + .yc_exchg = 0xF, + }, + .devno = 0, // btdemux must use mac0 +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __N5_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/nextchip_n5/n5_sensor_ctrl.c b/middleware/v2/component/isp/sensor/cv181x/nextchip_n5/n5_sensor_ctrl.c new file mode 100644 index 000000000..bfa617812 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/nextchip_n5/n5_sensor_ctrl.c @@ -0,0 +1,1218 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "n5_cmos_ex.h" +#include +#include + +const CVI_U8 n5_i2c_addr = 0x32; /* I2C slave address of N5, SA0=0:0x32, SA0=1:0x33*/ +const CVI_U32 n5_addr_byte = 1; +const CVI_U32 n5_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; +static pthread_t g_n5_thid; +unsigned char chn_mode[2] = {0xEE, 0xEE}; + +#define N5_TEST_PATTERN 1 + +int n5_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunN5_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + syslog(LOG_DEBUG, "open %s\n", acDevFile); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, n5_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int n5_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int n5_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return 0; + + if (n5_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, n5_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, n5_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (n5_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int n5_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (n5_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + if (n5_data_byte == 2) + buf[idx++] = (data >> 8) & 0xff; + + // add data byte 0 + buf[idx++] = data & 0xff; + + ret = write(g_fd[ViPipe], buf, n5_addr_byte + n5_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + +#if 0 // read back checing + ret = n5_read_register(ViPipe, addr); + if (ret != data) + syslog(LOG_DEBUG, "i2c readback-check fail, 0x%x != 0x%x\n", ret, data); +#endif + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void n5_common_setting(VI_PIPE ViPipe) +{ + n5_write_register(ViPipe, 0xff, 0x00); + n5_write_register(ViPipe, 0x00, 0x10); + n5_write_register(ViPipe, 0x01, 0x10); + n5_write_register(ViPipe, 0x18, 0x3f); + n5_write_register(ViPipe, 0x19, 0x3f); + n5_write_register(ViPipe, 0x22, 0x0b); + n5_write_register(ViPipe, 0x23, 0x41); + n5_write_register(ViPipe, 0x26, 0x0b); + n5_write_register(ViPipe, 0x27, 0x41); + n5_write_register(ViPipe, 0x54, 0x00); + n5_write_register(ViPipe, 0xa0, 0x05); + n5_write_register(ViPipe, 0xa1, 0x05); + n5_write_register(ViPipe, 0xff, 0x01); + n5_write_register(ViPipe, 0x97, 0x00); + n5_write_register(ViPipe, 0x97, 0x0f); + n5_write_register(ViPipe, 0x7A, 0x0f); + n5_write_register(ViPipe, 0xff, 0x05); + n5_write_register(ViPipe, 0x00, 0xd0); + n5_write_register(ViPipe, 0x01, 0x22); + n5_write_register(ViPipe, 0x05, 0x04); + n5_write_register(ViPipe, 0x08, 0x55); + n5_write_register(ViPipe, 0x1b, 0x08); + n5_write_register(ViPipe, 0x25, 0xdc); + n5_write_register(ViPipe, 0x28, 0x80); + n5_write_register(ViPipe, 0x2f, 0x00); + n5_write_register(ViPipe, 0x30, 0xe0); + n5_write_register(ViPipe, 0x31, 0x43); + n5_write_register(ViPipe, 0x32, 0xa2); + n5_write_register(ViPipe, 0x57, 0x00); + n5_write_register(ViPipe, 0x58, 0x77); + n5_write_register(ViPipe, 0x5b, 0x41); + n5_write_register(ViPipe, 0x5c, 0x7C); + n5_write_register(ViPipe, 0x5f, 0x00); + n5_write_register(ViPipe, 0x7b, 0x11); + n5_write_register(ViPipe, 0x7c, 0x01); + n5_write_register(ViPipe, 0x7d, 0x80); + n5_write_register(ViPipe, 0x80, 0x00); + n5_write_register(ViPipe, 0x90, 0x01); + n5_write_register(ViPipe, 0xa9, 0x00); + n5_write_register(ViPipe, 0xb8, 0x39); + n5_write_register(ViPipe, 0xb9, 0x72); + n5_write_register(ViPipe, 0xd1, 0x00); + n5_write_register(ViPipe, 0xd5, 0x80); + n5_write_register(ViPipe, 0xff, 0x06); + n5_write_register(ViPipe, 0x00, 0xd0); + n5_write_register(ViPipe, 0x01, 0x22); + n5_write_register(ViPipe, 0x05, 0x04); + n5_write_register(ViPipe, 0x08, 0x55); + n5_write_register(ViPipe, 0x1b, 0x08); + n5_write_register(ViPipe, 0x25, 0xdc); + n5_write_register(ViPipe, 0x28, 0x80); + n5_write_register(ViPipe, 0x2f, 0x00); + n5_write_register(ViPipe, 0x30, 0xe0); + n5_write_register(ViPipe, 0x31, 0x43); + n5_write_register(ViPipe, 0x32, 0xa2); + n5_write_register(ViPipe, 0x57, 0x00); + n5_write_register(ViPipe, 0x58, 0x77); + n5_write_register(ViPipe, 0x5b, 0x41); + n5_write_register(ViPipe, 0x5c, 0x7C); + n5_write_register(ViPipe, 0x5f, 0x00); + n5_write_register(ViPipe, 0x7b, 0x11); + n5_write_register(ViPipe, 0x7c, 0x01); + n5_write_register(ViPipe, 0x7d, 0x80); + n5_write_register(ViPipe, 0x80, 0x00); + n5_write_register(ViPipe, 0x90, 0x01); + n5_write_register(ViPipe, 0xa9, 0x00); + n5_write_register(ViPipe, 0xb8, 0x39); + n5_write_register(ViPipe, 0xb9, 0x72); + n5_write_register(ViPipe, 0xd1, 0x00); + n5_write_register(ViPipe, 0xd5, 0x80); + n5_write_register(ViPipe, 0xff, 0x09); + n5_write_register(ViPipe, 0x50, 0x30); + n5_write_register(ViPipe, 0x51, 0x6f); + n5_write_register(ViPipe, 0x52, 0x67); + n5_write_register(ViPipe, 0x53, 0x48); + n5_write_register(ViPipe, 0x54, 0x30); + n5_write_register(ViPipe, 0x55, 0x6f); + n5_write_register(ViPipe, 0x56, 0x67); + n5_write_register(ViPipe, 0x57, 0x48); + n5_write_register(ViPipe, 0x96, 0x00); + n5_write_register(ViPipe, 0x9e, 0x00); + n5_write_register(ViPipe, 0xb6, 0x00); + n5_write_register(ViPipe, 0xbe, 0x00); + n5_write_register(ViPipe, 0xff, 0x0a); + n5_write_register(ViPipe, 0x25, 0x10); + n5_write_register(ViPipe, 0x27, 0x1e); + n5_write_register(ViPipe, 0x30, 0xac); + n5_write_register(ViPipe, 0x31, 0x78); + n5_write_register(ViPipe, 0x32, 0x17); + n5_write_register(ViPipe, 0x33, 0xc1); + n5_write_register(ViPipe, 0x34, 0x40); + n5_write_register(ViPipe, 0x35, 0x00); + n5_write_register(ViPipe, 0x36, 0xc3); + n5_write_register(ViPipe, 0x37, 0x0a); + n5_write_register(ViPipe, 0x38, 0x00); + n5_write_register(ViPipe, 0x39, 0x02); + n5_write_register(ViPipe, 0x3a, 0x00); + n5_write_register(ViPipe, 0x3b, 0xb2); + n5_write_register(ViPipe, 0xa5, 0x10); + n5_write_register(ViPipe, 0xa7, 0x1e); + n5_write_register(ViPipe, 0xb0, 0xac); + n5_write_register(ViPipe, 0xb1, 0x78); + n5_write_register(ViPipe, 0xb2, 0x17); + n5_write_register(ViPipe, 0xb3, 0xc1); + n5_write_register(ViPipe, 0xb4, 0x40); + n5_write_register(ViPipe, 0xb5, 0x00); + n5_write_register(ViPipe, 0xb6, 0xc3); + n5_write_register(ViPipe, 0xb7, 0x0a); + n5_write_register(ViPipe, 0xb8, 0x00); + n5_write_register(ViPipe, 0xb9, 0x02); + n5_write_register(ViPipe, 0xba, 0x00); + n5_write_register(ViPipe, 0xbb, 0xb2); + n5_write_register(ViPipe, 0x77, 0x8F); + n5_write_register(ViPipe, 0xF7, 0x8F); + n5_write_register(ViPipe, 0xff, 0x13); + n5_write_register(ViPipe, 0x07, 0x47); + n5_write_register(ViPipe, 0x12, 0x04); + n5_write_register(ViPipe, 0x1e, 0x1f); + n5_write_register(ViPipe, 0x1f, 0x27); + n5_write_register(ViPipe, 0x2e, 0x10); + n5_write_register(ViPipe, 0x2f, 0xc8); + n5_write_register(ViPipe, 0x30, 0x00); + n5_write_register(ViPipe, 0x31, 0xff); + n5_write_register(ViPipe, 0x32, 0x00); + n5_write_register(ViPipe, 0x33, 0x00); + n5_write_register(ViPipe, 0x3a, 0xff); + n5_write_register(ViPipe, 0x3b, 0xff); + n5_write_register(ViPipe, 0x3c, 0xff); + n5_write_register(ViPipe, 0x3d, 0xff); + n5_write_register(ViPipe, 0x3e, 0xff); + n5_write_register(ViPipe, 0x3f, 0x0f); + n5_write_register(ViPipe, 0x70, 0x00); + n5_write_register(ViPipe, 0x72, 0x05); + n5_write_register(ViPipe, 0x7A, 0xf0); + n5_write_register(ViPipe, 0xff, 0x00); //8x8 color block test pattern + n5_write_register(ViPipe, 0x78, 0xba); + n5_write_register(ViPipe, 0xff, 0x05); + n5_write_register(ViPipe, 0x2c, 0x08); + n5_write_register(ViPipe, 0x6a, 0x80); + n5_write_register(ViPipe, 0xff, 0x06); + n5_write_register(ViPipe, 0x2c, 0x08); + n5_write_register(ViPipe, 0x6a, 0x80); +} + +void n5_set_chn_720h_ntsc(VI_PIPE ViPipe, CVI_U8 chn) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "%s chn=%d\n", __func__, chn); + n5_write_register(ViPipe, 0xff, 0x00); + n5_write_register(ViPipe, 0x08+chn, 0xa0); + n5_write_register(ViPipe, 0x34+chn, 0x00); + n5_write_register(ViPipe, 0x81+chn, 0x60); + n5_write_register(ViPipe, 0x85+chn, 0x00); + n5_write_register(ViPipe, 0x54, n5_read_register(ViPipe, 0x54)|(0x10<1mux(default), 2->2mux +void n5_set_portmode(VI_PIPE ViPipe, CVI_U8 port, CVI_U8 muxmode, CVI_U8 is_bt601) +{ + CVI_U8 val_1xc8, val_1xca, val_0x54; + // add delay for MUX2 + CVI_U8 clk_freq_array[4] = {0x83, 0x03, 0x43, 0x63}; //clk_freq: 0~3:37.125M/74.25M/148.5M/297M + //CVI_U8 clk_freq_array[4] = {0x83, 0x03, 0x4f, 0x63}; //clk_freq: 0~3:37.125M/74.25M/148.5M/297M + + n5_write_register(ViPipe, 0xff, 0x00); + val_0x54 = n5_read_register(ViPipe, 0x54); + + if ((muxmode == N5_OUTMODE_2MUX_SD) || + (muxmode == N5_OUTMODE_2MUX_HD) || + (muxmode == N5_OUTMODE_2MUX_FHD) || + (muxmode == N5_OUTMODE_2MUX_BT1120S_720P) || + (muxmode == N5_OUTMODE_2MUX_BT1120S_1080P)) + val_0x54 |= 0x01; + else + val_0x54 &= 0xFE; + + n5_write_register(ViPipe, 0x54, val_0x54); + n5_write_register(ViPipe, 0xff, 0x01); + val_1xc8 = n5_read_register(ViPipe, 0xc8); + switch (muxmode) { + case N5_OUTMODE_1MUX_SD: + n5_write_register(ViPipe, 0xA0+port, 0x00); + n5_write_register(ViPipe, 0xC0, 0x00); + n5_write_register(ViPipe, 0xC2, 0x11); + val_1xc8 &= (port == 1?0x0F:0xF0); + n5_write_register(ViPipe, 0xC8, val_1xc8); + n5_write_register(ViPipe, 0xCC+port, clk_freq_array[0]); + break; + case N5_OUTMODE_1MUX_HD: + n5_write_register(ViPipe, 0xA0+port, 0x00); + n5_write_register(ViPipe, 0xC0, 0x00); + n5_write_register(ViPipe, 0xC2, 0x11); + val_1xc8 &= (port == 1?0x0F:0xF0); + n5_write_register(ViPipe, 0xC8, val_1xc8); + n5_write_register(ViPipe, 0xCC+port, clk_freq_array[1]); + break; + case N5_OUTMODE_1MUX_FHD: + n5_write_register(ViPipe, 0xA0+port, 0x00); + n5_write_register(ViPipe, 0xC0, 0x00); + n5_write_register(ViPipe, 0xC2, 0x11); + val_1xc8 &= (port == 1?0x0F:0xF0); + n5_write_register(ViPipe, 0xC8, val_1xc8); + n5_write_register(ViPipe, 0xCC+port, clk_freq_array[2]); + break; + case N5_OUTMODE_1MUX_FHD_HALF: + n5_write_register(ViPipe, 0xA0+port, 0x00); + n5_write_register(ViPipe, 0xC0, 0x88); + n5_write_register(ViPipe, 0xC2, 0x99); + val_1xc8 &= (port == 1?0x0F:0xF0); + n5_write_register(ViPipe, 0xC8, val_1xc8); + n5_write_register(ViPipe, 0xCC+port, clk_freq_array[1]); + break; + case N5_OUTMODE_2MUX_SD: + n5_write_register(ViPipe, 0xA0+port, 0x20); + n5_write_register(ViPipe, 0xC0, 0x10); + n5_write_register(ViPipe, 0xC2, 0x10); + val_1xc8 &= (port == 1?0x0F:0xF0); + val_1xc8 |= (port == 1?0x20:0x02); + n5_write_register(ViPipe, 0xC8, val_1xc8); + n5_write_register(ViPipe, 0xCC+port, clk_freq_array[1]); + break; + case N5_OUTMODE_2MUX_HD: + n5_write_register(ViPipe, 0xA0+port, 0x20); + n5_write_register(ViPipe, 0xC0, 0x10); + n5_write_register(ViPipe, 0xC2, 0x10); + val_1xc8 &= (port == 1?0x0F:0xF0); + val_1xc8 |= (port == 1?0x20:0x02); + n5_write_register(ViPipe, 0xC8, val_1xc8); + n5_write_register(ViPipe, 0xCC+port, clk_freq_array[2]); + break; + case N5_OUTMODE_2MUX_FHD: + n5_write_register(ViPipe, 0xA0+port, 0x00); + n5_write_register(ViPipe, 0xC0, 0x10); + n5_write_register(ViPipe, 0xC2, 0x10); + val_1xc8 &= (port == 1?0x0F:0xF0); + val_1xc8 |= (port == 1?0x20:0x02); + n5_write_register(ViPipe, 0xC8, val_1xc8); + n5_write_register(ViPipe, 0xCC+port, clk_freq_array[2]); + break; + case N5_OUTMODE_1MUX_BT1120S: + n5_write_register(ViPipe, 0xA0, 0x00); + n5_write_register(ViPipe, 0xA1, 0x00); + n5_write_register(ViPipe, 0xC0, 0xCC); + n5_write_register(ViPipe, 0xC1, 0xCC); + n5_write_register(ViPipe, 0xC2, 0x44); + n5_write_register(ViPipe, 0xC3, 0x44); + n5_write_register(ViPipe, 0xC8, 0x00); + n5_write_register(ViPipe, 0xCA, 0x33); //two ports are enabled + n5_write_register(ViPipe, 0xCC, clk_freq_array[2]); + break; + case N5_OUTMODE_2MUX_BT1120S_720P: + n5_write_register(ViPipe, 0xA0, 0x00); + n5_write_register(ViPipe, 0xA1, 0x00); + n5_write_register(ViPipe, 0xC0, 0xDC); //C data + n5_write_register(ViPipe, 0xC1, 0xDC); + n5_write_register(ViPipe, 0xC2, 0x54); //Y data + n5_write_register(ViPipe, 0xC3, 0x54); + n5_write_register(ViPipe, 0xC8, 0x22); + n5_write_register(ViPipe, 0xCA, 0x33); //two ports are enabled + n5_write_register(ViPipe, 0xCC, clk_freq_array[1]); + break; + case N5_OUTMODE_2MUX_BT1120S_1080P: + n5_write_register(ViPipe, 0xA0, 0x20); + n5_write_register(ViPipe, 0xA1, 0x20); + n5_write_register(ViPipe, 0xC0, 0xDC); //C data + n5_write_register(ViPipe, 0xC1, 0xDC); + n5_write_register(ViPipe, 0xC2, 0x54); //Y data + n5_write_register(ViPipe, 0xC3, 0x54); + n5_write_register(ViPipe, 0xC8, 0x22); + n5_write_register(ViPipe, 0xCA, 0x33); //two ports are enabled + n5_write_register(ViPipe, 0xCC, clk_freq_array[1]); + break; + } + if (is_bt601 == 1) { + n5_write_register(ViPipe, 0xA8+port, 0x90+(port*0x10)); //h/v0 sync enabled +// n5_write_register(ViPipe, 0xA9, 0xA0); //h/v1 sync enabled +// n5_write_register(ViPipe, 0xBC, 0x10); //h/v0 swap enabled +// n5_write_register(ViPipe, 0xBD, 0x10); +// n5_write_register(ViPipe, 0xBE, 0x10); //h/v1 swap enabled +// n5_write_register(ViPipe, 0xBF, 0x10); + } else { + n5_write_register(ViPipe, 0xA8, 0x00); +// n5_write_register(ViPipe, 0xA9, 0x00); //h/v sync disable. + } + + if (muxmode == N5_OUTMODE_2MUX_BT1120S_720P) { + n5_write_register(ViPipe, 0xE4, 0x11); + n5_write_register(ViPipe, 0xE5, 0x11); + } else { + n5_write_register(ViPipe, 0xE4, 0x00); + n5_write_register(ViPipe, 0xE5, 0x00); + } + + val_1xca = n5_read_register(ViPipe, 0xca); + val_1xca |= (0x11<> ch) & 0x01; + n5_write_register(ViPipe, 0xff, 0x05+ch); + val_5xf0 = n5_read_register(ViPipe, 0xf0); + //if(0xFF == val_5xf0 || (0x0F == (val_5xf0&0x0F)) || (0xF0 == (val_5xf0&0xF0)) ) //no video + if (ch_vloss[ch] == 0 && ch_prevloss[ch] == 1) { + if (val_5xf0 == 0xFF) { + //printk("1pre_vfc[%d]=%2x val_5xf0=%2x\n",ch, pre_vfc[ch], val_5xf0); + if (chn_mode[ch] != NC_VIVO_CH_FORMATDEF_UNKNOWN) { + n5_set_chnmode(ViPipe, ch, NC_VIVO_CH_FORMATDEF_UNKNOWN); + n5_write_register(ViPipe, 0xff, 0x05+ch); + n5_write_register(ViPipe, 0xB8, 0xB8); + n5_write_register(ViPipe, 0xff, 0x13); + val_13x70 = n5_read_register(ViPipe, 0x70); + val_13x70 &= (~(0x01< +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_isp.h" + +#include "n6_cmos_ex.h" +#include "n6_cmos_param.h" + +/**************************************************************************** + * global variables * + ****************************************************************************/ +ISP_SNS_COMMBUS_U g_aunN6_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_STATE_S *g_pastN6[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define N6_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastN6[dev]) +#define N6_SENSOR_SET_CTX(dev, pstCtx) (g_pastN6[dev] = pstCtx) +#define N6_SENSOR_RESET_CTX(dev) (g_pastN6[dev] = CVI_NULL) +#define N6_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) +#define N6_ID 0xE0 + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const N6_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + N6_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astN6_mode[pstSnsState->u8ImgMode]; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + N6_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstCfg0 = &pstSnsState->astSyncInfo[0]; + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + N6_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + + if (pstSensorImageMode->f32Fps <= 30) { + if (N6_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = N6_MODE_1080P_25P; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + N6_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->u8ImgMode = N6_MODE_1080P_25P; + pstSnsState->enWDRMode = WDR_MODE_NONE; +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + N6_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &n6_rx_attr, sizeof(*pstRxAttr)); + CVI_TRACE_SNS(CVI_DBG_ERR, "get n6_rx0_attr\n"); + + pstRxAttr->img_size.width = g_astN6_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astN6_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &n6_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = n6_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = n6_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 n6_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunN6_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + N6_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + N6_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + N6_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + N6_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + (void) pstAeLib; + (void) pstAwbLib; + + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = N6_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + (void) pstAeLib; + (void) pstAwbLib; + + CVI_S32 s32Ret; + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, N6_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsN6_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnMirrorFlip = CVI_NULL, + .pfnStandby = CVI_NULL, + .pfnRestart = CVI_NULL, + .pfnWriteReg = n6_write_register, + .pfnReadReg = n6_read_register, + .pfnSetBusInfo = n6_set_bus_info, + .pfnSetInit = CVI_NULL, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = CVI_NULL, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/nextchip_n6/n6_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/nextchip_n6/n6_cmos_ex.h new file mode 100644 index 000000000..485a8021b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/nextchip_n6/n6_cmos_ex.h @@ -0,0 +1,107 @@ +#ifndef __N6_CMOS_EX_H_ +#define __N6_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +typedef enum _N6_MODE_E { + N6_MODE_H720_NT = 1, + N6_MODE_H720_PAL, + N6_MODE_720P_30P, + N6_MODE_720P_25P, + N6_MODE_960P_30P, + N6_MODE_960P_25P, + N6_MODE_1080P_30P, + N6_MODE_1080P_25P, + N6_MODE_1080P_60P, + N6_MODE_1080P_50P, + N6_MODE_4M_30P, + N6_MODE_4M_25P, + N6_MODE_8M_15P, + N6_MODE_8M_12_5P, + N6_MODE_NUM +} N6_MODE_E; + +typedef enum _n6_outmode_sel { + N6_OUTMODE_1MUX_SD = 0, + N6_OUTMODE_1MUX_HD, + N6_OUTMODE_1MUX_FHD, + N6_OUTMODE_1MUX_FHD_HALF, + N6_OUTMODE_2MUX_SD, + N6_OUTMODE_2MUX_HD, + N6_OUTMODE_2MUX_FHD, + N6_OUTMODE_1MUX_BT1120S, + N6_OUTMODE_2MUX_BT1120S_720P, + N6_OUTMODE_2MUX_BT1120S_1080P, + N6_OUTMODE_BUTT +} N6_OUTMODE_SEL; + +typedef struct _N6_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + char name[64]; +} N6_MODE_S; + +#define _MIPI_PORT0_ +//#define _MIPI_PORT1_ + +#ifdef _MIPI_PORT0_ +#define _MAR_BANK_ 0x20 +#define _MTX_BANK_ 0x23 +#else +#define _MAR_BANK_ 0x30 +#define _MTX_BANK_ 0x33 +#endif + +#define CH0_NO 0 +#define CH1_NO 1 +#define NTPAL 0 + +#define VFMT_NTSC 0 +#define VFMT_PAL 1 + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastN6[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunN6_BusInfo[]; +extern const CVI_U8 n6_i2c_addr; +extern const CVI_U32 n6_addr_byte; +extern const CVI_U32 n6_data_byte; +extern void n6_init(VI_PIPE ViPipe); +extern void n6_exit(VI_PIPE ViPipe); +extern void n6_standby(VI_PIPE ViPipe); +extern void n6_restart(VI_PIPE ViPipe); +extern int n6_write_register(VI_PIPE ViPipe, int addr, int data); +extern int n6_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __N6_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/nextchip_n6/n6_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/nextchip_n6/n6_cmos_param.h new file mode 100644 index 000000000..0698002ba --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/nextchip_n6/n6_cmos_param.h @@ -0,0 +1,71 @@ +#ifndef __N6_CMOS_PARAM_H_ +#define __N6_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "n6_cmos_ex.h" + +static const N6_MODE_S g_astN6_mode[N6_MODE_NUM] = { + [N6_MODE_1080P_25P] = { + .name = "1080p25", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + }, +}; + +struct combo_dev_attr_s n6_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_400M, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .mipi_attr = { + .raw_data_type = YUV422_8BIT, + .lane_id = {2, 0, 1, 3, 4}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + .demux = { + .demux_en = 1, + .vc_mapping = {0, 1, 2, 3}, + }, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __N6_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/nextchip_n6/n6_sensor_ctrl.c b/middleware/v2/component/isp/sensor/cv181x/nextchip_n6/n6_sensor_ctrl.c new file mode 100644 index 000000000..f803c9c11 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/nextchip_n6/n6_sensor_ctrl.c @@ -0,0 +1,842 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include +#include "cvi_sns_ctrl.h" +#include "n6_cmos_ex.h" +#include +#include + +const CVI_U8 n6_i2c_addr = 0x31; /* I2C slave address of N6, SA0=0:0x32, SA0=1:0x33*/ +const CVI_U32 n6_addr_byte = 1; +const CVI_U32 n6_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; +static CVI_U32 adet; +//static CVI_U32 fmt = 1; //0:960h 1:720P 2:1080P +//static unsigned int ntpal = 0; //0:ntsc/30p 1:pal/25p +static CVI_U32 mclk = 1; //0:1458 1:756 + +#define N6_TEST_PATTERN 1 + +int n6_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunN6_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + syslog(LOG_DEBUG, "open %s\n", acDevFile); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, n6_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int n6_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int n6_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return 0; + + if (n6_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, n6_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, n6_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (n6_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int n6_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (n6_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + if (n6_data_byte == 2) + buf[idx++] = (data >> 8) & 0xff; + + // add data byte 0 + buf[idx++] = data & 0xff; + + ret = write(g_fd[ViPipe], buf, n6_addr_byte + n6_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + +#if 0 // read back checing + ret = n6_read_register(ViPipe, addr); + if (ret != data) + syslog(LOG_DEBUG, "i2c readback-check fail, 0x%x != 0x%x\n", ret, data); +#endif + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void n6_common_setting(VI_PIPE ViPipe) +{ + CVI_U8 ch; + + n6_write_register(ViPipe, 0xff, 0x00); + n6_write_register(ViPipe, 0x80, 0x0f); + n6_write_register(ViPipe, 0x00, 0x10); + n6_write_register(ViPipe, 0x01, 0x10); + n6_write_register(ViPipe, 0x02, 0x10); + n6_write_register(ViPipe, 0x03, 0x10); + n6_write_register(ViPipe, 0x22, 0x0b); + n6_write_register(ViPipe, 0x23, 0x41); + n6_write_register(ViPipe, 0x26, 0x0b); + n6_write_register(ViPipe, 0x27, 0x41); + n6_write_register(ViPipe, 0x2a, 0x0b); + n6_write_register(ViPipe, 0x2b, 0x41); + n6_write_register(ViPipe, 0x2e, 0x0b); + n6_write_register(ViPipe, 0x2f, 0x41); + + n6_write_register(ViPipe, 0xff, 0x01); + n6_write_register(ViPipe, 0x98, 0x30); + n6_write_register(ViPipe, 0xed, 0x00); + + for (ch = 0; ch < 4; ch++) { + n6_write_register(ViPipe, 0xff, 0x05 + ch); + n6_write_register(ViPipe, 0x00, 0xd0); + n6_write_register(ViPipe, 0x01, 0x22); + n6_write_register(ViPipe, 0x47, 0xee); + n6_write_register(ViPipe, 0x50, 0xc6); + n6_write_register(ViPipe, 0x57, 0x00); + n6_write_register(ViPipe, 0x58, 0x77); + n6_write_register(ViPipe, 0x5b, 0x41); + n6_write_register(ViPipe, 0x5c, 0x78); + n6_write_register(ViPipe, 0xB8, 0xB8); + } + + n6_write_register(ViPipe, 0xff, 0x09); + n6_write_register(ViPipe, 0x50, 0x30); + n6_write_register(ViPipe, 0x51, 0x6f); + n6_write_register(ViPipe, 0x52, 0x67); + n6_write_register(ViPipe, 0x53, 0x48); + n6_write_register(ViPipe, 0x54, 0x30); + n6_write_register(ViPipe, 0x55, 0x6f); + n6_write_register(ViPipe, 0x56, 0x67); + n6_write_register(ViPipe, 0x57, 0x48); + n6_write_register(ViPipe, 0x58, 0x30); + n6_write_register(ViPipe, 0x59, 0x6f); + n6_write_register(ViPipe, 0x5a, 0x67); + n6_write_register(ViPipe, 0x5b, 0x48); + n6_write_register(ViPipe, 0x5c, 0x30); + n6_write_register(ViPipe, 0x5d, 0x6f); + n6_write_register(ViPipe, 0x5e, 0x67); + n6_write_register(ViPipe, 0x5f, 0x48); + + n6_write_register(ViPipe, 0xff, 0x0a); + n6_write_register(ViPipe, 0x25, 0x10); + n6_write_register(ViPipe, 0x27, 0x1e); + n6_write_register(ViPipe, 0x30, 0xac); + n6_write_register(ViPipe, 0x31, 0x78); + n6_write_register(ViPipe, 0x32, 0x17); + n6_write_register(ViPipe, 0x33, 0xc1); + n6_write_register(ViPipe, 0x34, 0x40); + n6_write_register(ViPipe, 0x35, 0x00); + n6_write_register(ViPipe, 0x36, 0xc3); + n6_write_register(ViPipe, 0x37, 0x0a); + n6_write_register(ViPipe, 0x38, 0x00); + n6_write_register(ViPipe, 0x39, 0x02); + n6_write_register(ViPipe, 0x3a, 0x00); + n6_write_register(ViPipe, 0x3b, 0xb2); + n6_write_register(ViPipe, 0xa5, 0x10); + n6_write_register(ViPipe, 0xa7, 0x1e); + n6_write_register(ViPipe, 0xb0, 0xac); + n6_write_register(ViPipe, 0xb1, 0x78); + n6_write_register(ViPipe, 0xb2, 0x17); + n6_write_register(ViPipe, 0xb3, 0xc1); + n6_write_register(ViPipe, 0xb4, 0x40); + n6_write_register(ViPipe, 0xb5, 0x00); + n6_write_register(ViPipe, 0xb6, 0xc3); + n6_write_register(ViPipe, 0xb7, 0x0a); + n6_write_register(ViPipe, 0xb8, 0x00); + n6_write_register(ViPipe, 0xb9, 0x02); + n6_write_register(ViPipe, 0xba, 0x00); + n6_write_register(ViPipe, 0xbb, 0xb2); + n6_write_register(ViPipe, 0xff, 0x0b); + n6_write_register(ViPipe, 0x25, 0x10); + n6_write_register(ViPipe, 0x27, 0x1e); + n6_write_register(ViPipe, 0x30, 0xac); + n6_write_register(ViPipe, 0x31, 0x78); + n6_write_register(ViPipe, 0x32, 0x17); + n6_write_register(ViPipe, 0x33, 0xc1); + n6_write_register(ViPipe, 0x34, 0x40); + n6_write_register(ViPipe, 0x35, 0x00); + n6_write_register(ViPipe, 0x36, 0xc3); + n6_write_register(ViPipe, 0x37, 0x0a); + n6_write_register(ViPipe, 0x38, 0x00); + n6_write_register(ViPipe, 0x39, 0x02); + n6_write_register(ViPipe, 0x3a, 0x00); + n6_write_register(ViPipe, 0x3b, 0xb2); + n6_write_register(ViPipe, 0xa5, 0x10); + n6_write_register(ViPipe, 0xa7, 0x1e); + n6_write_register(ViPipe, 0xb0, 0xac); + n6_write_register(ViPipe, 0xb1, 0x78); + n6_write_register(ViPipe, 0xb2, 0x17); + n6_write_register(ViPipe, 0xb3, 0xc1); + n6_write_register(ViPipe, 0xb4, 0x40); + n6_write_register(ViPipe, 0xb5, 0x00); + n6_write_register(ViPipe, 0xb6, 0xc3); + n6_write_register(ViPipe, 0xb7, 0x0a); + n6_write_register(ViPipe, 0xb8, 0x00); + n6_write_register(ViPipe, 0xb9, 0x02); + n6_write_register(ViPipe, 0xba, 0x00); + n6_write_register(ViPipe, 0xbb, 0xb2); + + n6_write_register(ViPipe, 0xff, 0x13); + n6_write_register(ViPipe, 0x05, 0xa0); + n6_write_register(ViPipe, 0x31, 0xff); + n6_write_register(ViPipe, 0x07, 0x47); + n6_write_register(ViPipe, 0x12, 0x04); + n6_write_register(ViPipe, 0x1e, 0x1f); + n6_write_register(ViPipe, 0x1f, 0x27); + n6_write_register(ViPipe, 0x2e, 0x10); + n6_write_register(ViPipe, 0x2f, 0xc8); + n6_write_register(ViPipe, 0x31, 0xff); + n6_write_register(ViPipe, 0x32, 0x00); + n6_write_register(ViPipe, 0x33, 0x00); + n6_write_register(ViPipe, 0x72, 0x05); + n6_write_register(ViPipe, 0x7a, 0xf0); + + n6_write_register(ViPipe, 0xff, _MAR_BANK_); + n6_write_register(ViPipe, 0x10, 0xff); + n6_write_register(ViPipe, 0x11, 0xff); + if (mclk == 1) { + n6_write_register(ViPipe, 0x30, 0x0f); + n6_write_register(ViPipe, 0x32, 0x92); + n6_write_register(ViPipe, 0x34, 0xcd); + n6_write_register(ViPipe, 0x36, 0x04); + n6_write_register(ViPipe, 0x38, 0x58); + } else { + n6_write_register(ViPipe, 0x30, 0x0f); + n6_write_register(ViPipe, 0x32, 0xff); + n6_write_register(ViPipe, 0x34, 0xcd); + n6_write_register(ViPipe, 0x36, 0x04); + n6_write_register(ViPipe, 0x38, 0xff); + } + n6_write_register(ViPipe, 0x3c, 0x01); + n6_write_register(ViPipe, 0x3d, 0x11); + n6_write_register(ViPipe, 0x3e, 0x11); + n6_write_register(ViPipe, 0x45, 0x60); + n6_write_register(ViPipe, 0x46, 0x49); + + n6_write_register(ViPipe, 0xff, _MTX_BANK_); + n6_write_register(ViPipe, 0xe9, 0x03); + n6_write_register(ViPipe, 0x03, 0x02); + n6_write_register(ViPipe, 0x01, 0xe4); + n6_write_register(ViPipe, 0x00, 0x7d); + n6_write_register(ViPipe, 0x01, 0xe0); + n6_write_register(ViPipe, 0x02, 0xa0); + n6_write_register(ViPipe, 0x20, 0x1e); + n6_write_register(ViPipe, 0x20, 0x1f); + + if (mclk == 1) { + n6_write_register(ViPipe, 0x04, 0x38); + n6_write_register(ViPipe, 0x45, 0xc4); + n6_write_register(ViPipe, 0x46, 0x01); + n6_write_register(ViPipe, 0x47, 0x1b); + n6_write_register(ViPipe, 0x48, 0x08); + n6_write_register(ViPipe, 0x65, 0xc4); + n6_write_register(ViPipe, 0x66, 0x01); + n6_write_register(ViPipe, 0x67, 0x1b); + n6_write_register(ViPipe, 0x68, 0x08); + n6_write_register(ViPipe, 0x85, 0xc4); + n6_write_register(ViPipe, 0x86, 0x01); + n6_write_register(ViPipe, 0x87, 0x1b); + n6_write_register(ViPipe, 0x88, 0x08); + n6_write_register(ViPipe, 0xa5, 0xc4); + n6_write_register(ViPipe, 0xa6, 0x01); + n6_write_register(ViPipe, 0xa7, 0x1b); + n6_write_register(ViPipe, 0xa8, 0x08); + n6_write_register(ViPipe, 0xc5, 0xc4); + n6_write_register(ViPipe, 0xc6, 0x01); + n6_write_register(ViPipe, 0xc7, 0x1b); + n6_write_register(ViPipe, 0xc8, 0x08); + } else { + n6_write_register(ViPipe, 0x04, 0x6c); + n6_write_register(ViPipe, 0x45, 0xcd); + n6_write_register(ViPipe, 0x46, 0x42); + n6_write_register(ViPipe, 0x47, 0x36); + n6_write_register(ViPipe, 0x48, 0x0f); + n6_write_register(ViPipe, 0x65, 0xcd); + n6_write_register(ViPipe, 0x66, 0x42); + n6_write_register(ViPipe, 0x67, 0x0e); + n6_write_register(ViPipe, 0x68, 0x0f); + n6_write_register(ViPipe, 0x85, 0xcd); + n6_write_register(ViPipe, 0x86, 0x42); + n6_write_register(ViPipe, 0x87, 0x0e); + n6_write_register(ViPipe, 0x88, 0x0f); + n6_write_register(ViPipe, 0xa5, 0xcd); + n6_write_register(ViPipe, 0xa6, 0x42); + n6_write_register(ViPipe, 0xa7, 0x0e); + n6_write_register(ViPipe, 0xa8, 0x0f); + n6_write_register(ViPipe, 0xc5, 0xcd); + n6_write_register(ViPipe, 0xc6, 0x42); + n6_write_register(ViPipe, 0xc7, 0x0e); + n6_write_register(ViPipe, 0xc8, 0x0f); + } + n6_write_register(ViPipe, 0xeb, 0x8d); + + n6_write_register(ViPipe, 0xff, _MAR_BANK_); + n6_write_register(ViPipe, 0x00, 0xff); + n6_write_register(ViPipe, 0x40, 0x01); + n6_write_register(ViPipe, 0x40, 0x00); + n6_write_register(ViPipe, 0xff, 0x01); + n6_write_register(ViPipe, 0x97, 0x00); + n6_write_register(ViPipe, 0x97, 0x0f); + + n6_write_register(ViPipe, 0xff, 0x00); //test pattern + n6_write_register(ViPipe, 0x78, 0xba); + n6_write_register(ViPipe, 0x79, 0xac); + n6_write_register(ViPipe, 0xff, 0x05); + n6_write_register(ViPipe, 0x2c, 0x08); + n6_write_register(ViPipe, 0x6a, 0x80); + n6_write_register(ViPipe, 0xff, 0x06); + n6_write_register(ViPipe, 0x2c, 0x08); + n6_write_register(ViPipe, 0x6a, 0x80); + n6_write_register(ViPipe, 0xff, 0x07); + n6_write_register(ViPipe, 0x2c, 0x08); + n6_write_register(ViPipe, 0x6a, 0x80); + n6_write_register(ViPipe, 0xff, 0x08); + n6_write_register(ViPipe, 0x2c, 0x08); + n6_write_register(ViPipe, 0x6a, 0x80); +} + +void n6_set_chn_960h(VI_PIPE ViPipe, CVI_U8 ch, CVI_U8 ntpal) +{ + CVI_U8 val_0x54, val_20x01; + + CVI_TRACE_SNS(CVI_DBG_INFO, "%s ch=%d\n", __func__, ch); + + n6_write_register(ViPipe, 0xff, 0x00); + n6_write_register(ViPipe, 0x08 + ch, ntpal ? 0xdd : 0xa0); + n6_write_register(ViPipe, 0x18 + ch, 0x08); + n6_write_register(ViPipe, 0x22 + ch * 4, 0x0b); + n6_write_register(ViPipe, 0x23 + ch * 4, 0x41); + n6_write_register(ViPipe, 0x30 + ch, 0x12); + n6_write_register(ViPipe, 0x34 + ch, 0x01); + val_0x54 = n6_read_register(ViPipe, 0x54); + if (ntpal) + val_0x54 &= ~(0x10 << ch); + else + val_0x54 |= (0x10 << ch); + n6_write_register(ViPipe, 0x54, val_0x54); + n6_write_register(ViPipe, 0x58 + ch, ntpal ? 0x80 : 0x90); + n6_write_register(ViPipe, 0x5c + ch, ntpal ? 0xbe : 0xbc); + n6_write_register(ViPipe, 0x64 + ch, ntpal ? 0xa0 : 0x81); + n6_write_register(ViPipe, 0x81 + ch, ntpal ? 0xf0 : 0xe0); + n6_write_register(ViPipe, 0x85 + ch, 0x00); + n6_write_register(ViPipe, 0x89 + ch, 0x00); + n6_write_register(ViPipe, 0x8e + ch, 0x00); + n6_write_register(ViPipe, 0xa0 + ch, 0x05); + + n6_write_register(ViPipe, 0xff, 0x01); + n6_write_register(ViPipe, 0x84 + ch, 0x02); + n6_write_register(ViPipe, 0x88 + ch, 0x00); + n6_write_register(ViPipe, 0x8c + ch, 0x40); + n6_write_register(ViPipe, 0xa0 + ch, 0x20); + n6_write_register(ViPipe, 0xed, 0x00); + + n6_write_register(ViPipe, 0xff, 0x05 + ch); + n6_write_register(ViPipe, 0x01, 0x22); + n6_write_register(ViPipe, 0x05, 0x00); + n6_write_register(ViPipe, 0x08, 0x55); + n6_write_register(ViPipe, 0x25, 0xdc); + n6_write_register(ViPipe, 0x28, 0x80); + n6_write_register(ViPipe, 0x2f, 0x00); + n6_write_register(ViPipe, 0x30, 0xe0); + n6_write_register(ViPipe, 0x31, 0x43); + n6_write_register(ViPipe, 0x32, 0xa2); + n6_write_register(ViPipe, 0x47, 0x04); + n6_write_register(ViPipe, 0x50, 0x84); + n6_write_register(ViPipe, 0x57, 0x00); + n6_write_register(ViPipe, 0x58, 0x77); + n6_write_register(ViPipe, 0x5b, 0x43); + n6_write_register(ViPipe, 0x5c, 0x78); + n6_write_register(ViPipe, 0x5f, 0x00); + n6_write_register(ViPipe, 0x62, 0x20); + n6_write_register(ViPipe, 0x7b, 0x00); + n6_write_register(ViPipe, 0x7c, 0x01); + n6_write_register(ViPipe, 0x7d, 0x80); + n6_write_register(ViPipe, 0x80, 0x00); + n6_write_register(ViPipe, 0x90, 0x01); + n6_write_register(ViPipe, 0xa9, 0x00); + n6_write_register(ViPipe, 0xb5, 0x00); + n6_write_register(ViPipe, 0xb8, 0xb9); + n6_write_register(ViPipe, 0xb9, 0x72); + n6_write_register(ViPipe, 0xd1, 0x00); + n6_write_register(ViPipe, 0xd5, 0x80); + + n6_write_register(ViPipe, 0xff, 0x09); + n6_write_register(ViPipe, 0x96 + ch * 0x20, 0x10); + n6_write_register(ViPipe, 0x98 + ch * 0x20, ntpal ? 0xc0 : 0xe0); + n6_write_register(ViPipe, 0x9e + ch * 0x20, 0x00); + + n6_write_register(ViPipe, 0xff, _MAR_BANK_); + val_20x01 = n6_read_register(ViPipe, 0x01); + val_20x01 &= (~(0x03 << (ch * 2))); + val_20x01 |= (0x02 << (ch * 2)); + n6_write_register(ViPipe, 0x01, val_20x01); + n6_write_register(ViPipe, 0x12 + ch * 2, 0xe0); + n6_write_register(ViPipe, 0x13 + ch * 2, 0x01); + +} + +void n6_set_chn_720p(VI_PIPE ViPipe, CVI_U8 ch, CVI_U8 ntpal) +{ + CVI_U8 val_0x54, val_20x01; + + CVI_TRACE_SNS(CVI_DBG_INFO, "%s ch=%d\n", __func__, ch); + + n6_write_register(ViPipe, 0xff, 0x00); + n6_write_register(ViPipe, 0x08 + ch, 0x00); + n6_write_register(ViPipe, 0x18 + ch, 0x3f); + n6_write_register(ViPipe, 0x30 + ch, 0x12); + n6_write_register(ViPipe, 0x34 + ch, 0x00); + val_0x54 = n6_read_register(ViPipe, 0x54); + val_0x54 &= ~(0x10 << ch); + n6_write_register(ViPipe, 0x54, val_0x54); + n6_write_register(ViPipe, 0x58 + ch, ntpal ? 0x80 : 0x80); + n6_write_register(ViPipe, 0x5c + ch, ntpal ? 0x00 : 0x00); + n6_write_register(ViPipe, 0x64 + ch, ntpal ? 0x01 : 0x01); + n6_write_register(ViPipe, 0x81 + ch, ntpal ? 0x0d : 0x0c); + n6_write_register(ViPipe, 0x85 + ch, 0x00); + n6_write_register(ViPipe, 0x89 + ch, 0x00); + n6_write_register(ViPipe, 0x8e + ch, 0x00); + n6_write_register(ViPipe, 0xa0 + ch, 0x05); + + n6_write_register(ViPipe, 0xff, 0x01); + n6_write_register(ViPipe, 0x84 + ch, 0x02); + n6_write_register(ViPipe, 0x88 + ch, 0x00); + n6_write_register(ViPipe, 0x8c + ch, 0x40); + n6_write_register(ViPipe, 0xa0 + ch, 0x20); + + n6_write_register(ViPipe, 0xff, 0x05 + ch); + n6_write_register(ViPipe, 0x01, 0x22); + n6_write_register(ViPipe, 0x05, 0x04); + n6_write_register(ViPipe, 0x08, 0x55); + n6_write_register(ViPipe, 0x25, 0xdc); + n6_write_register(ViPipe, 0x28, 0x80); + n6_write_register(ViPipe, 0x2f, 0x00); + n6_write_register(ViPipe, 0x30, 0xe0); + n6_write_register(ViPipe, 0x31, 0x43); + n6_write_register(ViPipe, 0x32, 0xa2); + n6_write_register(ViPipe, 0x47, 0xee); + n6_write_register(ViPipe, 0x50, 0xc6); + n6_write_register(ViPipe, 0x57, 0x00); + n6_write_register(ViPipe, 0x58, 0x77); + n6_write_register(ViPipe, 0x5b, 0x41); + n6_write_register(ViPipe, 0x5c, 0x7C); + n6_write_register(ViPipe, 0x5f, 0x00); + n6_write_register(ViPipe, 0x62, 0x20); + n6_write_register(ViPipe, 0x7b, 0x11); + n6_write_register(ViPipe, 0x7c, 0x01); + n6_write_register(ViPipe, 0x7d, 0x80); + n6_write_register(ViPipe, 0x80, 0x00); + n6_write_register(ViPipe, 0x90, 0x01); + n6_write_register(ViPipe, 0xa9, 0x00); + n6_write_register(ViPipe, 0xb5, 0x40); + n6_write_register(ViPipe, 0xb8, 0x39); + n6_write_register(ViPipe, 0xb9, 0x72); + n6_write_register(ViPipe, 0xd1, 0x00); + n6_write_register(ViPipe, 0xd5, 0x80); + + n6_write_register(ViPipe, 0xff, 0x09); + n6_write_register(ViPipe, 0x96 + ch * 0x20, 0x00); + n6_write_register(ViPipe, 0x98 + ch * 0x20, 0x00); + n6_write_register(ViPipe, 0x9e + ch * 0x20, 0x00); + + n6_write_register(ViPipe, 0xff, _MAR_BANK_); + val_20x01 = n6_read_register(ViPipe, 0x01); + val_20x01 &= (~(0x03 << (ch * 2))); + val_20x01 |= (0x01 << (ch * 2)); + n6_write_register(ViPipe, 0x01, val_20x01); + n6_write_register(ViPipe, 0x12 + ch * 2, 0x80); + n6_write_register(ViPipe, 0x13 + ch * 2, 0x02); + +} + +/* + * 1280x960p + * dev:0x60 / 0x62 / 0x64 / 0x66 + * ch : 0 ~ 3 + * ntpal: 1:25p, 0:30p + */ +void n6_set_chn_960p(VI_PIPE ViPipe, CVI_U8 ch, CVI_U8 ntpal) +{ + CVI_U8 val_0x54, val_20x01; + + CVI_TRACE_SNS(CVI_DBG_INFO, "%s ch=%d\n", __func__, ch); + + n6_write_register(ViPipe, 0xff, 0x00); + n6_write_register(ViPipe, 0x08 + ch, 0x00); + n6_write_register(ViPipe, 0x18 + ch, 0x0f); + n6_write_register(ViPipe, 0x30 + ch, 0x12); + n6_write_register(ViPipe, 0x34 + ch, 0x00); + val_0x54 = n6_read_register(ViPipe, 0x54); + val_0x54 &= ~(0x10 << ch); + n6_write_register(ViPipe, 0x54, val_0x54); + n6_write_register(ViPipe, 0x58 + ch, ntpal ? 0x40 : 0x48); + n6_write_register(ViPipe, 0x5c + ch, ntpal ? 0x80 : 0x80); + n6_write_register(ViPipe, 0x64 + ch, ntpal ? 0x28 : 0x28); + n6_write_register(ViPipe, 0x81 + ch, ntpal ? 0x07 : 0x06); + n6_write_register(ViPipe, 0x85 + ch, 0x0b); + n6_write_register(ViPipe, 0x89 + ch, 0x00); + n6_write_register(ViPipe, 0x8e + ch, 0x00); + n6_write_register(ViPipe, 0xa0 + ch, 0x05); + + n6_write_register(ViPipe, 0xff, 0x01); + n6_write_register(ViPipe, 0x84 + ch, 0x02); + n6_write_register(ViPipe, 0x88 + ch, 0x00); + n6_write_register(ViPipe, 0x8c + ch, 0x40); + n6_write_register(ViPipe, 0xa0 + ch, 0x20); + + n6_write_register(ViPipe, 0xff, 0x05 + ch); + n6_write_register(ViPipe, 0x01, 0x22); + n6_write_register(ViPipe, 0x05, 0x04); + n6_write_register(ViPipe, 0x08, 0x55); + n6_write_register(ViPipe, 0x25, 0xdc); + n6_write_register(ViPipe, 0x28, 0x80); + n6_write_register(ViPipe, 0x2f, 0x00); + n6_write_register(ViPipe, 0x30, 0xe0); + n6_write_register(ViPipe, 0x31, 0x43); + n6_write_register(ViPipe, 0x32, 0xa2); + n6_write_register(ViPipe, 0x47, 0xee); + n6_write_register(ViPipe, 0x50, 0xc6); + n6_write_register(ViPipe, 0x57, 0x00); + n6_write_register(ViPipe, 0x58, 0x77); + n6_write_register(ViPipe, 0x5b, 0x41); + n6_write_register(ViPipe, 0x5c, 0x7C); + n6_write_register(ViPipe, 0x5f, 0x00); + n6_write_register(ViPipe, 0x62, 0x20); + n6_write_register(ViPipe, 0x7b, 0x11); + n6_write_register(ViPipe, 0x7c, 0x01); + n6_write_register(ViPipe, 0x7d, 0x80); + n6_write_register(ViPipe, 0x80, 0x00); + n6_write_register(ViPipe, 0x90, 0x01); + n6_write_register(ViPipe, 0xa9, 0x00); + n6_write_register(ViPipe, 0xb5, 0x40); + n6_write_register(ViPipe, 0xb8, 0x39); + n6_write_register(ViPipe, 0xb9, 0x72); + n6_write_register(ViPipe, 0xd1, 0x00); + n6_write_register(ViPipe, 0xd5, 0x80); + + n6_write_register(ViPipe, 0xff, 0x09); + n6_write_register(ViPipe, 0x96 + ch * 0x20, 0x00); + n6_write_register(ViPipe, 0x98 + ch * 0x20, 0x00); + n6_write_register(ViPipe, 0x9e + ch * 0x20, 0x00); + + n6_write_register(ViPipe, 0xff, _MAR_BANK_); + val_20x01 = n6_read_register(ViPipe, 0x01); + val_20x01 &= (~(0x03 << (ch * 2))); + //val_20x01 |=(0x01<<(ch*2)); + n6_write_register(ViPipe, 0x01, val_20x01); + n6_write_register(ViPipe, 0x12 + ch * 2, 0x80); + n6_write_register(ViPipe, 0x13 + ch * 2, 0x02); + +} + +void n6_set_chn_1080p(VI_PIPE ViPipe, CVI_U8 ch, CVI_U8 ntpal) +{ + CVI_U8 val_0x54, val_20x01; + + CVI_TRACE_SNS(CVI_DBG_INFO, "%s ch=%d\n", __func__, ch); + + n6_write_register(ViPipe, 0xff, 0x00); + n6_write_register(ViPipe, 0x08 + ch, 0x00); + n6_write_register(ViPipe, 0x18 + ch, 0x3f); + n6_write_register(ViPipe, 0x30 + ch, 0x12); + n6_write_register(ViPipe, 0x34 + ch, 0x00); + val_0x54 = n6_read_register(ViPipe, 0x54); + val_0x54 &= ~(0x10 << ch); + n6_write_register(ViPipe, 0x54, val_0x54); + n6_write_register(ViPipe, 0x58 + ch, ntpal ? 0x80 : 0x80); + n6_write_register(ViPipe, 0x5c + ch, ntpal ? 0x00 : 0x00); + n6_write_register(ViPipe, 0x64 + ch, ntpal ? 0x01 : 0x01); + n6_write_register(ViPipe, 0x81 + ch, ntpal ? 0x03 : 0x02); + n6_write_register(ViPipe, 0x85 + ch, 0x00); + n6_write_register(ViPipe, 0x89 + ch, 0x10); + n6_write_register(ViPipe, 0x8e + ch, 0x00); + n6_write_register(ViPipe, 0xa0 + ch, 0x05); + + n6_write_register(ViPipe, 0xff, 0x01); + n6_write_register(ViPipe, 0x84 + ch, 0x02); + n6_write_register(ViPipe, 0x88 + ch, 0x00); + n6_write_register(ViPipe, 0x8c + ch, 0x40); + n6_write_register(ViPipe, 0xa0 + ch, 0x20); + + n6_write_register(ViPipe, 0xff, 0x05 + ch); + n6_write_register(ViPipe, 0x01, 0x22); + n6_write_register(ViPipe, 0x05, 0x04); + n6_write_register(ViPipe, 0x08, 0x55); + n6_write_register(ViPipe, 0x25, 0xdc); + n6_write_register(ViPipe, 0x28, 0x80); + n6_write_register(ViPipe, 0x2f, 0x00); + n6_write_register(ViPipe, 0x30, 0xe0); + n6_write_register(ViPipe, 0x31, 0x41); + n6_write_register(ViPipe, 0x32, 0xa2); + n6_write_register(ViPipe, 0x47, 0xee); + n6_write_register(ViPipe, 0x50, 0xc6); + n6_write_register(ViPipe, 0x57, 0x00); + n6_write_register(ViPipe, 0x58, 0x77); + n6_write_register(ViPipe, 0x5b, 0x41); + n6_write_register(ViPipe, 0x5c, 0x7C); + n6_write_register(ViPipe, 0x5f, 0x00); + n6_write_register(ViPipe, 0x62, 0x20); + n6_write_register(ViPipe, 0x7b, 0x11); + n6_write_register(ViPipe, 0x7c, 0x01); + n6_write_register(ViPipe, 0x7d, 0x80); + n6_write_register(ViPipe, 0x80, 0x00); + n6_write_register(ViPipe, 0x90, 0x01); + n6_write_register(ViPipe, 0xa9, 0x00); + n6_write_register(ViPipe, 0xb5, 0x40); + n6_write_register(ViPipe, 0xb8, 0x39); + n6_write_register(ViPipe, 0xb9, 0x72); + n6_write_register(ViPipe, 0xd1, 0x00); + n6_write_register(ViPipe, 0xd5, 0x80); + + n6_write_register(ViPipe, 0xff, 0x09); + n6_write_register(ViPipe, 0x96 + ch * 0x20, 0x00); + n6_write_register(ViPipe, 0x98 + ch * 0x20, 0x00); + n6_write_register(ViPipe, 0x9e + ch * 0x20, 0x00); + + n6_write_register(ViPipe, 0xff, _MAR_BANK_); + val_20x01 = n6_read_register(ViPipe, 0x01); + val_20x01 &= (~(0x03 << (ch * 2))); + n6_write_register(ViPipe, 0x01, val_20x01); + n6_write_register(ViPipe, 0x12 + ch*2, 0xc0); + n6_write_register(ViPipe, 0x13 + ch*2, 0x03); + +} + +unsigned char n6_read_vfc(VI_PIPE ViPipe, CVI_U8 ch) +{ + CVI_U8 ch_vfc = 0xff; + + n6_write_register(ViPipe, 0xff, 0x05 + ch); + ch_vfc = n6_read_register(ViPipe, 0xf0); + + return ch_vfc; +} + +void n6_device_auto_detect(VI_PIPE ViPipe) +{ + CVI_U8 ch_vfc[16] = {0xff, 0xff, 0xff, 0xff, 0xff}; + CVI_U8 val_13x70, val_13x71; + int check_cnt = 0; + CVI_U8 ch; + + CVI_TRACE_SNS(CVI_DBG_INFO, "%s auto detection routine\n", __func__); + + n6_write_register(ViPipe, 0xFF, 0x13); + n6_write_register(ViPipe, 0x30, 0x7f); + n6_write_register(ViPipe, 0x70, 0xf0); + n6_write_register(ViPipe, 0xFF, 0x00); + n6_write_register(ViPipe, 0x00, 0x18); + n6_write_register(ViPipe, 0x01, 0x18); + n6_write_register(ViPipe, 0x02, 0x18); + n6_write_register(ViPipe, 0x03, 0x18); + n6_write_register(ViPipe, 0x00, 0x10); + n6_write_register(ViPipe, 0x01, 0x10); + n6_write_register(ViPipe, 0x02, 0x10); + n6_write_register(ViPipe, 0x03, 0x10); + while ((check_cnt++) < 50) { + for (ch = 0; ch < 4; ch++) { + ch_vfc[ch] = n6_read_vfc(ViPipe, ch); + if (ch_vfc[ch] != 0xff) + syslog(LOG_DEBUG, "ch[%d] video vfc read value0 : %2x\n", ch, ch_vfc[ch]); + } + delay_ms(40); + } + for (ch = 0; ch < 4; ch++) { + n6_write_register(ViPipe, 0xFF, 0x13); + val_13x70 = n6_read_register(ViPipe, 0x70); + val_13x70 |= (0x01< +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "os04a10_cmos_ex.h" +#include "os04a10_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define OS04A10_ID 0x530441 +#define OS04A10_I2C_ADDR_1 0x10 +#define OS04A10_I2C_ADDR_2 0x36 +#define OS04A10_I2C_ADDR_IS_VALID(addr) ((addr) == OS04A10_I2C_ADDR_1 || (addr) == OS04A10_I2C_ADDR_2) +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastOs04a10[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define OS04A10_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastOs04a10[dev]) +#define OS04A10_SENSOR_SET_CTX(dev, pstCtx) (g_pastOs04a10[dev] = pstCtx) +#define OS04A10_SENSOR_RESET_CTX(dev) (g_pastOs04a10[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunOs04a10_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Os04a10_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Os04a10_UseHwSync[VI_MAX_PIPE_NUM] = {0}; + +OS04A10_STATE_S g_astOs04a10_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeOs04a10_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Os04a10 Lines Range*****/ +#define OS04A10_FULL_LINES_MAX (0xFFFF) +#define OS04A10_FULL_LINES_MAX_2TO1_WDR (0xFFFF) + +/*****Os04a10 Register Address*****/ +#define OS04A10_HOLD_3208 0x3208 +#define OS04A10_HOLD_320D 0x320D +#define OS04A10_EXP1_ADDR 0x3501 +#define OS04A10_EXP2_ADDR 0x3541 +#define OS04A10_AGAIN1_ADDR 0x3508 +#define OS04A10_DGAIN1_ADDR 0x350A +#define OS04A10_AGAIN2_ADDR 0x3548 +#define OS04A10_DGAIN2_ADDR 0x354A +#define OS04A10_VTS_ADDR 0x380E +#define OS04A10_TABLE_END 0xffff + +#define OS04A10_RES_IS_1520P(w, h) ((w) == 2688 && (h) == 1520) +#define OS04A10_RES_IS_1440P(w, h) ((w) == 2560 && (h) == 1440) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const OS04A10_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astOs04a10_mode[pstSnsState->u8ImgMode]; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = OS04A10_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + //pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + //pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ + + } + break; + } + CVI_TRACE_SNS(CVI_DBG_INFO, "again[%d, %d], dgain[%d, %d]\n", + pstAeSnsDft->u32MinAgain, pstAeSnsDft->u32MaxAgain, pstAeSnsDft->u32MinDgain, pstAeSnsDft->u32MaxDgain); + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX, l2s_offset, v_start, v_end, isp_res, max_l2s; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astOs04a10_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astOs04a10_mode[pstSnsState->u8ImgMode].f32MinFps; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OS04A10_FULL_LINES_MAX) ? OS04A10_FULL_LINES_MAX : u32VMAX; + + pstSnsRegsInfo->astI2cData[LINEAR_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_1].u32Data = (u32VMAX & 0xFF); + } else { + l2s_offset = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32L2S_offset; + v_start = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32VStart; + v_end = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32VEnd; + isp_res = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32IspResTime; + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OS04A10_FULL_LINES_MAX_2TO1_WDR) ? + OS04A10_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + + /* Short exposure < Long to Short Distance - 1 + * Max L-S Distance = VTS - (Yend + 1 - Ystart) - l2s_offset(40) + */ + max_l2s = u32VMAX - (v_end + 1 - v_start) - l2s_offset; + if (max_l2s > isp_res) + max_l2s -= isp_res; + else + CVI_TRACE_SNS(CVI_DBG_WARN, "cannot reserve 1ms for isp delay %d\n", max_l2s); + + g_astOs04a10_State[ViPipe].u32Sexp_MAX = max_l2s - 4; + pstSnsRegsInfo->astI2cData[WDR2_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_VTS_1].u32Data = (u32VMAX & 0xFF); + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32IntTime[0]; + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = u32IntTime[1]; + + pstSnsRegsInfo->astI2cData[WDR2_EXP1_0].u32Data = ((pstSnsState->au32WDRIntTime[1] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_EXP1_1].u32Data = (pstSnsState->au32WDRIntTime[1] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_EXP2_0].u32Data = ((pstSnsState->au32WDRIntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_EXP2_1].u32Data = (pstSnsState->au32WDRIntTime[0] & 0xFF); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + CVI_U32 u32TmpIntTime = u32IntTime[0]; + CVI_U32 maxExp = pstSnsState->au32FL[0] - 8; + /* linear exposure reg range: + * min : 2 + * max : vts - 8 + * step : 1 + */ + u32TmpIntTime = (u32TmpIntTime > maxExp) ? maxExp : u32TmpIntTime; + u32TmpIntTime = u32TmpIntTime >= 2 ? u32TmpIntTime : 2; + u32IntTime[0] = u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_0].u32Data = ((u32TmpIntTime & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_1].u32Data = (u32TmpIntTime & 0xFF); + } + + return CVI_SUCCESS; + +} + +typedef struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} gain_tbl_info_s; + +static struct gain_tbl_info_s AgainInfo[15] = { + { + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x01, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 2944, + .idxBase = 16, + .regGain = 0x02, + .regGainFineBase = 0x00, + .regGainFineStep = 2, + }, + { + .gainMax = 3968, + .idxBase = 24, + .regGain = 0x03, + .regGainFineBase = 0x00, + .regGainFineStep = 2, + }, + { + .gainMax = 4864, + .idxBase = 32, + .regGain = 0x04, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 5888, + .idxBase = 36, + .regGain = 0x05, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 6912, + .idxBase = 40, + .regGain = 0x06, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 7936, + .idxBase = 44, + .regGain = 0x07, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 8704, + .idxBase = 48, + .regGain = 0x08, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 9728, + .idxBase = 50, + .regGain = 0x09, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 10752, + .idxBase = 52, + .regGain = 0x0a, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 11776, + .idxBase = 54, + .regGain = 0x0b, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 12800, + .idxBase = 56, + .regGain = 0x0c, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 13824, + .idxBase = 58, + .regGain = 0x0d, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 14848, + .idxBase = 60, + .regGain = 0x0e, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 15872, + .idxBase = 62, + .regGain = 0x0f, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, +}; + +static CVI_U32 Again_table[65] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; + +static struct gain_tbl_info_s DgainInfo[15] = { + { + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x01, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 3008, + .idxBase = 16, + .regGain = 0x02, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 5056, + .idxBase = 48, + .regGain = 0x04, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 6080, + .idxBase = 64, + .regGain = 0x05, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 7104, + .idxBase = 80, + .regGain = 0x06, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 8128, + .idxBase = 96, + .regGain = 0x07, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 9152, + .idxBase = 112, + .regGain = 0x08, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 10176, + .idxBase = 128, + .regGain = 0x09, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 11200, + .idxBase = 144, + .regGain = 0x0a, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 12224, + .idxBase = 160, + .regGain = 0x0b, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 13248, + .idxBase = 176, + .regGain = 0x0c, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 14272, + .idxBase = 192, + .regGain = 0x0d, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 15296, + .idxBase = 208, + .regGain = 0x0e, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 16320, + .idxBase = 224, + .regGain = 0x0f, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, +}; + +static CVI_U32 Dgain_table[240] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, 1856, 1920, + 1984, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, + 2944, 3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, + 3904, 3968, 4032, 4096, 4160, 4224, 4288, 4352, 4416, 4480, 4544, 4608, 4672, 4736, 4800, + 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, 5504, 5568, 5632, 5696, 5760, + 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, 6464, 6528, 6592, 6656, 6720, + 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, 7424, 7488, 7552, 7616, 7680, + 7744, 7808, 7872, 7936, 8000, 8064, 8128, 8192, 8256, 8320, 8384, 8448, 8512, 8576, 8640, + 8704, 8768, 8832, 8896, 8960, 9024, 9088, 9152, 9216, 9280, 9344, 9408, 9472, 9536, 9600, + 9664, 9728, 9792, 9856, 9920, 9984, 10048, 10112, 10176, 10240, 10304, 10368, 10432, 10496, + 10560, 10624, 10688, 10752, 10816, 10880, 10944, 11008, 11072, 11136, 11200, 11264, 11328, + 11392, 11456, 11520, 11584, 11648, 11712, 11776, 11840, 11904, 11968, 12032, 12096, 12160, + 12224, 12288, 12352, 12416, 12480, 12544, 12608, 12672, 12736, 12800, 12864, 12928, 12992, + 13056, 13120, 13184, 13248, 13312, 13376, 13440, 13504, 13568, 13632, 13696, 13760, 13824, + 13888, 13952, 14016, 14080, 14144, 14208, 14272, 14336, 14400, 14464, 14528, 14592, 14656, + 14720, 14784, 14848, 14912, 14976, 15040, 15104, 15168, 15232, 15296, 15360, 15424, 15488, + 15552, 15616, 15680, 15744, 15808, 15872, 15936, 16000, 16064, 16128, 16192, 16256, 16320 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[63]) { + *pu32AgainLin = Again_table[63]; + *pu32AgainDb = 63; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[239]) { + *pu32DgainLin = Dgain_table[239]; + *pu32DgainDb = 239; + return CVI_SUCCESS; + } + + for (i = 1; i < 240; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_1].u32Data = (u32Again & 0xFF) << 4; + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1].u32Data = (u32Dgain & 0xFF) << 4; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_2].u32Data = 0x00; + } else { + /* DOL mode */ + if (g_au16Os04a10_GainMode[ViPipe] == SNS_GAIN_MODE_WDR_2F) { + //sef gain + /* find SEF Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_0].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_1].u32Data = (u32Again & 0xFF) << 4; + + /* find SEF Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_0].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_1].u32Data = (u32Dgain & 0xFF) << 4; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_2].u32Data = 0x00; + + u32Again = pu32Again[1]; //lef gain + u32Dgain = pu32Dgain[1]; + /* find LEF Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_0].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_1].u32Data = (u32Again & 0xFF) << 4; + + /* find LEF Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_0].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_1].u32Data = (u32Dgain & 0xFF) << 4; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_2].u32Data = 0x00; + } else if (g_au16Os04a10_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_0].u32Data = (info->regGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_0].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_1].u32Data = (u32Again & 0xFF) << 4; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_1].u32Data = (u32Again & 0xFF) << 4; + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_0].u32Data = (info->regGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_0].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_1].u32Data = (u32Dgain & 0xFF) << 4; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_1].u32Data = (u32Dgain & 0xFF) << 4; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_2].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_2].u32Data = 0x00; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = 2; + /* + * Long exp + Short exp < VTS - 8 + */ + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 8 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 8) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + + u32IntTimeMaxTmp = (g_astOs04a10_State[ViPipe].u32Sexp_MAX < u32IntTimeMaxTmp) ? + g_astOs04a10_State[ViPipe].u32Sexp_MAX : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? u32ShortTimeMinLimit : u32IntTimeMaxTmp; + syslog(LOG_DEBUG, "Max inttime0 = %u\n", u32IntTimeMaxTmp); + + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio is too large!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + CVI_TRACE_SNS(CVI_DBG_DEBUG, "sexp[%d, %d], lexp[%d, %d], ratio:%d, max_sexp:%d\n", + au32IntTimeMin[0], au32IntTimeMax[0], au32IntTimeMin[1], au32IntTimeMax[1], + au32Ratio[0], g_astOs04a10_State[ViPipe].u32Sexp_MAX); + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + else + memcpy(pstBlc, + &g_stIspBlcCalibratio10Bit, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const OS04A10_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astOs04a10_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == OS04A10_MODE_1440P30_WDR) + pstSnsState->u8ImgMode = OS04A10_MODE_1440P30_12BIT; + + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == OS04A10_MODE_1440P30_12BIT) { + pstSnsState->u8ImgMode = OS04A10_MODE_1440P30_WDR; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1440p mode(60fps->30fps)\n"); + } + + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32VtsDef; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunOs04a10_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = os04a10_i2c_addr; + pstI2c_data[i].u32AddrByteNum = os04a10_addr_byte; + pstI2c_data[i].u32DataByteNum = os04a10_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[WDR2_HOLD_START].u32RegAddr = OS04A10_HOLD_3208; + pstI2c_data[WDR2_HOLD_START].u32Data = 0x00; + pstI2c_data[WDR2_EXP1_0].u32RegAddr = OS04A10_EXP1_ADDR; + pstI2c_data[WDR2_EXP1_1].u32RegAddr = OS04A10_EXP1_ADDR + 1; + pstI2c_data[WDR2_EXP2_0].u32RegAddr = OS04A10_EXP2_ADDR; + pstI2c_data[WDR2_EXP2_1].u32RegAddr = OS04A10_EXP2_ADDR + 1; + pstI2c_data[WDR2_AGAIN1_0].u32RegAddr = OS04A10_AGAIN1_ADDR; + pstI2c_data[WDR2_AGAIN1_1].u32RegAddr = OS04A10_AGAIN1_ADDR + 1; + pstI2c_data[WDR2_AGAIN2_0].u32RegAddr = OS04A10_AGAIN2_ADDR; + pstI2c_data[WDR2_AGAIN2_1].u32RegAddr = OS04A10_AGAIN2_ADDR + 1; + pstI2c_data[WDR2_DGAIN1_0].u32RegAddr = OS04A10_DGAIN1_ADDR; + pstI2c_data[WDR2_DGAIN1_1].u32RegAddr = OS04A10_DGAIN1_ADDR + 1; + pstI2c_data[WDR2_DGAIN2_0].u32RegAddr = OS04A10_DGAIN2_ADDR; + pstI2c_data[WDR2_DGAIN2_1].u32RegAddr = OS04A10_DGAIN2_ADDR + 1; + pstI2c_data[WDR2_VTS_0].u32RegAddr = OS04A10_VTS_ADDR; + pstI2c_data[WDR2_VTS_1].u32RegAddr = OS04A10_VTS_ADDR + 1; + pstI2c_data[WDR2_HOLD_END].u32RegAddr = OS04A10_HOLD_3208; + pstI2c_data[WDR2_HOLD_END].u32Data = 0x10; + pstI2c_data[WDR2_LAUNCH_0].u32RegAddr = OS04A10_HOLD_320D; + pstI2c_data[WDR2_LAUNCH_0].u32Data = 0x00; + pstI2c_data[WDR2_LAUNCH_0].u8DelayFrmNum = 0; + pstI2c_data[WDR2_LAUNCH_1].u32RegAddr = OS04A10_HOLD_3208; + pstI2c_data[WDR2_LAUNCH_1].u32Data = 0xA0; + pstI2c_data[WDR2_LAUNCH_1].u8DelayFrmNum = 0; + break; + default: + pstI2c_data[LINEAR_HOLD_START].u32RegAddr = OS04A10_HOLD_3208; + pstI2c_data[LINEAR_HOLD_START].u32Data = 0x00; + pstI2c_data[LINEAR_EXP_0].u32RegAddr = OS04A10_EXP1_ADDR; + pstI2c_data[LINEAR_EXP_1].u32RegAddr = OS04A10_EXP1_ADDR + 1; + pstI2c_data[LINEAR_AGAIN_0].u32RegAddr = OS04A10_AGAIN1_ADDR; + pstI2c_data[LINEAR_AGAIN_1].u32RegAddr = OS04A10_AGAIN1_ADDR + 1; + pstI2c_data[LINEAR_DGAIN_0].u32RegAddr = OS04A10_DGAIN1_ADDR; + pstI2c_data[LINEAR_DGAIN_1].u32RegAddr = OS04A10_DGAIN1_ADDR + 1; + pstI2c_data[LINEAR_DGAIN_2].u32RegAddr = OS04A10_DGAIN1_ADDR + 2; + pstI2c_data[LINEAR_VTS_0].u32RegAddr = OS04A10_VTS_ADDR; + pstI2c_data[LINEAR_VTS_1].u32RegAddr = OS04A10_VTS_ADDR + 1; + pstI2c_data[LINEAR_HOLD_END].u32RegAddr = OS04A10_HOLD_3208; + pstI2c_data[LINEAR_HOLD_END].u32Data = 0x10; + pstI2c_data[LINEAR_LAUNCH_0].u32RegAddr = OS04A10_HOLD_320D; + pstI2c_data[LINEAR_LAUNCH_0].u32Data = 0x00; + pstI2c_data[LINEAR_LAUNCH_0].u8DelayFrmNum = 0; + pstI2c_data[LINEAR_LAUNCH_1].u32RegAddr = OS04A10_HOLD_3208; + pstI2c_data[LINEAR_LAUNCH_1].u32Data = 0xA0; + pstI2c_data[LINEAR_LAUNCH_1].u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[WDR2_HOLD_START].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_HOLD_END].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_LAUNCH_0].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_LAUNCH_1].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD_START].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_HOLD_END].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_LAUNCH_0].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_LAUNCH_1].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (OS04A10_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = OS04A10_MODE_1440P30_12BIT; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (OS04A10_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = OS04A10_MODE_1440P30_WDR; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeOs04a10_MirrorFip[ViPipe] != eSnsMirrorFlip) { + os04a10_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeOs04a10_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = OS04A10_MODE_1440P30_12BIT; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astOs04a10_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &os04a10_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astOs04a10_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astOs04a10_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } else { + pstRxAttr->mac_clk = RX_MAC_CLK_400M; + pstRxAttr->mipi_attr.raw_data_type = RAW_DATA_10BIT; + pstRxAttr->mclk.freq = CAMPLL_FREQ_24M; + } + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &os04a10_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = os04a10_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = os04a10_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (OS04A10_I2C_ADDR_IS_VALID(s32I2cAddr)) + os04a10_i2c_addr = s32I2cAddr; +} + +static CVI_S32 os04a10_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunOs04a10_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + OS04A10_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OS04A10_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + OS04A10_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = OS04A10_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, OS04A10_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, OS04A10_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, OS04A10_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Os04a10_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Os04a10_UseHwSync[ViPipe] = pstInitAttr->u16UseHwSync; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsOs04a10_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = os04a10_standby, + .pfnRestart = os04a10_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = os04a10_write_register, + .pfnReadReg = os04a10_read_register, + .pfnSetBusInfo = os04a10_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_os04a10/os04a10_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/ov_os04a10/os04a10_cmos_ex.h new file mode 100644 index 000000000..5fb642510 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_os04a10/os04a10_cmos_ex.h @@ -0,0 +1,117 @@ +#ifndef __OS04A10_CMOS_EX_H_ +#define __OS04A10_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum os04a10_linear_regs_e { + LINEAR_HOLD_START = 0, + LINEAR_EXP_0, + LINEAR_EXP_1, + LINEAR_AGAIN_0, + LINEAR_AGAIN_1, + LINEAR_DGAIN_0, + LINEAR_DGAIN_1, + LINEAR_DGAIN_2, + LINEAR_VTS_0, + LINEAR_VTS_1, + LINEAR_HOLD_END, + LINEAR_LAUNCH_0, + LINEAR_LAUNCH_1, + LINEAR_REGS_NUM +}; + +enum os04a10_wdr2_regs_e { + WDR2_HOLD_START = 0, + WDR2_EXP1_0, + WDR2_EXP1_1, + WDR2_EXP2_0, + WDR2_EXP2_1, + WDR2_AGAIN1_0, + WDR2_AGAIN1_1, + WDR2_AGAIN2_0, + WDR2_AGAIN2_1, + WDR2_DGAIN1_0, + WDR2_DGAIN1_1, + WDR2_DGAIN1_2, + WDR2_DGAIN2_0, + WDR2_DGAIN2_1, + WDR2_DGAIN2_2, + WDR2_VTS_0, + WDR2_VTS_1, + WDR2_HOLD_END, + WDR2_LAUNCH_0, + WDR2_LAUNCH_1, + WDR2_REGS_NUM +}; + +typedef enum _OS04A10_MODE_E { + OS04A10_MODE_1440P30_12BIT = 0, + OS04A10_MODE_LINEAR_NUM, + OS04A10_MODE_1440P30_WDR = OS04A10_MODE_LINEAR_NUM, + OS04A10_MODE_NUM +} OS04A10_MODE_E; + +typedef struct _OS04A10_STATE_S { + CVI_U32 u32Sexp_MAX; +} OS04A10_STATE_S; + +typedef struct _OS04A10_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; + CVI_U32 u32L2S_offset; + CVI_U32 u32IspResTime; + CVI_U32 u32VStart; + CVI_U32 u32VEnd; +} OS04A10_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastOs04a10[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunOs04a10_BusInfo[]; +extern CVI_U16 g_au16Os04a10_GainMode[]; +extern CVI_U16 g_au16Os04a10_UseHwSync[VI_MAX_PIPE_NUM]; +extern CVI_U8 os04a10_i2c_addr; +extern const CVI_U32 os04a10_addr_byte; +extern const CVI_U32 os04a10_data_byte; +extern void os04a10_init(VI_PIPE ViPipe); +extern void os04a10_exit(VI_PIPE ViPipe); +extern void os04a10_standby(VI_PIPE ViPipe); +extern void os04a10_restart(VI_PIPE ViPipe); +extern void os04a10_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int os04a10_write_register(VI_PIPE ViPipe, int addr, int data); +extern int os04a10_read_register(VI_PIPE ViPipe, int addr); +extern int os04a10_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OS04A10_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_os04a10/os04a10_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/ov_os04a10/os04a10_cmos_param.h new file mode 100644 index 000000000..6cdd6294e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_os04a10/os04a10_cmos_param.h @@ -0,0 +1,237 @@ +#ifndef __OS04A10_CMOS_PARAM_H_ +#define __OS04A10_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "os04a10_cmos_ex.h" + +static const OS04A10_MODE_S g_astOs04a10_mode[OS04A10_MODE_NUM] = { + [OS04A10_MODE_1440P30_12BIT] = { + .name = "1440p30_12bit", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + .stWndRect = { + .s32X = 64, + .s32Y = 40, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.74, /* 0x658 * 30 / 0xFFFF */ + .u32HtsDef = 2688, + .u32VtsDef = 1624, + .stExp[0] = { + .u16Min = 2, + .u16Max = 1624 - 8, + .u16Def = 500, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16373, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [OS04A10_MODE_1440P30_WDR] = { + .name = "1440p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + .stWndRect = { + .s32X = 64, + .s32Y = 40, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + .stWndRect = { + .s32X = 64, + .s32Y = 40, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.74, /* 1624 * 30 / 0xFFFF */ + .u32HtsDef = 2972, + .u32VtsDef = 1624, + .u32L2S_offset = 40, + .u32IspResTime = 49, /* ceil((u32Vts * f32MaxFps) / 1000); about 1ms*/ + .u32VStart = 0, + .u32VEnd = 0x5ff, + .stExp[0] = { + .u16Min = 8, + .u16Max = 88, + .u16Def = 88, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 8, + .u16Max = 0x486 - 4 - 88, + .u16Def = 500, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16373, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 16373, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {128, 128, 128, 128, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1057, 1057, 1057, 1057 +#endif + }, + .stAuto = { + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, +#endif + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio10Bit = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, +#endif + }, + }, +}; + +struct combo_dev_attr_s os04a10_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_500M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {0, 1, 2, 3, 4}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + .dphy = { + .enable = 1, + .hs_settle = 8, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_25M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OS04A10_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_os04a10/os04a10_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/ov_os04a10/os04a10_sensor_ctl.c new file mode 100644 index 000000000..435483b32 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_os04a10/os04a10_sensor_ctl.c @@ -0,0 +1,893 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "os04a10_cmos_ex.h" + +static void os04a10_wdr_1520p30_2to1_init(VI_PIPE ViPipe); +static void os04a10_linear_1520p30_12BIT_init(VI_PIPE ViPipe); + +CVI_U8 os04a10_i2c_addr = 0x36; /* I2C Address of OS04A10 */ +const CVI_U32 os04a10_addr_byte = 2; +const CVI_U32 os04a10_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeOs04a10_MirrorFip_Initial[VI_MAX_PIPE_NUM] = { + ISP_SNS_MIRROR, ISP_SNS_MIRROR, ISP_SNS_MIRROR, ISP_SNS_MIRROR}; + +int os04a10_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunOs04a10_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, os04a10_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + return CVI_SUCCESS; +} + +int os04a10_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int os04a10_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (os04a10_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, os04a10_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, os04a10_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (os04a10_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int os04a10_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (os04a10_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (os04a10_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, os04a10_addr_byte + os04a10_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} +/* + *static void delay_ms(int ms) + *{ + * usleep(ms * 1000); + *} + */ +void os04a10_standby(VI_PIPE ViPipe) +{ + os04a10_write_register(ViPipe, 0x0100, 0x00); /* STANDBY */ +} + +void os04a10_restart(VI_PIPE ViPipe) +{ + os04a10_write_register(ViPipe, 0x0100, 0x01); /* resume */ +} + +void os04a10_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + CVI_U32 start = 1; + CVI_U32 end = g_pastOs04a10[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum - 3; + + for (i = start; i < end; i++) { + os04a10_write_register(ViPipe, + g_pastOs04a10[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastOs04a10[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + CVI_TRACE_SNS(CVI_DBG_INFO, "i2c_addr:%#x, i2c_data:%#x\n", + g_pastOs04a10[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastOs04a10[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +ISP_SNS_MIRRORFLIP_TYPE_E aeSnsMirrorFlipMap[ISP_SNS_BUTT][ISP_SNS_BUTT] = { + {ISP_SNS_NORMAL, ISP_SNS_MIRROR, ISP_SNS_FLIP, ISP_SNS_MIRROR_FLIP}, + {ISP_SNS_MIRROR, ISP_SNS_NORMAL, ISP_SNS_MIRROR_FLIP, ISP_SNS_FLIP}, + {ISP_SNS_FLIP, ISP_SNS_MIRROR_FLIP, ISP_SNS_NORMAL, ISP_SNS_MIRROR}, + {ISP_SNS_MIRROR_FLIP, ISP_SNS_FLIP, ISP_SNS_MIRROR, ISP_SNS_NORMAL} +}; + +#define OS04A10_ORIEN_ADDR (0x3820) +void os04a10_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + CVI_U32 i = 0; + + for (i = 0; i < ISP_SNS_BUTT; i++) { + if (g_aeOs04a10_MirrorFip_Initial[ViPipe] == aeSnsMirrorFlipMap[i][0]) { + eSnsMirrorFlip = aeSnsMirrorFlipMap[i][eSnsMirrorFlip]; + break; + } + } + + val = os04a10_read_register(ViPipe, OS04A10_ORIEN_ADDR); + val &= ~(0x3 << 1); + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x1<<1; + break; + case ISP_SNS_FLIP: + val |= 0x1<<2; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x1<<1; + val |= 0x1<<2; + break; + default: + return; + } + + os04a10_standby(ViPipe); + os04a10_write_register(ViPipe, OS04A10_ORIEN_ADDR, val); + usleep(1000*100); + os04a10_restart(ViPipe); +} + +#define OS04A10_CHIP_ID_ADDR_H 0x300A +#define OS04A10_CHIP_ID_ADDR_M 0x300B +#define OS04A10_CHIP_ID_ADDR_L 0x300C +#define OS04A10_CHIP_ID 0x530441 + +int os04a10_probe(VI_PIPE ViPipe) +{ + int nVal, nVal2, nVal3; + + usleep(500); + if (os04a10_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = os04a10_read_register(ViPipe, OS04A10_CHIP_ID_ADDR_H); + nVal2 = os04a10_read_register(ViPipe, OS04A10_CHIP_ID_ADDR_M); + nVal3 = os04a10_read_register(ViPipe, OS04A10_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0 || nVal3 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 16) | ((nVal2 & 0xFF) << 8) | (nVal3 & 0xFF)) != OS04A10_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void os04a10_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastOs04a10[ViPipe]->enWDRMode; + u8ImgMode = g_pastOs04a10[ViPipe]->u8ImgMode; + + os04a10_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == OS04A10_MODE_1440P30_WDR) + os04a10_wdr_1520p30_2to1_init(ViPipe); + } else { + if (u8ImgMode == OS04A10_MODE_1440P30_12BIT) + os04a10_linear_1520p30_12BIT_init(ViPipe); + } + g_pastOs04a10[ViPipe]->bInit = CVI_TRUE; +} + +void os04a10_exit(VI_PIPE ViPipe) +{ + os04a10_i2c_exit(ViPipe); +} + +static void os04a10_linear_1520p30_12BIT_init(VI_PIPE ViPipe) +{ + os04a10_write_register(ViPipe, 0x0103, 0x01); + os04a10_write_register(ViPipe, 0x0109, 0x01); + os04a10_write_register(ViPipe, 0x0104, 0x02); + os04a10_write_register(ViPipe, 0x0102, 0x00); + os04a10_write_register(ViPipe, 0x0305, 0x40); + os04a10_write_register(ViPipe, 0x0306, 0x00); + os04a10_write_register(ViPipe, 0x0307, 0x00); + os04a10_write_register(ViPipe, 0x0308, 0x05); + os04a10_write_register(ViPipe, 0x030a, 0x01); + os04a10_write_register(ViPipe, 0x0317, 0x0a); + os04a10_write_register(ViPipe, 0x0322, 0x01); + os04a10_write_register(ViPipe, 0x0323, 0x02); + os04a10_write_register(ViPipe, 0x0324, 0x00); + os04a10_write_register(ViPipe, 0x0325, 0x8b); + os04a10_write_register(ViPipe, 0x0327, 0x05); + os04a10_write_register(ViPipe, 0x0329, 0x02); + os04a10_write_register(ViPipe, 0x032c, 0x02); + os04a10_write_register(ViPipe, 0x032d, 0x02); + os04a10_write_register(ViPipe, 0x032e, 0x02); + os04a10_write_register(ViPipe, 0x300f, 0x11); + os04a10_write_register(ViPipe, 0x3012, 0x41); + os04a10_write_register(ViPipe, 0x3026, 0x10); + os04a10_write_register(ViPipe, 0x3027, 0x08); + os04a10_write_register(ViPipe, 0x302d, 0x24); + os04a10_write_register(ViPipe, 0x3104, 0x01); + os04a10_write_register(ViPipe, 0x3106, 0x11); + os04a10_write_register(ViPipe, 0x3400, 0x00); + os04a10_write_register(ViPipe, 0x3408, 0x05); + os04a10_write_register(ViPipe, 0x340c, 0x0c); + os04a10_write_register(ViPipe, 0x340d, 0xb0); + os04a10_write_register(ViPipe, 0x3425, 0x51); + os04a10_write_register(ViPipe, 0x3426, 0x10); + os04a10_write_register(ViPipe, 0x3427, 0x14); + os04a10_write_register(ViPipe, 0x3428, 0x10); + os04a10_write_register(ViPipe, 0x3429, 0x10); + os04a10_write_register(ViPipe, 0x342a, 0x10); + os04a10_write_register(ViPipe, 0x342b, 0x04); + os04a10_write_register(ViPipe, 0x3501, 0x02); + os04a10_write_register(ViPipe, 0x3504, 0x08); + os04a10_write_register(ViPipe, 0x3508, 0x01); + os04a10_write_register(ViPipe, 0x3509, 0x00); + os04a10_write_register(ViPipe, 0x350a, 0x01); + os04a10_write_register(ViPipe, 0x3544, 0x08); + os04a10_write_register(ViPipe, 0x3548, 0x01); + os04a10_write_register(ViPipe, 0x3549, 0x00); + os04a10_write_register(ViPipe, 0x3584, 0x08); + os04a10_write_register(ViPipe, 0x3588, 0x01); + os04a10_write_register(ViPipe, 0x3589, 0x00); + os04a10_write_register(ViPipe, 0x3601, 0x70); + os04a10_write_register(ViPipe, 0x3604, 0xe3); + os04a10_write_register(ViPipe, 0x3605, 0xff); + os04a10_write_register(ViPipe, 0x3606, 0x01); + os04a10_write_register(ViPipe, 0x3608, 0xa8); + os04a10_write_register(ViPipe, 0x360a, 0xd0); + os04a10_write_register(ViPipe, 0x360b, 0x08); + os04a10_write_register(ViPipe, 0x360e, 0xc8); + os04a10_write_register(ViPipe, 0x360f, 0x66); + os04a10_write_register(ViPipe, 0x3610, 0x89); + os04a10_write_register(ViPipe, 0x3611, 0x8a); + os04a10_write_register(ViPipe, 0x3612, 0x4e); + os04a10_write_register(ViPipe, 0x3613, 0xbd); + os04a10_write_register(ViPipe, 0x3614, 0x9b); + os04a10_write_register(ViPipe, 0x362a, 0x0e); + os04a10_write_register(ViPipe, 0x362b, 0x0e); + os04a10_write_register(ViPipe, 0x362c, 0x0e); + os04a10_write_register(ViPipe, 0x362d, 0x09); + os04a10_write_register(ViPipe, 0x362e, 0x1a); + os04a10_write_register(ViPipe, 0x362f, 0x34); + os04a10_write_register(ViPipe, 0x3630, 0x67); + os04a10_write_register(ViPipe, 0x3631, 0x7f); + os04a10_write_register(ViPipe, 0x3638, 0x00); + os04a10_write_register(ViPipe, 0x3643, 0x00); + os04a10_write_register(ViPipe, 0x3644, 0x00); + os04a10_write_register(ViPipe, 0x3645, 0x00); + os04a10_write_register(ViPipe, 0x3646, 0x00); + os04a10_write_register(ViPipe, 0x3647, 0x00); + os04a10_write_register(ViPipe, 0x3648, 0x00); + os04a10_write_register(ViPipe, 0x3649, 0x00); + os04a10_write_register(ViPipe, 0x364a, 0x04); + os04a10_write_register(ViPipe, 0x364c, 0x0e); + os04a10_write_register(ViPipe, 0x364d, 0x0e); + os04a10_write_register(ViPipe, 0x364e, 0x0e); + os04a10_write_register(ViPipe, 0x364f, 0x0e); + os04a10_write_register(ViPipe, 0x3650, 0xff); + os04a10_write_register(ViPipe, 0x3651, 0xff); + os04a10_write_register(ViPipe, 0x365a, 0x00); + os04a10_write_register(ViPipe, 0x365b, 0x00); + os04a10_write_register(ViPipe, 0x365c, 0x00); + os04a10_write_register(ViPipe, 0x365d, 0x00); + os04a10_write_register(ViPipe, 0x3661, 0x07); + os04a10_write_register(ViPipe, 0x3662, 0x00); + os04a10_write_register(ViPipe, 0x3663, 0x20); + os04a10_write_register(ViPipe, 0x3665, 0x12); + os04a10_write_register(ViPipe, 0x3667, 0xd4); + os04a10_write_register(ViPipe, 0x3668, 0x80); + os04a10_write_register(ViPipe, 0x366c, 0x00); + os04a10_write_register(ViPipe, 0x366d, 0x00); + os04a10_write_register(ViPipe, 0x366e, 0x00); + os04a10_write_register(ViPipe, 0x366f, 0x00); + os04a10_write_register(ViPipe, 0x3671, 0x08); + os04a10_write_register(ViPipe, 0x3673, 0x2a); + os04a10_write_register(ViPipe, 0x3681, 0x80); + os04a10_write_register(ViPipe, 0x3700, 0x2d); + os04a10_write_register(ViPipe, 0x3701, 0x22); + os04a10_write_register(ViPipe, 0x3702, 0x25); + os04a10_write_register(ViPipe, 0x3703, 0x28); + os04a10_write_register(ViPipe, 0x3705, 0x00); + os04a10_write_register(ViPipe, 0x3706, 0xf0); + os04a10_write_register(ViPipe, 0x3707, 0x0a); + os04a10_write_register(ViPipe, 0x3708, 0x36); + os04a10_write_register(ViPipe, 0x3709, 0x57); + os04a10_write_register(ViPipe, 0x370a, 0x03); + os04a10_write_register(ViPipe, 0x370b, 0x15); + os04a10_write_register(ViPipe, 0x3714, 0x01); + os04a10_write_register(ViPipe, 0x3719, 0x24); + os04a10_write_register(ViPipe, 0x371b, 0x1f); + os04a10_write_register(ViPipe, 0x371c, 0x00); + os04a10_write_register(ViPipe, 0x371d, 0x08); + os04a10_write_register(ViPipe, 0x373f, 0x63); + os04a10_write_register(ViPipe, 0x3740, 0x63); + os04a10_write_register(ViPipe, 0x3741, 0x63); + os04a10_write_register(ViPipe, 0x3742, 0x63); + os04a10_write_register(ViPipe, 0x3743, 0x01); + os04a10_write_register(ViPipe, 0x3756, 0xe7); + os04a10_write_register(ViPipe, 0x3757, 0xe7); + os04a10_write_register(ViPipe, 0x3762, 0x1c); + os04a10_write_register(ViPipe, 0x376c, 0x10); + os04a10_write_register(ViPipe, 0x3776, 0x05); + os04a10_write_register(ViPipe, 0x3777, 0x22); + os04a10_write_register(ViPipe, 0x3779, 0x60); + os04a10_write_register(ViPipe, 0x377c, 0x48); + os04a10_write_register(ViPipe, 0x3784, 0x06); + os04a10_write_register(ViPipe, 0x3785, 0x0a); + os04a10_write_register(ViPipe, 0x3790, 0x10); + os04a10_write_register(ViPipe, 0x3793, 0x04); + os04a10_write_register(ViPipe, 0x3794, 0x07); + os04a10_write_register(ViPipe, 0x3796, 0x00); + os04a10_write_register(ViPipe, 0x3797, 0x02); + os04a10_write_register(ViPipe, 0x379c, 0x4d); + os04a10_write_register(ViPipe, 0x37a1, 0x80); + os04a10_write_register(ViPipe, 0x37bb, 0x88); + os04a10_write_register(ViPipe, 0x37be, 0x48); + os04a10_write_register(ViPipe, 0x37bf, 0x01); + os04a10_write_register(ViPipe, 0x37c0, 0x01); + os04a10_write_register(ViPipe, 0x37c4, 0x72); + os04a10_write_register(ViPipe, 0x37c5, 0x72); + os04a10_write_register(ViPipe, 0x37c6, 0x72); + os04a10_write_register(ViPipe, 0x37ca, 0x21); + os04a10_write_register(ViPipe, 0x37cc, 0x15); + os04a10_write_register(ViPipe, 0x37cd, 0x90); + os04a10_write_register(ViPipe, 0x37cf, 0x02); + os04a10_write_register(ViPipe, 0x37d0, 0x00); + os04a10_write_register(ViPipe, 0x37d1, 0xf0); + os04a10_write_register(ViPipe, 0x37d2, 0x03); + os04a10_write_register(ViPipe, 0x37d3, 0x15); + os04a10_write_register(ViPipe, 0x37d4, 0x01); + os04a10_write_register(ViPipe, 0x37d5, 0x00); + os04a10_write_register(ViPipe, 0x37d6, 0x03); + os04a10_write_register(ViPipe, 0x37d7, 0x15); + os04a10_write_register(ViPipe, 0x37d8, 0x01); + os04a10_write_register(ViPipe, 0x37dc, 0x00); + os04a10_write_register(ViPipe, 0x37dd, 0x00); + os04a10_write_register(ViPipe, 0x37da, 0x00); + os04a10_write_register(ViPipe, 0x37db, 0x00); + os04a10_write_register(ViPipe, 0x3800, 0x00); + os04a10_write_register(ViPipe, 0x3801, 0x00); + os04a10_write_register(ViPipe, 0x3802, 0x00); + os04a10_write_register(ViPipe, 0x3803, 0x00); + os04a10_write_register(ViPipe, 0x3804, 0x0a); + os04a10_write_register(ViPipe, 0x3805, 0x8f); + os04a10_write_register(ViPipe, 0x3806, 0x05); + os04a10_write_register(ViPipe, 0x3807, 0xff); + os04a10_write_register(ViPipe, 0x3808, 0x0a); + os04a10_write_register(ViPipe, 0x3809, 0x80); + os04a10_write_register(ViPipe, 0x380a, 0x05); + os04a10_write_register(ViPipe, 0x380b, 0xf0); + os04a10_write_register(ViPipe, 0x380c, 0x05); + os04a10_write_register(ViPipe, 0x380d, 0xcc); + os04a10_write_register(ViPipe, 0x380e, 0x06); + os04a10_write_register(ViPipe, 0x380f, 0x58); + os04a10_write_register(ViPipe, 0x3811, 0x08); + os04a10_write_register(ViPipe, 0x3813, 0x08); + os04a10_write_register(ViPipe, 0x3814, 0x01); + os04a10_write_register(ViPipe, 0x3815, 0x01); + os04a10_write_register(ViPipe, 0x3816, 0x01); + os04a10_write_register(ViPipe, 0x3817, 0x01); + os04a10_write_register(ViPipe, 0x381c, 0x00); + os04a10_write_register(ViPipe, 0x3820, 0x02); + os04a10_write_register(ViPipe, 0x3821, 0x00); + os04a10_write_register(ViPipe, 0x3822, 0x14); + os04a10_write_register(ViPipe, 0x3823, 0x18); + os04a10_write_register(ViPipe, 0x3826, 0x00); + os04a10_write_register(ViPipe, 0x3827, 0x00); + os04a10_write_register(ViPipe, 0x3833, 0x40); + os04a10_write_register(ViPipe, 0x384c, 0x05); + os04a10_write_register(ViPipe, 0x384d, 0xc4); + os04a10_write_register(ViPipe, 0x3858, 0x3c); + os04a10_write_register(ViPipe, 0x3865, 0x02); + os04a10_write_register(ViPipe, 0x3866, 0x00); + os04a10_write_register(ViPipe, 0x3867, 0x00); + os04a10_write_register(ViPipe, 0x3868, 0x02); + os04a10_write_register(ViPipe, 0x3900, 0x13); + os04a10_write_register(ViPipe, 0x3940, 0x13); + os04a10_write_register(ViPipe, 0x3980, 0x13); + os04a10_write_register(ViPipe, 0x3c01, 0x11); + os04a10_write_register(ViPipe, 0x3c05, 0x00); + os04a10_write_register(ViPipe, 0x3c0f, 0x1c); + os04a10_write_register(ViPipe, 0x3c12, 0x0d); + os04a10_write_register(ViPipe, 0x3c19, 0x00); + os04a10_write_register(ViPipe, 0x3c21, 0x00); + os04a10_write_register(ViPipe, 0x3c3a, 0x10); + os04a10_write_register(ViPipe, 0x3c3b, 0x18); + os04a10_write_register(ViPipe, 0x3c3d, 0xc6); + os04a10_write_register(ViPipe, 0x3c55, 0x08); + os04a10_write_register(ViPipe, 0x3c5a, 0xe5); + os04a10_write_register(ViPipe, 0x3c5d, 0xcf); + os04a10_write_register(ViPipe, 0x3c5e, 0xcf); + os04a10_write_register(ViPipe, 0x3d8c, 0x70); + os04a10_write_register(ViPipe, 0x3d8d, 0x10); + os04a10_write_register(ViPipe, 0x4000, 0xf9); + os04a10_write_register(ViPipe, 0x4001, 0x2f); + os04a10_write_register(ViPipe, 0x4004, 0x00); + os04a10_write_register(ViPipe, 0x4005, 0x80); + os04a10_write_register(ViPipe, 0x4008, 0x02); + os04a10_write_register(ViPipe, 0x4009, 0x11); + os04a10_write_register(ViPipe, 0x400a, 0x03); + os04a10_write_register(ViPipe, 0x400b, 0x27); + os04a10_write_register(ViPipe, 0x400e, 0x40); + os04a10_write_register(ViPipe, 0x402e, 0x00); + os04a10_write_register(ViPipe, 0x402f, 0x80); + os04a10_write_register(ViPipe, 0x4030, 0x00); + os04a10_write_register(ViPipe, 0x4031, 0x80); + os04a10_write_register(ViPipe, 0x4032, 0x9f); + os04a10_write_register(ViPipe, 0x4033, 0x80); + os04a10_write_register(ViPipe, 0x4050, 0x00); + os04a10_write_register(ViPipe, 0x4051, 0x07); + os04a10_write_register(ViPipe, 0x4011, 0xbb); + os04a10_write_register(ViPipe, 0x410f, 0x01); + os04a10_write_register(ViPipe, 0x4288, 0xcf); + os04a10_write_register(ViPipe, 0x4289, 0x00); + os04a10_write_register(ViPipe, 0x428a, 0x46); + os04a10_write_register(ViPipe, 0x430b, 0xff); + os04a10_write_register(ViPipe, 0x430c, 0xff); + os04a10_write_register(ViPipe, 0x430d, 0x00); + os04a10_write_register(ViPipe, 0x430e, 0x00); + os04a10_write_register(ViPipe, 0x4314, 0x04); + os04a10_write_register(ViPipe, 0x4500, 0x18); + os04a10_write_register(ViPipe, 0x4501, 0x18); + os04a10_write_register(ViPipe, 0x4503, 0x10); + os04a10_write_register(ViPipe, 0x4504, 0x00); + os04a10_write_register(ViPipe, 0x4506, 0x32); + os04a10_write_register(ViPipe, 0x4507, 0x02); + os04a10_write_register(ViPipe, 0x4601, 0x30); + os04a10_write_register(ViPipe, 0x4603, 0x00); + os04a10_write_register(ViPipe, 0x460a, 0x50); + os04a10_write_register(ViPipe, 0x460c, 0x60); + os04a10_write_register(ViPipe, 0x4640, 0x62); + os04a10_write_register(ViPipe, 0x4646, 0xaa); + os04a10_write_register(ViPipe, 0x4647, 0x55); + os04a10_write_register(ViPipe, 0x4648, 0x99); + os04a10_write_register(ViPipe, 0x4649, 0x66); + os04a10_write_register(ViPipe, 0x464d, 0x00); + os04a10_write_register(ViPipe, 0x4654, 0x11); + os04a10_write_register(ViPipe, 0x4655, 0x22); + os04a10_write_register(ViPipe, 0x4800, 0x44); + os04a10_write_register(ViPipe, 0x480e, 0x00); + os04a10_write_register(ViPipe, 0x4810, 0xff); + os04a10_write_register(ViPipe, 0x4811, 0xff); + os04a10_write_register(ViPipe, 0x4813, 0x00); + os04a10_write_register(ViPipe, 0x481f, 0x30); + os04a10_write_register(ViPipe, 0x4837, 0x14); + os04a10_write_register(ViPipe, 0x484b, 0x27); + os04a10_write_register(ViPipe, 0x4d00, 0x4d); + os04a10_write_register(ViPipe, 0x4d01, 0x9d); + os04a10_write_register(ViPipe, 0x4d02, 0xb9); + os04a10_write_register(ViPipe, 0x4d03, 0x2e); + os04a10_write_register(ViPipe, 0x4d04, 0x4a); + os04a10_write_register(ViPipe, 0x4d05, 0x3d); + os04a10_write_register(ViPipe, 0x4d09, 0x4f); + os04a10_write_register(ViPipe, 0x5000, 0x7f); + os04a10_write_register(ViPipe, 0x5001, 0x0d); + os04a10_write_register(ViPipe, 0x5080, 0x00); + os04a10_write_register(ViPipe, 0x50c0, 0x00); + os04a10_write_register(ViPipe, 0x5100, 0x00); + os04a10_write_register(ViPipe, 0x5200, 0x00); + os04a10_write_register(ViPipe, 0x5201, 0x00); + os04a10_write_register(ViPipe, 0x5202, 0x03); + os04a10_write_register(ViPipe, 0x5203, 0xff); + os04a10_write_register(ViPipe, 0x5780, 0x53); + os04a10_write_register(ViPipe, 0x5782, 0x60); + os04a10_write_register(ViPipe, 0x5783, 0xf0); + os04a10_write_register(ViPipe, 0x5786, 0x01); + os04a10_write_register(ViPipe, 0x5788, 0x60); + os04a10_write_register(ViPipe, 0x5789, 0xf0); + os04a10_write_register(ViPipe, 0x5792, 0x11); + os04a10_write_register(ViPipe, 0x5793, 0x33); + os04a10_write_register(ViPipe, 0x5857, 0xff); + os04a10_write_register(ViPipe, 0x5858, 0xff); + os04a10_write_register(ViPipe, 0x5859, 0xff); + os04a10_write_register(ViPipe, 0x58d7, 0xff); + os04a10_write_register(ViPipe, 0x58d8, 0xff); + os04a10_write_register(ViPipe, 0x58d9, 0xff); + + os04a10_default_reg_init(ViPipe); + os04a10_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===OS04A10 1520P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void os04a10_wdr_1520p30_2to1_init(VI_PIPE ViPipe) +{ + os04a10_write_register(ViPipe, 0x0103, 0x01); + os04a10_write_register(ViPipe, 0x0109, 0x01); + os04a10_write_register(ViPipe, 0x0104, 0x02); + os04a10_write_register(ViPipe, 0x0102, 0x00); + os04a10_write_register(ViPipe, 0x0305, 0x3c); + os04a10_write_register(ViPipe, 0x0306, 0x00); + os04a10_write_register(ViPipe, 0x0307, 0x00); + os04a10_write_register(ViPipe, 0x0308, 0x04); + os04a10_write_register(ViPipe, 0x030a, 0x01); + os04a10_write_register(ViPipe, 0x0317, 0x09); + os04a10_write_register(ViPipe, 0x0322, 0x01); + os04a10_write_register(ViPipe, 0x0323, 0x02); + os04a10_write_register(ViPipe, 0x0324, 0x00); + os04a10_write_register(ViPipe, 0x0325, 0x90); + os04a10_write_register(ViPipe, 0x0327, 0x05); + os04a10_write_register(ViPipe, 0x0329, 0x02); + os04a10_write_register(ViPipe, 0x032c, 0x02); + os04a10_write_register(ViPipe, 0x032d, 0x02); + os04a10_write_register(ViPipe, 0x032e, 0x02); + os04a10_write_register(ViPipe, 0x300f, 0x11); + os04a10_write_register(ViPipe, 0x3012, 0x41); + os04a10_write_register(ViPipe, 0x3026, 0x10); + os04a10_write_register(ViPipe, 0x3027, 0x08); + os04a10_write_register(ViPipe, 0x302d, 0x24); + os04a10_write_register(ViPipe, 0x3104, 0x01); + os04a10_write_register(ViPipe, 0x3106, 0x11); + os04a10_write_register(ViPipe, 0x3400, 0x00); + os04a10_write_register(ViPipe, 0x3408, 0x05); + os04a10_write_register(ViPipe, 0x340c, 0x0c); + os04a10_write_register(ViPipe, 0x340d, 0xb0); + os04a10_write_register(ViPipe, 0x3425, 0x51); + os04a10_write_register(ViPipe, 0x3426, 0x10); + os04a10_write_register(ViPipe, 0x3427, 0x14); + os04a10_write_register(ViPipe, 0x3428, 0x10); + os04a10_write_register(ViPipe, 0x3429, 0x10); + os04a10_write_register(ViPipe, 0x342a, 0x10); + os04a10_write_register(ViPipe, 0x342b, 0x04); + os04a10_write_register(ViPipe, 0x3501, 0x02); + os04a10_write_register(ViPipe, 0x3504, 0x08); + os04a10_write_register(ViPipe, 0x3508, 0x01); + os04a10_write_register(ViPipe, 0x3509, 0x00); + os04a10_write_register(ViPipe, 0x350a, 0x01); + os04a10_write_register(ViPipe, 0x3544, 0x08); + os04a10_write_register(ViPipe, 0x3548, 0x01); + os04a10_write_register(ViPipe, 0x3549, 0x00); + os04a10_write_register(ViPipe, 0x3584, 0x08); + os04a10_write_register(ViPipe, 0x3588, 0x01); + os04a10_write_register(ViPipe, 0x3589, 0x00); + os04a10_write_register(ViPipe, 0x3601, 0x70); + os04a10_write_register(ViPipe, 0x3604, 0xe3); + os04a10_write_register(ViPipe, 0x3605, 0x7f); + os04a10_write_register(ViPipe, 0x3606, 0x80); + os04a10_write_register(ViPipe, 0x3608, 0xa8); + os04a10_write_register(ViPipe, 0x360a, 0xd0); + os04a10_write_register(ViPipe, 0x360b, 0x08); + os04a10_write_register(ViPipe, 0x360e, 0xc8); + os04a10_write_register(ViPipe, 0x360f, 0x66); + os04a10_write_register(ViPipe, 0x3610, 0x89); + os04a10_write_register(ViPipe, 0x3611, 0x8a); + os04a10_write_register(ViPipe, 0x3612, 0x4e); + os04a10_write_register(ViPipe, 0x3613, 0xbd); + os04a10_write_register(ViPipe, 0x3614, 0x9b); + os04a10_write_register(ViPipe, 0x362a, 0x0e); + os04a10_write_register(ViPipe, 0x362b, 0x0e); + os04a10_write_register(ViPipe, 0x362c, 0x0e); + os04a10_write_register(ViPipe, 0x362d, 0x0e); + os04a10_write_register(ViPipe, 0x362e, 0x1a); + os04a10_write_register(ViPipe, 0x362f, 0x34); + os04a10_write_register(ViPipe, 0x3630, 0x67); + os04a10_write_register(ViPipe, 0x3631, 0x7f); + os04a10_write_register(ViPipe, 0x3638, 0x00); + os04a10_write_register(ViPipe, 0x3643, 0x00); + os04a10_write_register(ViPipe, 0x3644, 0x00); + os04a10_write_register(ViPipe, 0x3645, 0x00); + os04a10_write_register(ViPipe, 0x3646, 0x00); + os04a10_write_register(ViPipe, 0x3647, 0x00); + os04a10_write_register(ViPipe, 0x3648, 0x00); + os04a10_write_register(ViPipe, 0x3649, 0x00); + os04a10_write_register(ViPipe, 0x364a, 0x04); + os04a10_write_register(ViPipe, 0x364c, 0x0e); + os04a10_write_register(ViPipe, 0x364d, 0x0e); + os04a10_write_register(ViPipe, 0x364e, 0x0e); + os04a10_write_register(ViPipe, 0x364f, 0x0e); + os04a10_write_register(ViPipe, 0x3650, 0xff); + os04a10_write_register(ViPipe, 0x3651, 0xff); + os04a10_write_register(ViPipe, 0x365a, 0x00); + os04a10_write_register(ViPipe, 0x365b, 0x00); + os04a10_write_register(ViPipe, 0x365c, 0x00); + os04a10_write_register(ViPipe, 0x365d, 0x00); + os04a10_write_register(ViPipe, 0x3661, 0x07); + os04a10_write_register(ViPipe, 0x3662, 0x02); + os04a10_write_register(ViPipe, 0x3663, 0x20); + os04a10_write_register(ViPipe, 0x3665, 0x12); + os04a10_write_register(ViPipe, 0x3667, 0x54); + os04a10_write_register(ViPipe, 0x3668, 0x80); + os04a10_write_register(ViPipe, 0x366c, 0x00); + os04a10_write_register(ViPipe, 0x366d, 0x00); + os04a10_write_register(ViPipe, 0x366e, 0x00); + os04a10_write_register(ViPipe, 0x366f, 0x00); + os04a10_write_register(ViPipe, 0x3671, 0x09); + os04a10_write_register(ViPipe, 0x3673, 0x2a); + os04a10_write_register(ViPipe, 0x3681, 0x80); + os04a10_write_register(ViPipe, 0x3700, 0x2d); + os04a10_write_register(ViPipe, 0x3701, 0x22); + os04a10_write_register(ViPipe, 0x3702, 0x25); + os04a10_write_register(ViPipe, 0x3703, 0x20); + os04a10_write_register(ViPipe, 0x3705, 0x00); + os04a10_write_register(ViPipe, 0x3706, 0x72); + os04a10_write_register(ViPipe, 0x3707, 0x0a); + os04a10_write_register(ViPipe, 0x3708, 0x36); + os04a10_write_register(ViPipe, 0x3709, 0x57); + os04a10_write_register(ViPipe, 0x370a, 0x01); + os04a10_write_register(ViPipe, 0x370b, 0x14); + os04a10_write_register(ViPipe, 0x3714, 0x01); + os04a10_write_register(ViPipe, 0x3719, 0x1f); + os04a10_write_register(ViPipe, 0x371b, 0x16); + os04a10_write_register(ViPipe, 0x371c, 0x00); + os04a10_write_register(ViPipe, 0x371d, 0x08); + os04a10_write_register(ViPipe, 0x373f, 0x63); + os04a10_write_register(ViPipe, 0x3740, 0x63); + os04a10_write_register(ViPipe, 0x3741, 0x63); + os04a10_write_register(ViPipe, 0x3742, 0x63); + os04a10_write_register(ViPipe, 0x3743, 0x01); + os04a10_write_register(ViPipe, 0x3756, 0x9d); + os04a10_write_register(ViPipe, 0x3757, 0x9d); + os04a10_write_register(ViPipe, 0x3762, 0x1c); + os04a10_write_register(ViPipe, 0x376c, 0x34); + os04a10_write_register(ViPipe, 0x3776, 0x05); + os04a10_write_register(ViPipe, 0x3777, 0x22); + os04a10_write_register(ViPipe, 0x3779, 0x60); + os04a10_write_register(ViPipe, 0x377c, 0x48); + os04a10_write_register(ViPipe, 0x3784, 0x06); + os04a10_write_register(ViPipe, 0x3785, 0x0a); + os04a10_write_register(ViPipe, 0x3790, 0x10); + os04a10_write_register(ViPipe, 0x3793, 0x04); + os04a10_write_register(ViPipe, 0x3794, 0x07); + os04a10_write_register(ViPipe, 0x3796, 0x00); + os04a10_write_register(ViPipe, 0x3797, 0x02); + os04a10_write_register(ViPipe, 0x379c, 0x4d); + os04a10_write_register(ViPipe, 0x37a1, 0x80); + os04a10_write_register(ViPipe, 0x37bb, 0x88); + os04a10_write_register(ViPipe, 0x37be, 0x48); + os04a10_write_register(ViPipe, 0x37bf, 0x01); + os04a10_write_register(ViPipe, 0x37c0, 0x01); + os04a10_write_register(ViPipe, 0x37c4, 0x72); + os04a10_write_register(ViPipe, 0x37c5, 0x72); + os04a10_write_register(ViPipe, 0x37c6, 0x72); + os04a10_write_register(ViPipe, 0x37ca, 0x21); + os04a10_write_register(ViPipe, 0x37cc, 0x13); + os04a10_write_register(ViPipe, 0x37cd, 0x90); + os04a10_write_register(ViPipe, 0x37cf, 0x02); + os04a10_write_register(ViPipe, 0x37d0, 0x00); + os04a10_write_register(ViPipe, 0x37d1, 0x72); + os04a10_write_register(ViPipe, 0x37d2, 0x01); + os04a10_write_register(ViPipe, 0x37d3, 0x14); + os04a10_write_register(ViPipe, 0x37d4, 0x00); + os04a10_write_register(ViPipe, 0x37d5, 0x6c); + os04a10_write_register(ViPipe, 0x37d6, 0x00); + os04a10_write_register(ViPipe, 0x37d7, 0xf7); + os04a10_write_register(ViPipe, 0x37d8, 0x01); + os04a10_write_register(ViPipe, 0x37dc, 0x00); + os04a10_write_register(ViPipe, 0x37dd, 0x00); + os04a10_write_register(ViPipe, 0x37da, 0x00); + os04a10_write_register(ViPipe, 0x37db, 0x00); + os04a10_write_register(ViPipe, 0x3800, 0x00); + os04a10_write_register(ViPipe, 0x3801, 0x00); + os04a10_write_register(ViPipe, 0x3802, 0x00); + os04a10_write_register(ViPipe, 0x3803, 0x00); + os04a10_write_register(ViPipe, 0x3804, 0x0a); + os04a10_write_register(ViPipe, 0x3805, 0x8f); + os04a10_write_register(ViPipe, 0x3806, 0x05); + os04a10_write_register(ViPipe, 0x3807, 0xff); + os04a10_write_register(ViPipe, 0x3808, 0x0a); + os04a10_write_register(ViPipe, 0x3809, 0x80); + os04a10_write_register(ViPipe, 0x380a, 0x05); + os04a10_write_register(ViPipe, 0x380b, 0xf0); + os04a10_write_register(ViPipe, 0x380c, 0x02); + os04a10_write_register(ViPipe, 0x380d, 0xdc); + os04a10_write_register(ViPipe, 0x380e, 0x06); + os04a10_write_register(ViPipe, 0x380f, 0x58); + os04a10_write_register(ViPipe, 0x3811, 0x08); + os04a10_write_register(ViPipe, 0x3813, 0x08); + os04a10_write_register(ViPipe, 0x3814, 0x01); + os04a10_write_register(ViPipe, 0x3815, 0x01); + os04a10_write_register(ViPipe, 0x3816, 0x01); + os04a10_write_register(ViPipe, 0x3817, 0x01); + os04a10_write_register(ViPipe, 0x381c, 0x08); + os04a10_write_register(ViPipe, 0x3820, 0x03); + os04a10_write_register(ViPipe, 0x3821, 0x00); + os04a10_write_register(ViPipe, 0x3822, 0x14); + os04a10_write_register(ViPipe, 0x3823, 0x18); + os04a10_write_register(ViPipe, 0x3826, 0x00); + os04a10_write_register(ViPipe, 0x3827, 0x00); + os04a10_write_register(ViPipe, 0x3833, 0x41); + os04a10_write_register(ViPipe, 0x384c, 0x02); + os04a10_write_register(ViPipe, 0x384d, 0xdc); + os04a10_write_register(ViPipe, 0x3858, 0x3c); + os04a10_write_register(ViPipe, 0x3865, 0x02); + os04a10_write_register(ViPipe, 0x3866, 0x00); + os04a10_write_register(ViPipe, 0x3867, 0x00); + os04a10_write_register(ViPipe, 0x3868, 0x02); + os04a10_write_register(ViPipe, 0x3900, 0x13); + os04a10_write_register(ViPipe, 0x3940, 0x13); + os04a10_write_register(ViPipe, 0x3980, 0x13); + os04a10_write_register(ViPipe, 0x3c01, 0x11); + os04a10_write_register(ViPipe, 0x3c05, 0x00); + os04a10_write_register(ViPipe, 0x3c0f, 0x1c); + os04a10_write_register(ViPipe, 0x3c12, 0x0d); + os04a10_write_register(ViPipe, 0x3c19, 0x00); + os04a10_write_register(ViPipe, 0x3c21, 0x00); + os04a10_write_register(ViPipe, 0x3c3a, 0x10); + os04a10_write_register(ViPipe, 0x3c3b, 0x18); + os04a10_write_register(ViPipe, 0x3c3d, 0xc6); + os04a10_write_register(ViPipe, 0x3c55, 0x08); + os04a10_write_register(ViPipe, 0x3c5a, 0x55); + os04a10_write_register(ViPipe, 0x3c5d, 0xcf); + os04a10_write_register(ViPipe, 0x3c5e, 0xcf); + os04a10_write_register(ViPipe, 0x3d8c, 0x70); + os04a10_write_register(ViPipe, 0x3d8d, 0x10); + os04a10_write_register(ViPipe, 0x4000, 0xf9); + os04a10_write_register(ViPipe, 0x4001, 0xef); + os04a10_write_register(ViPipe, 0x4004, 0x00); + os04a10_write_register(ViPipe, 0x4005, 0x40); + os04a10_write_register(ViPipe, 0x4008, 0x02); + os04a10_write_register(ViPipe, 0x4009, 0x11); + os04a10_write_register(ViPipe, 0x400a, 0x06); + os04a10_write_register(ViPipe, 0x400b, 0x40); + os04a10_write_register(ViPipe, 0x400e, 0x40); + os04a10_write_register(ViPipe, 0x402e, 0x00); + os04a10_write_register(ViPipe, 0x402f, 0x40); + os04a10_write_register(ViPipe, 0x4030, 0x00); + os04a10_write_register(ViPipe, 0x4031, 0x40); + os04a10_write_register(ViPipe, 0x4032, 0x0f); + os04a10_write_register(ViPipe, 0x4033, 0x80); + os04a10_write_register(ViPipe, 0x4050, 0x00); + os04a10_write_register(ViPipe, 0x4051, 0x07); + os04a10_write_register(ViPipe, 0x4011, 0xbb); + os04a10_write_register(ViPipe, 0x410f, 0x01); + os04a10_write_register(ViPipe, 0x4288, 0xce); + os04a10_write_register(ViPipe, 0x4289, 0x00); + os04a10_write_register(ViPipe, 0x428a, 0x46); + os04a10_write_register(ViPipe, 0x430b, 0x0f); + os04a10_write_register(ViPipe, 0x430c, 0xfc); + os04a10_write_register(ViPipe, 0x430d, 0x00); + os04a10_write_register(ViPipe, 0x430e, 0x00); + os04a10_write_register(ViPipe, 0x4314, 0x04); + os04a10_write_register(ViPipe, 0x4500, 0x18); + os04a10_write_register(ViPipe, 0x4501, 0x18); + os04a10_write_register(ViPipe, 0x4503, 0x10); + os04a10_write_register(ViPipe, 0x4504, 0x00); + os04a10_write_register(ViPipe, 0x4506, 0x32); + os04a10_write_register(ViPipe, 0x4507, 0x03); + os04a10_write_register(ViPipe, 0x4601, 0x30); + os04a10_write_register(ViPipe, 0x4603, 0x00); + os04a10_write_register(ViPipe, 0x460a, 0x50); + os04a10_write_register(ViPipe, 0x460c, 0x60); + os04a10_write_register(ViPipe, 0x4640, 0x62); + os04a10_write_register(ViPipe, 0x4646, 0xaa); + os04a10_write_register(ViPipe, 0x4647, 0x55); + os04a10_write_register(ViPipe, 0x4648, 0x99); + os04a10_write_register(ViPipe, 0x4649, 0x66); + os04a10_write_register(ViPipe, 0x464d, 0x00); + os04a10_write_register(ViPipe, 0x4654, 0x11); + os04a10_write_register(ViPipe, 0x4655, 0x22); + os04a10_write_register(ViPipe, 0x4800, 0x44); + os04a10_write_register(ViPipe, 0x480e, 0x04); + os04a10_write_register(ViPipe, 0x4810, 0xff); + os04a10_write_register(ViPipe, 0x4811, 0xff); + os04a10_write_register(ViPipe, 0x4813, 0x84); + os04a10_write_register(ViPipe, 0x481f, 0x30); + os04a10_write_register(ViPipe, 0x4837, 0x0e); + os04a10_write_register(ViPipe, 0x484b, 0x67); + os04a10_write_register(ViPipe, 0x4d00, 0x4d); + os04a10_write_register(ViPipe, 0x4d01, 0x9d); + os04a10_write_register(ViPipe, 0x4d02, 0xb9); + os04a10_write_register(ViPipe, 0x4d03, 0x2e); + os04a10_write_register(ViPipe, 0x4d04, 0x4a); + os04a10_write_register(ViPipe, 0x4d05, 0x3d); + os04a10_write_register(ViPipe, 0x4d09, 0x4f); + os04a10_write_register(ViPipe, 0x5000, 0x1f); + os04a10_write_register(ViPipe, 0x5001, 0x0c); + os04a10_write_register(ViPipe, 0x5080, 0x00); + os04a10_write_register(ViPipe, 0x50c0, 0x00); + os04a10_write_register(ViPipe, 0x5100, 0x00); + os04a10_write_register(ViPipe, 0x5200, 0x00); + os04a10_write_register(ViPipe, 0x5201, 0x00); + os04a10_write_register(ViPipe, 0x5202, 0x03); + os04a10_write_register(ViPipe, 0x5203, 0xff); + os04a10_write_register(ViPipe, 0x5780, 0x53); + os04a10_write_register(ViPipe, 0x5782, 0x18); + os04a10_write_register(ViPipe, 0x5783, 0x3c); + os04a10_write_register(ViPipe, 0x5786, 0x01); + os04a10_write_register(ViPipe, 0x5788, 0x18); + os04a10_write_register(ViPipe, 0x5789, 0x3c); + os04a10_write_register(ViPipe, 0x5792, 0x11); + os04a10_write_register(ViPipe, 0x5793, 0x33); + os04a10_write_register(ViPipe, 0x5857, 0xff); + os04a10_write_register(ViPipe, 0x5858, 0xff); + os04a10_write_register(ViPipe, 0x5859, 0xff); + os04a10_write_register(ViPipe, 0x58d7, 0xff); + os04a10_write_register(ViPipe, 0x58d8, 0xff); + os04a10_write_register(ViPipe, 0x58d9, 0xff); + + os04a10_default_reg_init(ViPipe); + os04a10_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===OS04A10 1520P 30fps 10bit 2to1 WDR Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_os04c10/Makefile b/middleware/v2/component/isp/sensor/cv181x/ov_os04c10/Makefile new file mode 100644 index 000000000..f9ec29965 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_os04c10/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_os04c10.a +TARGET_SO = $(MW_LIB)/libsns_os04c10.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_os04c10/os04c10_cmos.c b/middleware/v2/component/isp/sensor/cv181x/ov_os04c10/os04c10_cmos.c new file mode 100644 index 000000000..06321a7fa --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_os04c10/os04c10_cmos.c @@ -0,0 +1,1133 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "os04c10_cmos_ex.h" +#include "os04c10_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define OS04C10_ID 0x530443 +#define OS04C10_I2C_ADDR_1 0x10 +#define OS04C10_I2C_ADDR_2 0x36 +#define OS04C10_I2C_ADDR_IS_VALID(addr) ((addr) == OS04C10_I2C_ADDR_1 || (addr) == OS04C10_I2C_ADDR_2) +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastOs04c10[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define OS04C10_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastOs04c10[dev]) +#define OS04C10_SENSOR_SET_CTX(dev, pstCtx) (g_pastOs04c10[dev] = pstCtx) +#define OS04C10_SENSOR_RESET_CTX(dev) (g_pastOs04c10[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunOs04c10_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Os04c10_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Os04c10_UseHwSync[VI_MAX_PIPE_NUM] = {0}; + +OS04C10_STATE_S g_astOs04c10_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeOs04c10_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Os04c10 Lines Range*****/ +#define OS04C10_FULL_LINES_MAX (0xFFFF) +#define OS04C10_FULL_LINES_MAX_2TO1_WDR (0xFFFF) + +/*****Os04c10 Register Address*****/ +#define OS04C10_HOLD_3208 0x3208 +#define OS04C10_HOLD_320D 0x320D +#define OS04C10_EXP1_ADDR 0x3501 +#define OS04C10_EXP2_ADDR 0x3511 +#define OS04C10_AGAIN1_ADDR 0x3508 +#define OS04C10_DGAIN1_ADDR 0x350A +#define OS04C10_AGAIN2_ADDR 0x350C +#define OS04C10_DGAIN2_ADDR 0x350E +#define OS04C10_L2S_ADDR 0x3798 +#define OS04C10_VTS_ADDR 0x380E +#define OS04C10_GGAIN_ADDR 0x5142 +#define OS04C10_TABLE_END 0xffff + +#define OS04C10_RES_IS_1520P(w, h) ((w) == 2688 && (h) == 1520) +#define OS04C10_RES_IS_1440P(w, h) ((w) == 2560 && (h) == 1440) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const OS04C10_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astOs04c10_mode[pstSnsState->u8ImgMode]; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = OS04C10_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + /* OV sensor cannot update new setting before the old setting takes effect */ + pstAeSnsDft->u8AERunInterval = 4; + + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + } + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astOs04c10_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astOs04c10_mode[pstSnsState->u8ImgMode].f32MinFps; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OS04C10_FULL_LINES_MAX) ? OS04C10_FULL_LINES_MAX : u32VMAX; + + pstSnsRegsInfo->astI2cData[LINEAR_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_1].u32Data = (u32VMAX & 0xFF); + } else { + CVI_U32 isp_res = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32IspResTime; + CVI_U32 l2s_offset = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32L2S_offset; + CVI_U32 margin = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32HdrMargin; + CVI_U32 vblank = 0; + + /* In auto mode, + * L2S_distane = Sexp_max + L2S offset + * Vblank = Vtotal - Vactive - margin + * if Vblank > isp_res + * Sexp_max + L2S offset <= Vblank - isp_res + * else if Vblank < isp_res + * Sexp_max + L2S offset = Vblank + */ + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OS04C10_FULL_LINES_MAX_2TO1_WDR) ? + OS04C10_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + + vblank = u32VMAX - g_astOs04c10_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height + - margin; + if (vblank > isp_res) + vblank -= isp_res; + else + CVI_TRACE_SNS(CVI_DBG_WARN, "cannot reserve 1ms for isp delay %d\n", vblank); + + g_astOs04c10_State[ViPipe].u32Sexp_MAX = vblank - l2s_offset; + pstSnsRegsInfo->astI2cData[WDR2_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_VTS_1].u32Data = (u32VMAX & 0xFF); + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32IntTime[0]; + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = u32IntTime[1]; + + pstSnsRegsInfo->astI2cData[WDR2_EXP1_0].u32Data = ((pstSnsState->au32WDRIntTime[1] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_EXP1_1].u32Data = (pstSnsState->au32WDRIntTime[1] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_EXP2_0].u32Data = ((pstSnsState->au32WDRIntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_EXP2_1].u32Data = (pstSnsState->au32WDRIntTime[0] & 0xFF); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + + //When the expLine is very small, the exposure time of R G B has a great error + //use sensor internal Ggain to fix the gap + //sync patch from ov fae: clyde.liu + CVI_FLOAT ratio1 = (CVI_FLOAT)((u32IntTime[1] + 0.25) * (u32IntTime[0] + 0.75)); + CVI_FLOAT ratio2 = (CVI_FLOAT)((u32IntTime[1] + 0.75) * (u32IntTime[0] + 0.25)); + CVI_FLOAT ratio = ratio1 / ratio2; + CVI_U16 fixGGain = (CVI_U16)(ratio * 1024); + + pstSnsRegsInfo->astI2cData[WDR2_GGAIN_0].u32Data = (fixGGain & 0xFF00) >> 8; + pstSnsRegsInfo->astI2cData[WDR2_GGAIN_1].u32Data = (fixGGain & 0xFF); + + } else { + pstSnsRegsInfo->astI2cData[LINEAR_EXP_0].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_1].u32Data = (u32IntTime[0] & 0xFF); + } + + return CVI_SUCCESS; + +} + +/* + * GainReg {0x3508, 0x3509} Real Gain + * 0x0080~0x00FF INT(GainReg/8)/16 + * 0x0100~0x01FF INT(GainReg/16)/8 + * 0x0200~0x03FF INT(GainReg/32)/4 + * 0x0400~0x07FF INT(GainReg/64)/2 + */ + +static CVI_U32 gain_table[64] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[63]) { + *pu32AgainLin = gain_table[63]; + *pu32AgainDb = (63 - 48) * 64 + 1024; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + i--; + if (i < 16) + *pu32AgainDb = i * 8 + 128; + else if (i < 32) + *pu32AgainDb = (i - 16) * 16 + 256; + else if (i < 48) + *pu32AgainDb = (i - 32) * 32 + 512; + else + *pu32AgainDb = (i - 48) * 64 + 1024; + + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin <= 1024) { + *pu32DgainLin = 1024; + } else if (*pu32DgainLin > 16383) { + *pu32DgainLin = 16383; + } + *pu32DgainDb = *pu32DgainLin; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0].u32Data = ((u32Again & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_1].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0].u32Data = ((u32Dgain & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1].u32Data = (u32Dgain & 0xFF); + } else { + /* DOL mode */ + u32Again = pu32Again[1]; + u32Dgain = pu32Dgain[1]; + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_0].u32Data = ((u32Again & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_1].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_0].u32Data = ((u32Dgain & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_1].u32Data = (u32Dgain & 0xFF); + + if (g_au16Os04c10_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[1]; + u32Dgain = pu32Dgain[1]; + } else if (g_au16Os04c10_GainMode[ViPipe] == SNS_GAIN_MODE_WDR_2F) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + } else { + return CVI_SUCCESS; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_0].u32Data = ((u32Again & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_1].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_0].u32Data = ((u32Dgain & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_1].u32Data = (u32Dgain & 0xFF); + + } + + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = 2; + /* + * Max Lexp = VTS - 8 + * Max Sexp = VTS - Lexp - 12 + * Long exp + Short exp < VTS - 12 + */ + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 12 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 12) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + + u32IntTimeMaxTmp = (g_astOs04c10_State[ViPipe].u32Sexp_MAX < u32IntTimeMaxTmp) ? + g_astOs04c10_State[ViPipe].u32Sexp_MAX : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + syslog(LOG_DEBUG, "Max inttime0 = %u\n", u32IntTimeMaxTmp); + + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio is too large!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + else + memcpy(pstBlc, + &g_stIspBlcCalibratio10Bit, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const OS04C10_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astOs04c10_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == OS04C10_MODE_2688X1520P30_WDR) + pstSnsState->u8ImgMode = OS04C10_MODE_2688X1520P30; + else if (pstSnsState->u8ImgMode == OS04C10_MODE_2560X1440P30_WDR) + pstSnsState->u8ImgMode = OS04C10_MODE_2560X1440P30; + else { + } + + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == OS04C10_MODE_2688X1520P30) { + pstSnsState->u8ImgMode = OS04C10_MODE_2688X1520P30_WDR; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1520p mode(60fps->30fps)\n"); + } else if (pstSnsState->u8ImgMode == OS04C10_MODE_2560X1440P30) { + pstSnsState->u8ImgMode = OS04C10_MODE_2560X1440P30_WDR; + } else { + } + + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32VtsDef; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunOs04c10_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = os04c10_i2c_addr; + pstI2c_data[i].u32AddrByteNum = os04c10_addr_byte; + pstI2c_data[i].u32DataByteNum = os04c10_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[WDR2_HOLD_START].u32RegAddr = OS04C10_HOLD_3208; + pstI2c_data[WDR2_HOLD_START].u32Data = 0x00; + pstI2c_data[WDR2_EXP1_0].u32RegAddr = OS04C10_EXP1_ADDR; + pstI2c_data[WDR2_EXP1_1].u32RegAddr = OS04C10_EXP1_ADDR + 1; + pstI2c_data[WDR2_EXP2_0].u32RegAddr = OS04C10_EXP2_ADDR; + pstI2c_data[WDR2_EXP2_1].u32RegAddr = OS04C10_EXP2_ADDR + 1; + pstI2c_data[WDR2_AGAIN1_0].u32RegAddr = OS04C10_AGAIN1_ADDR; + pstI2c_data[WDR2_AGAIN1_1].u32RegAddr = OS04C10_AGAIN1_ADDR + 1; + pstI2c_data[WDR2_AGAIN2_0].u32RegAddr = OS04C10_AGAIN2_ADDR; + pstI2c_data[WDR2_AGAIN2_1].u32RegAddr = OS04C10_AGAIN2_ADDR + 1; + pstI2c_data[WDR2_DGAIN1_0].u32RegAddr = OS04C10_DGAIN1_ADDR; + pstI2c_data[WDR2_DGAIN1_1].u32RegAddr = OS04C10_DGAIN1_ADDR + 1; + pstI2c_data[WDR2_DGAIN2_0].u32RegAddr = OS04C10_DGAIN2_ADDR; + pstI2c_data[WDR2_DGAIN2_1].u32RegAddr = OS04C10_DGAIN2_ADDR + 1; + pstI2c_data[WDR2_VTS_0].u32RegAddr = OS04C10_VTS_ADDR; + pstI2c_data[WDR2_VTS_1].u32RegAddr = OS04C10_VTS_ADDR + 1; + pstI2c_data[WDR2_HOLD_END].u32RegAddr = OS04C10_HOLD_3208; + pstI2c_data[WDR2_HOLD_END].u32Data = 0x10; + pstI2c_data[WDR2_LAUNCH_0].u32RegAddr = OS04C10_HOLD_320D; + pstI2c_data[WDR2_LAUNCH_0].u32Data = 0x00; + pstI2c_data[WDR2_LAUNCH_0].u8DelayFrmNum = 0; + pstI2c_data[WDR2_LAUNCH_1].u32RegAddr = OS04C10_HOLD_3208; + pstI2c_data[WDR2_LAUNCH_1].u32Data = 0xA0; + pstI2c_data[WDR2_LAUNCH_1].u8DelayFrmNum = 0; + pstI2c_data[WDR2_GGAIN_0].u32RegAddr = OS04C10_GGAIN_ADDR; + pstI2c_data[WDR2_GGAIN_1].u32RegAddr = OS04C10_GGAIN_ADDR + 1; + break; + default: + pstI2c_data[LINEAR_HOLD_START].u32RegAddr = OS04C10_HOLD_3208; + pstI2c_data[LINEAR_HOLD_START].u32Data = 0x00; + pstI2c_data[LINEAR_EXP_0].u32RegAddr = OS04C10_EXP1_ADDR; + pstI2c_data[LINEAR_EXP_1].u32RegAddr = OS04C10_EXP1_ADDR + 1; + pstI2c_data[LINEAR_AGAIN_0].u32RegAddr = OS04C10_AGAIN1_ADDR; + pstI2c_data[LINEAR_AGAIN_1].u32RegAddr = OS04C10_AGAIN1_ADDR + 1; + pstI2c_data[LINEAR_DGAIN_0].u32RegAddr = OS04C10_DGAIN1_ADDR; + pstI2c_data[LINEAR_DGAIN_1].u32RegAddr = OS04C10_DGAIN1_ADDR + 1; + pstI2c_data[LINEAR_VTS_0].u32RegAddr = OS04C10_VTS_ADDR; + pstI2c_data[LINEAR_VTS_1].u32RegAddr = OS04C10_VTS_ADDR + 1; + pstI2c_data[LINEAR_HOLD_END].u32RegAddr = OS04C10_HOLD_3208; + pstI2c_data[LINEAR_HOLD_END].u32Data = 0x10; + pstI2c_data[LINEAR_LAUNCH_0].u32RegAddr = OS04C10_HOLD_320D; + pstI2c_data[LINEAR_LAUNCH_0].u32Data = 0x00; + pstI2c_data[LINEAR_LAUNCH_0].u8DelayFrmNum = 0; + pstI2c_data[LINEAR_LAUNCH_1].u32RegAddr = OS04C10_HOLD_3208; + pstI2c_data[LINEAR_LAUNCH_1].u32Data = 0xA0; + pstI2c_data[LINEAR_LAUNCH_1].u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[WDR2_HOLD_START].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_HOLD_END].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_LAUNCH_0].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_LAUNCH_1].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD_START].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_HOLD_END].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_LAUNCH_0].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_LAUNCH_1].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (OS04C10_RES_IS_1520P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OS04C10_MODE_2688X1520P30; + else if (OS04C10_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OS04C10_MODE_2560X1440P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (OS04C10_RES_IS_1520P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OS04C10_MODE_2688X1520P30_WDR; + else if (OS04C10_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OS04C10_MODE_2560X1440P30_WDR; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeOs04c10_MirrorFip[ViPipe] != eSnsMirrorFlip) { + os04c10_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeOs04c10_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = OS04C10_MODE_2560X1440P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astOs04c10_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &os04c10_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astOs04c10_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astOs04c10_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } else { + pstRxAttr->mac_clk = RX_MAC_CLK_400M; + pstRxAttr->mipi_attr.raw_data_type = RAW_DATA_10BIT; + } + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &os04c10_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = os04c10_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = os04c10_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (OS04C10_I2C_ADDR_IS_VALID(s32I2cAddr)) + os04c10_i2c_addr = s32I2cAddr; +} + +static CVI_S32 os04c10_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunOs04c10_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + OS04C10_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OS04C10_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + OS04C10_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = OS04C10_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, OS04C10_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, OS04C10_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, OS04C10_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Os04c10_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Os04c10_UseHwSync[ViPipe] = pstInitAttr->u16UseHwSync; + + return CVI_SUCCESS; +} +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return os04c10_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsOs04c10_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = os04c10_standby, + .pfnRestart = os04c10_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = os04c10_write_register, + .pfnReadReg = os04c10_read_register, + .pfnSetBusInfo = os04c10_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_os04c10/os04c10_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/ov_os04c10/os04c10_cmos_ex.h new file mode 100644 index 000000000..6245ff339 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_os04c10/os04c10_cmos_ex.h @@ -0,0 +1,121 @@ +#ifndef __OS04C10_CMOS_EX_H_ +#define __OS04C10_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum os04c10_linear_regs_e { + LINEAR_HOLD_START = 0, + LINEAR_EXP_0, + LINEAR_EXP_1, + LINEAR_AGAIN_0, + LINEAR_AGAIN_1, + LINEAR_DGAIN_0, + LINEAR_DGAIN_1, + LINEAR_VTS_0, + LINEAR_VTS_1, + LINEAR_HOLD_END, + LINEAR_LAUNCH_0, + LINEAR_LAUNCH_1, + LINEAR_REGS_NUM +}; + +enum os04c10_wdr2_regs_e { + WDR2_HOLD_START = 0, + WDR2_EXP1_0, + WDR2_EXP1_1, + WDR2_EXP2_0, + WDR2_EXP2_1, + WDR2_AGAIN1_0, + WDR2_AGAIN1_1, + WDR2_AGAIN2_0, + WDR2_AGAIN2_1, + WDR2_DGAIN1_0, + WDR2_DGAIN1_1, + WDR2_DGAIN2_0, + WDR2_DGAIN2_1, + WDR2_VTS_0, + WDR2_VTS_1, + WDR2_HOLD_END, + WDR2_LAUNCH_0, + WDR2_LAUNCH_1, + WDR2_GGAIN_0, + WDR2_GGAIN_1, + WDR2_REGS_NUM +}; + +typedef enum _OS04C10_MODE_E { + OS04C10_MODE_2688X1520P30 = 0, + OS04C10_MODE_2560X1440P30, + OS04C10_MODE_LINEAR_NUM, + OS04C10_MODE_2688X1520P30_WDR = OS04C10_MODE_LINEAR_NUM, + OS04C10_MODE_2560X1440P30_WDR, + OS04C10_MODE_NUM +} OS04C10_MODE_E; + +typedef struct _OS04C10_STATE_S { + CVI_U32 u32Sexp_MAX; +} OS04C10_STATE_S; + +typedef struct _OS04C10_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + CVI_U16 u16L2sOffset; + CVI_U16 u16TopBoundary; + CVI_U16 u16BotBoundary; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + CVI_U32 u32L2S_offset; + CVI_U32 u32IspResTime; + CVI_U32 u32HdrMargin; + char name[64]; +} OS04C10_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastOs04c10[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunOs04c10_BusInfo[]; +extern CVI_U16 g_au16Os04c10_GainMode[]; +extern CVI_U16 g_au16Os04c10_UseHwSync[VI_MAX_PIPE_NUM]; +extern CVI_U8 os04c10_i2c_addr; +extern const CVI_U32 os04c10_addr_byte; +extern const CVI_U32 os04c10_data_byte; +extern void os04c10_init(VI_PIPE ViPipe); +extern void os04c10_exit(VI_PIPE ViPipe); +extern void os04c10_standby(VI_PIPE ViPipe); +extern void os04c10_restart(VI_PIPE ViPipe); +extern int os04c10_write_register(VI_PIPE ViPipe, int addr, int data); +extern int os04c10_read_register(VI_PIPE ViPipe, int addr); +extern void os04c10_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int os04c10_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OS04C10_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_os04c10/os04c10_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/ov_os04c10/os04c10_cmos_param.h new file mode 100644 index 000000000..015eda30c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_os04c10/os04c10_cmos_param.h @@ -0,0 +1,359 @@ +#ifndef __OS04C10_CMOS_PARAM_H_ +#define __OS04C10_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "os04c10_cmos_ex.h" + +static const OS04C10_MODE_S g_astOs04c10_mode[OS04C10_MODE_NUM] = { + [OS04C10_MODE_2688X1520P30] = { + .name = "2688x1520p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2688, + .u32Height = 1520, + }, + .stMaxSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.73, /* 0x626 * 30 / 0xFFFF */ + .u32HtsDef = 3116, + .u32VtsDef = 1574, + .stExp[0] = { + .u16Min = 2, + .u16Max = 1574 - 8, + .u16Def = 500, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [OS04C10_MODE_2560X1440P30] = { + .name = "2560x1440p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.73, /* 0x626 * 30 / 0xFFFF */ + .u32HtsDef = 3116, + .u32VtsDef = 1574, + .stExp[0] = { + .u16Min = 2, + .u16Max = 1574 - 8, + .u16Def = 500, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [OS04C10_MODE_2688X1520P30_WDR] = { + .name = "2688x1520p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2688, + .u32Height = 1520, + }, + .stMaxSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2688, + .u32Height = 1520, + }, + .stMaxSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.77, /* 1682 * 30 / 0xFFFF */ + .u32HtsDef = 2972, + .u32VtsDef = 1682, + .u16L2sOffset = 4, + .u16TopBoundary = 24, + .u16BotBoundary = 244, + .stExp[0] = { + .u16Min = 8, + .u16Max = 88, + .u16Def = 88, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 8, + .u16Max = 0x486 - 4 - 88, + .u16Def = 500, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 1, + }, + .u32L2S_offset = 4, + .u32IspResTime = 50, /* about 1ms * line rate */ + .u32HdrMargin = 40, /* black_line + zero_line + ISP_offset * 2 */ + }, + [OS04C10_MODE_2560X1440P30_WDR] = { + .name = "2560x1440p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.77, /* 1682 * 30 / 0xFFFF */ + .u32HtsDef = 2972, + .u32VtsDef = 1682, + .u16L2sOffset = 4, + .u16TopBoundary = 24, + .u16BotBoundary = 244, + .stExp[0] = { + .u16Min = 8, + .u16Max = 88, + .u16Def = 88, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 8, + .u16Max = 0x486 - 4 - 88, + .u16Def = 500, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 1, + }, + .u32L2S_offset = 4, + .u32IspResTime = 50, /* about 1ms * line rate */ + .u32HdrMargin = 40, /* black_line + zero_line + ISP_offset * 2 */ + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {128, 128, 128, 128, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1057, 1057, 1057, 1057 +#endif + }, + .stAuto = { + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, +#endif + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio10Bit = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, +#endif + }, + }, +}; + +struct combo_dev_attr_s os04c10_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {0, 1, 2, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_25M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OS04C10_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_os04c10/os04c10_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/ov_os04c10/os04c10_sensor_ctl.c new file mode 100644 index 000000000..2cc6f6674 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_os04c10/os04c10_sensor_ctl.c @@ -0,0 +1,1627 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "os04c10_cmos_ex.h" + +#define HW_SYNC_AUTO 1 + +static void os04c10_wdr_1520p30_2to1_init(VI_PIPE ViPipe); +static void os04c10_linear_1520p30_init(VI_PIPE ViPipe); +static void os04c10_wdr_1440p30_2to1_init(VI_PIPE ViPipe); +static void os04c10_linear_1440p30_init(VI_PIPE ViPipe); + + +CVI_U8 os04c10_i2c_addr = 0x10; /* I2C Address of OS04C10 */ +const CVI_U32 os04c10_addr_byte = 2; +const CVI_U32 os04c10_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int os04c10_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunOs04c10_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, os04c10_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int os04c10_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int os04c10_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (os04c10_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, os04c10_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, os04c10_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (os04c10_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int os04c10_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (os04c10_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (os04c10_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, os04c10_addr_byte + os04c10_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void os04c10_prog(VI_PIPE ViPipe, int *rom) +{ + int i = 0; + + while (1) { + int lookup = rom[i++]; + int addr = (lookup >> 16) & 0xFFFF; + int data = lookup & 0xFFFF; + + if (addr == 0xFFFE) + delay_ms(data); + else if (addr != 0xFFFF) + os04c10_write_register(ViPipe, addr, data); + } +} + +void os04c10_standby(VI_PIPE ViPipe) +{ + os04c10_write_register(ViPipe, 0x0100, 0x00); /* STANDBY */ +} + +void os04c10_restart(VI_PIPE ViPipe) +{ + os04c10_write_register(ViPipe, 0x0100, 0x01); /* standby */ +} + +void os04c10_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + CVI_U32 start = 1; + CVI_U32 end = g_pastOs04c10[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum - 3; + + for (i = start; i < end; i++) { + os04c10_write_register(ViPipe, + g_pastOs04c10[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastOs04c10[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void os04c10_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 orien1, orien2; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + orien1 = 0x80; + orien2 = 0x24; + break; + case ISP_SNS_MIRROR: + orien1 = 0x88; + orien2 = 0x24; + break; + case ISP_SNS_FLIP: + orien1 = 0xB0; + orien2 = 0x04; + break; + case ISP_SNS_MIRROR_FLIP: + orien1 = 0xB8; + orien2 = 0x04; + break; + default: + return; + } + + os04c10_write_register(ViPipe, 0x3820, orien1); + os04c10_write_register(ViPipe, 0x3716, orien2); +} +#define OS04C10_CHIP_ID_ADDR_H 0x300A +#define OS04C10_CHIP_ID_ADDR_M 0x300B +#define OS04C10_CHIP_ID_ADDR_L 0x300C +#define OS04C10_CHIP_ID 0x530443 + +int os04c10_probe(VI_PIPE ViPipe) +{ + int nVal, nVal2, nVal3; + + usleep(500); + if (os04c10_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = os04c10_read_register(ViPipe, OS04C10_CHIP_ID_ADDR_H); + nVal2 = os04c10_read_register(ViPipe, OS04C10_CHIP_ID_ADDR_M); + nVal3 = os04c10_read_register(ViPipe, OS04C10_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0 || nVal3 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 16) | ((nVal2 & 0xFF) << 8) | (nVal3 & 0xFF)) != OS04C10_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void os04c10_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastOs04c10[ViPipe]->enWDRMode; + u8ImgMode = g_pastOs04c10[ViPipe]->u8ImgMode; + + os04c10_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == OS04C10_MODE_2688X1520P30_WDR) + os04c10_wdr_1520p30_2to1_init(ViPipe); + else if (u8ImgMode == OS04C10_MODE_2560X1440P30_WDR) + os04c10_wdr_1440p30_2to1_init(ViPipe); + else { + } + } else { + if (u8ImgMode == OS04C10_MODE_2688X1520P30) + os04c10_linear_1520p30_init(ViPipe); + else if (u8ImgMode == OS04C10_MODE_2560X1440P30) + os04c10_linear_1440p30_init(ViPipe); + else { + } + } + g_pastOs04c10[ViPipe]->bInit = CVI_TRUE; +} + +void os04c10_exit(VI_PIPE ViPipe) +{ + os04c10_i2c_exit(ViPipe); +} + +/* 1520P30 and 1520P25 */ +static void os04c10_linear_1520p30_init(VI_PIPE ViPipe) +{ + os04c10_write_register(ViPipe, 0x0100, 0x00); + os04c10_write_register(ViPipe, 0x0103, 0x01); + os04c10_write_register(ViPipe, 0x0301, 0xe4); + os04c10_write_register(ViPipe, 0x0303, 0x01); + os04c10_write_register(ViPipe, 0x0305, 0x6e); + os04c10_write_register(ViPipe, 0x0306, 0x01); + os04c10_write_register(ViPipe, 0x0307, 0x17); + os04c10_write_register(ViPipe, 0x0323, 0x04); + os04c10_write_register(ViPipe, 0x0324, 0x01); + os04c10_write_register(ViPipe, 0x0325, 0x62); + os04c10_write_register(ViPipe, 0x3012, 0x06); + os04c10_write_register(ViPipe, 0x3013, 0x02); + os04c10_write_register(ViPipe, 0x3016, 0x72); + os04c10_write_register(ViPipe, 0x3021, 0x03); + os04c10_write_register(ViPipe, 0x3106, 0x21); + os04c10_write_register(ViPipe, 0x3107, 0xa1); + os04c10_write_register(ViPipe, 0x3500, 0x00); + os04c10_write_register(ViPipe, 0x3501, 0x06); + os04c10_write_register(ViPipe, 0x3502, 0x1e); + os04c10_write_register(ViPipe, 0x3503, 0x88); + os04c10_write_register(ViPipe, 0x3508, 0x00); + os04c10_write_register(ViPipe, 0x3509, 0x80); + os04c10_write_register(ViPipe, 0x350a, 0x04); + os04c10_write_register(ViPipe, 0x350b, 0x00); + os04c10_write_register(ViPipe, 0x350c, 0x00); + os04c10_write_register(ViPipe, 0x350d, 0x80); + os04c10_write_register(ViPipe, 0x350e, 0x04); + os04c10_write_register(ViPipe, 0x350f, 0x00); + os04c10_write_register(ViPipe, 0x3510, 0x00); + os04c10_write_register(ViPipe, 0x3511, 0x00); + os04c10_write_register(ViPipe, 0x3512, 0x20); + os04c10_write_register(ViPipe, 0x3624, 0x02); + os04c10_write_register(ViPipe, 0x3625, 0x4c); + os04c10_write_register(ViPipe, 0x3660, 0x00); + os04c10_write_register(ViPipe, 0x3666, 0xa5); + os04c10_write_register(ViPipe, 0x3667, 0xa5); + os04c10_write_register(ViPipe, 0x366a, 0x60); + os04c10_write_register(ViPipe, 0x3673, 0x0d); + os04c10_write_register(ViPipe, 0x3672, 0x0d); + os04c10_write_register(ViPipe, 0x3671, 0x0d); + os04c10_write_register(ViPipe, 0x3670, 0x0d); + os04c10_write_register(ViPipe, 0x3685, 0x00); + os04c10_write_register(ViPipe, 0x3694, 0x0d); + os04c10_write_register(ViPipe, 0x3693, 0x0d); + os04c10_write_register(ViPipe, 0x3692, 0x0d); + os04c10_write_register(ViPipe, 0x3691, 0x0d); + os04c10_write_register(ViPipe, 0x3696, 0x4c); + os04c10_write_register(ViPipe, 0x3697, 0x4c); + os04c10_write_register(ViPipe, 0x3698, 0x40); + os04c10_write_register(ViPipe, 0x3699, 0x80); + os04c10_write_register(ViPipe, 0x369a, 0x18); + os04c10_write_register(ViPipe, 0x369b, 0x1f); + os04c10_write_register(ViPipe, 0x369c, 0x14); + os04c10_write_register(ViPipe, 0x369d, 0x80); + os04c10_write_register(ViPipe, 0x369e, 0x40); + os04c10_write_register(ViPipe, 0x369f, 0x21); + os04c10_write_register(ViPipe, 0x36a0, 0x12); + os04c10_write_register(ViPipe, 0x36a1, 0x5d); + os04c10_write_register(ViPipe, 0x36a2, 0x66); + os04c10_write_register(ViPipe, 0x370a, 0x02); + os04c10_write_register(ViPipe, 0x370e, 0x0c); + os04c10_write_register(ViPipe, 0x3710, 0x00); + os04c10_write_register(ViPipe, 0x3713, 0x00); + os04c10_write_register(ViPipe, 0x3725, 0x02); + os04c10_write_register(ViPipe, 0x372a, 0x03); + os04c10_write_register(ViPipe, 0x3738, 0xce); + os04c10_write_register(ViPipe, 0x3739, 0x10); + os04c10_write_register(ViPipe, 0x3748, 0x02); + os04c10_write_register(ViPipe, 0x374a, 0x02); + os04c10_write_register(ViPipe, 0x374c, 0x02); + os04c10_write_register(ViPipe, 0x374e, 0x02); + os04c10_write_register(ViPipe, 0x3756, 0x00); + os04c10_write_register(ViPipe, 0x3757, 0x0e); + os04c10_write_register(ViPipe, 0x3767, 0x00); + os04c10_write_register(ViPipe, 0x3771, 0x00); + os04c10_write_register(ViPipe, 0x377b, 0x20); + os04c10_write_register(ViPipe, 0x377c, 0x00); + os04c10_write_register(ViPipe, 0x377d, 0x0c); + os04c10_write_register(ViPipe, 0x3781, 0x03); + os04c10_write_register(ViPipe, 0x3782, 0x00); + os04c10_write_register(ViPipe, 0x3789, 0x14); + os04c10_write_register(ViPipe, 0x3795, 0x02); + os04c10_write_register(ViPipe, 0x379c, 0x00); + os04c10_write_register(ViPipe, 0x379d, 0x00); + os04c10_write_register(ViPipe, 0x37b8, 0x04); + os04c10_write_register(ViPipe, 0x37ba, 0x03); + os04c10_write_register(ViPipe, 0x37bb, 0x00); + os04c10_write_register(ViPipe, 0x37bc, 0x04); + os04c10_write_register(ViPipe, 0x37be, 0x08); + os04c10_write_register(ViPipe, 0x37c4, 0x11); + os04c10_write_register(ViPipe, 0x37c5, 0x80); + os04c10_write_register(ViPipe, 0x37c6, 0x14); + os04c10_write_register(ViPipe, 0x37c7, 0x08); + os04c10_write_register(ViPipe, 0x37da, 0x11); + os04c10_write_register(ViPipe, 0x381f, 0x08); + os04c10_write_register(ViPipe, 0x3829, 0x03); + os04c10_write_register(ViPipe, 0x3832, 0x00); + os04c10_write_register(ViPipe, 0x3881, 0x00); + os04c10_write_register(ViPipe, 0x3888, 0x04); + os04c10_write_register(ViPipe, 0x388b, 0x00); + os04c10_write_register(ViPipe, 0x3c80, 0x10); + os04c10_write_register(ViPipe, 0x3c86, 0x00); + os04c10_write_register(ViPipe, 0x3c9f, 0x01); + os04c10_write_register(ViPipe, 0x3d85, 0x1b); + os04c10_write_register(ViPipe, 0x3d8c, 0x71); + os04c10_write_register(ViPipe, 0x3d8d, 0xe2); + os04c10_write_register(ViPipe, 0x3f00, 0x0b); + os04c10_write_register(ViPipe, 0x3f06, 0x04); + os04c10_write_register(ViPipe, 0x400a, 0x01); + os04c10_write_register(ViPipe, 0x400b, 0x50); + os04c10_write_register(ViPipe, 0x400e, 0x08); + os04c10_write_register(ViPipe, 0x4040, 0x00); + os04c10_write_register(ViPipe, 0x4041, 0x07); + os04c10_write_register(ViPipe, 0x4043, 0x7e); + os04c10_write_register(ViPipe, 0x4045, 0x7e); + os04c10_write_register(ViPipe, 0x4047, 0x7e); + os04c10_write_register(ViPipe, 0x4049, 0x7e); + os04c10_write_register(ViPipe, 0x4090, 0x04); + os04c10_write_register(ViPipe, 0x40b0, 0x00); + os04c10_write_register(ViPipe, 0x40b1, 0x00); + os04c10_write_register(ViPipe, 0x40b2, 0x00); + os04c10_write_register(ViPipe, 0x40b3, 0x00); + os04c10_write_register(ViPipe, 0x40b4, 0x00); + os04c10_write_register(ViPipe, 0x40b5, 0x00); + os04c10_write_register(ViPipe, 0x40b7, 0x00); + os04c10_write_register(ViPipe, 0x40b8, 0x00); + os04c10_write_register(ViPipe, 0x40b9, 0x00); + os04c10_write_register(ViPipe, 0x40ba, 0x00); + os04c10_write_register(ViPipe, 0x4301, 0x00); + os04c10_write_register(ViPipe, 0x4303, 0x00); + os04c10_write_register(ViPipe, 0x4502, 0x04); + os04c10_write_register(ViPipe, 0x4503, 0x00); + os04c10_write_register(ViPipe, 0x4504, 0x06); + os04c10_write_register(ViPipe, 0x4506, 0x00); + os04c10_write_register(ViPipe, 0x4507, 0x64); + os04c10_write_register(ViPipe, 0x4803, 0x00); + os04c10_write_register(ViPipe, 0x480c, 0x32); + os04c10_write_register(ViPipe, 0x480e, 0x00); + os04c10_write_register(ViPipe, 0x4813, 0x00); + os04c10_write_register(ViPipe, 0x4819, 0x70); + os04c10_write_register(ViPipe, 0x481f, 0x30); + os04c10_write_register(ViPipe, 0x4823, 0x3f); + os04c10_write_register(ViPipe, 0x4825, 0x30); + os04c10_write_register(ViPipe, 0x4833, 0x10); + os04c10_write_register(ViPipe, 0x484b, 0x07); + os04c10_write_register(ViPipe, 0x488b, 0x00); + os04c10_write_register(ViPipe, 0x4d00, 0x04); + os04c10_write_register(ViPipe, 0x4d01, 0xad); + os04c10_write_register(ViPipe, 0x4d02, 0xbc); + os04c10_write_register(ViPipe, 0x4d03, 0xa1); + os04c10_write_register(ViPipe, 0x4d04, 0x1f); + os04c10_write_register(ViPipe, 0x4d05, 0x4c); + os04c10_write_register(ViPipe, 0x4d0b, 0x01); + os04c10_write_register(ViPipe, 0x4e00, 0x2a); + os04c10_write_register(ViPipe, 0x4e0d, 0x00); + os04c10_write_register(ViPipe, 0x5001, 0x09); + os04c10_write_register(ViPipe, 0x5004, 0x00); + os04c10_write_register(ViPipe, 0x5080, 0x04); + os04c10_write_register(ViPipe, 0x5036, 0x00); + os04c10_write_register(ViPipe, 0x5180, 0x70); + os04c10_write_register(ViPipe, 0x5181, 0x10); + os04c10_write_register(ViPipe, 0x520a, 0x03); + os04c10_write_register(ViPipe, 0x520b, 0x06); + os04c10_write_register(ViPipe, 0x520c, 0x0c); + os04c10_write_register(ViPipe, 0x580b, 0x0f); + os04c10_write_register(ViPipe, 0x580d, 0x00); + os04c10_write_register(ViPipe, 0x580f, 0x00); + os04c10_write_register(ViPipe, 0x5820, 0x00); + os04c10_write_register(ViPipe, 0x5821, 0x00); + os04c10_write_register(ViPipe, 0x301c, 0xf8); + os04c10_write_register(ViPipe, 0x301e, 0xb4); + os04c10_write_register(ViPipe, 0x301f, 0xd0); + os04c10_write_register(ViPipe, 0x3022, 0x61); + os04c10_write_register(ViPipe, 0x3109, 0xe7); + os04c10_write_register(ViPipe, 0x3600, 0x00); + os04c10_write_register(ViPipe, 0x3610, 0x95); + os04c10_write_register(ViPipe, 0x3611, 0x85); + os04c10_write_register(ViPipe, 0x3613, 0x3a); + os04c10_write_register(ViPipe, 0x3615, 0x60); + os04c10_write_register(ViPipe, 0x3621, 0xb0); + os04c10_write_register(ViPipe, 0x3620, 0x0c); + os04c10_write_register(ViPipe, 0x3629, 0x00); + os04c10_write_register(ViPipe, 0x3661, 0x04); + os04c10_write_register(ViPipe, 0x3662, 0x10); + os04c10_write_register(ViPipe, 0x3664, 0x70); + os04c10_write_register(ViPipe, 0x3665, 0x00); + os04c10_write_register(ViPipe, 0x3681, 0xa6); + os04c10_write_register(ViPipe, 0x3682, 0x53); + os04c10_write_register(ViPipe, 0x3683, 0x2a); + os04c10_write_register(ViPipe, 0x3684, 0x15); + os04c10_write_register(ViPipe, 0x3700, 0x2a); + os04c10_write_register(ViPipe, 0x3701, 0x12); + os04c10_write_register(ViPipe, 0x3703, 0x28); + os04c10_write_register(ViPipe, 0x3704, 0x0e); + os04c10_write_register(ViPipe, 0x3706, 0x9d); + os04c10_write_register(ViPipe, 0x3709, 0x4a); + os04c10_write_register(ViPipe, 0x370b, 0x48); + os04c10_write_register(ViPipe, 0x370c, 0x01); + os04c10_write_register(ViPipe, 0x370f, 0x04); + os04c10_write_register(ViPipe, 0x3714, 0x24); + os04c10_write_register(ViPipe, 0x3716, 0x24); + os04c10_write_register(ViPipe, 0x3719, 0x11); + os04c10_write_register(ViPipe, 0x371a, 0x1e); + os04c10_write_register(ViPipe, 0x3720, 0x00); + os04c10_write_register(ViPipe, 0x3724, 0x13); + os04c10_write_register(ViPipe, 0x373f, 0xb0); + os04c10_write_register(ViPipe, 0x3741, 0x9d); + os04c10_write_register(ViPipe, 0x3743, 0x9d); + os04c10_write_register(ViPipe, 0x3745, 0x9d); + os04c10_write_register(ViPipe, 0x3747, 0x9d); + os04c10_write_register(ViPipe, 0x3749, 0x48); + os04c10_write_register(ViPipe, 0x374b, 0x48); + os04c10_write_register(ViPipe, 0x374d, 0x48); + os04c10_write_register(ViPipe, 0x374f, 0x48); + os04c10_write_register(ViPipe, 0x3755, 0x10); + os04c10_write_register(ViPipe, 0x376c, 0x00); + os04c10_write_register(ViPipe, 0x378d, 0x3c); + os04c10_write_register(ViPipe, 0x3790, 0x01); + os04c10_write_register(ViPipe, 0x3791, 0x01); + os04c10_write_register(ViPipe, 0x3798, 0x40); + os04c10_write_register(ViPipe, 0x379e, 0x00); + os04c10_write_register(ViPipe, 0x379f, 0x04); + os04c10_write_register(ViPipe, 0x37a1, 0x10); + os04c10_write_register(ViPipe, 0x37a2, 0x1e); + os04c10_write_register(ViPipe, 0x37a8, 0x10); + os04c10_write_register(ViPipe, 0x37a9, 0x1e); + os04c10_write_register(ViPipe, 0x37ac, 0xa0); + os04c10_write_register(ViPipe, 0x37b9, 0x01); + os04c10_write_register(ViPipe, 0x37bd, 0x01); + os04c10_write_register(ViPipe, 0x37bf, 0x26); + os04c10_write_register(ViPipe, 0x37c0, 0x11); + os04c10_write_register(ViPipe, 0x37c2, 0x04); + os04c10_write_register(ViPipe, 0x37cd, 0x19); + os04c10_write_register(ViPipe, 0x37d8, 0x02); + os04c10_write_register(ViPipe, 0x37d9, 0x08); + os04c10_write_register(ViPipe, 0x37e5, 0x02); + os04c10_write_register(ViPipe, 0x3800, 0x00); + os04c10_write_register(ViPipe, 0x3801, 0x00); + os04c10_write_register(ViPipe, 0x3802, 0x00); + os04c10_write_register(ViPipe, 0x3803, 0x00); + os04c10_write_register(ViPipe, 0x3804, 0x0a); + os04c10_write_register(ViPipe, 0x3805, 0x8f); + os04c10_write_register(ViPipe, 0x3806, 0x05); + os04c10_write_register(ViPipe, 0x3807, 0xff); + os04c10_write_register(ViPipe, 0x3808, 0x0a); + os04c10_write_register(ViPipe, 0x3809, 0x80); + os04c10_write_register(ViPipe, 0x380a, 0x05); + os04c10_write_register(ViPipe, 0x380b, 0xf0); + os04c10_write_register(ViPipe, 0x380c, 0x08); + os04c10_write_register(ViPipe, 0x380d, 0x5c); + os04c10_write_register(ViPipe, 0x380e, 0x06); + os04c10_write_register(ViPipe, 0x380f, 0x26); + os04c10_write_register(ViPipe, 0x3811, 0x08); + os04c10_write_register(ViPipe, 0x3813, 0x08); + os04c10_write_register(ViPipe, 0x3814, 0x01); + os04c10_write_register(ViPipe, 0x3815, 0x01); + os04c10_write_register(ViPipe, 0x3816, 0x01); + os04c10_write_register(ViPipe, 0x3817, 0x01); + os04c10_write_register(ViPipe, 0x3820, 0x88); + os04c10_write_register(ViPipe, 0x3821, 0x00); + os04c10_write_register(ViPipe, 0x3880, 0x25); + os04c10_write_register(ViPipe, 0x3882, 0x20); + os04c10_write_register(ViPipe, 0x3c91, 0x0b); + os04c10_write_register(ViPipe, 0x3c94, 0x45); + os04c10_write_register(ViPipe, 0x4000, 0xf3); + os04c10_write_register(ViPipe, 0x4001, 0x60); + os04c10_write_register(ViPipe, 0x4003, 0x80); + os04c10_write_register(ViPipe, 0x4008, 0x02); + os04c10_write_register(ViPipe, 0x4009, 0x0d); + os04c10_write_register(ViPipe, 0x4300, 0xff); + os04c10_write_register(ViPipe, 0x4302, 0x0f); + os04c10_write_register(ViPipe, 0x4305, 0x83); + os04c10_write_register(ViPipe, 0x4505, 0x84); + os04c10_write_register(ViPipe, 0x4809, 0x1e); + os04c10_write_register(ViPipe, 0x480a, 0x04); + os04c10_write_register(ViPipe, 0x4837, 0x23); + os04c10_write_register(ViPipe, 0x4c00, 0x08); + os04c10_write_register(ViPipe, 0x4c01, 0x08); + os04c10_write_register(ViPipe, 0x4c04, 0x00); + os04c10_write_register(ViPipe, 0x4c05, 0x00); + os04c10_write_register(ViPipe, 0x5000, 0xf9); + os04c10_write_register(ViPipe, 0x3624, 0x00); + os04c10_write_register(ViPipe, 0x3016, 0x32); + os04c10_write_register(ViPipe, 0x0306, 0x00); + os04c10_write_register(ViPipe, 0x4837, 0x12); + os04c10_write_register(ViPipe, 0x0305, 0x6a); + os04c10_write_register(ViPipe, 0x0325, 0x54); + os04c10_write_register(ViPipe, 0x3106, 0x25); + os04c10_default_reg_init(ViPipe); + + if (!g_au16Os04c10_UseHwSync[ViPipe]) { + /* freerun */ + os04c10_write_register(ViPipe, 0x3002, 0x21); + } else { + /* auto master */ +#if HW_SYNC_AUTO + os04c10_write_register(ViPipe, 0x3002, 0x22); // [1] vsync_oen, [0]: fsin_oen + os04c10_write_register(ViPipe, 0x3690, 0x00); // [4]: 1'b0, 1st set vsync pulse + os04c10_write_register(ViPipe, 0x383e, 0x00); // vscyn_rise_rcnt_pt[23:16] + os04c10_write_register(ViPipe, 0x3818, 0x00); // Slave vsync pulse position cs [15:8] + os04c10_write_register(ViPipe, 0x3819, 0x00); // Slave vsync pulse position cs [7:0], + // max is HTS/4 + os04c10_write_register(ViPipe, 0x381a, 0x00); // vscyn_rise_rcnt_pt[15:8] + os04c10_write_register(ViPipe, 0x381b, 0x00); // vscyn_rise_rcnt_pt[7:0], max: + // VTS-12 for AHBIN 720p, (VTS -12)*2 for + // other formats + os04c10_write_register(ViPipe, 0x3832, 0xf8); // default, 8'h08, [7:4] vsync pulse width + os04c10_write_register(ViPipe, 0x368a, 0x04); // GPIO enable +#else + /* manual master */ + os04c10_write_register(ViPipe, 0x3002, 0x22); // [1] vsync_oen, [0]: fsin_oen + os04c10_write_register(ViPipe, 0x3690, 0x00); // [4]: 1'b0, 1st set vsync pulse + os04c10_write_register(ViPipe, 0x383e, 0x00); // vscyn_rise_rcnt_pt[23:16] + os04c10_write_register(ViPipe, 0x3818, 0x00); // Slave vsync pulse position cs [15:8] + os04c10_write_register(ViPipe, 0x3819, 0x00); // Slave vsync pulse position cs [7:0], + // max is HTS/4 + os04c10_write_register(ViPipe, 0x381a, 0x00); // vscyn_rise_rcnt_pt[15:8] + os04c10_write_register(ViPipe, 0x381b, 0x18); // vscyn_rise_rcnt_pt[7:0], max: + // VTS-12 for AHBIN 720p, (VTS -12)*2 for + // other formats + os04c10_write_register(ViPipe, 0x3832, 0xf8); // default, 8'h08, [7:4] vsync pulse width + os04c10_write_register(ViPipe, 0x368a, 0x04); // GPIO enable +#endif + } + os04c10_write_register(ViPipe, 0x0100, 0x01); + + usleep(50*1000); + + printf("ViPipe:%d,===OS04C10 1520P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void os04c10_linear_1440p30_init(VI_PIPE ViPipe) +{ + os04c10_write_register(ViPipe, 0x0100, 0x00); + os04c10_write_register(ViPipe, 0x0103, 0x01); + os04c10_write_register(ViPipe, 0x0301, 0xe4); + os04c10_write_register(ViPipe, 0x0303, 0x01); + os04c10_write_register(ViPipe, 0x0305, 0x6e); + os04c10_write_register(ViPipe, 0x0306, 0x01); + os04c10_write_register(ViPipe, 0x0307, 0x17); + os04c10_write_register(ViPipe, 0x0323, 0x04); + os04c10_write_register(ViPipe, 0x0324, 0x01); + os04c10_write_register(ViPipe, 0x0325, 0x62); + os04c10_write_register(ViPipe, 0x3012, 0x06); + os04c10_write_register(ViPipe, 0x3013, 0x02); + os04c10_write_register(ViPipe, 0x3016, 0x72); + os04c10_write_register(ViPipe, 0x3021, 0x03); + os04c10_write_register(ViPipe, 0x3106, 0x21); + os04c10_write_register(ViPipe, 0x3107, 0xa1); + os04c10_write_register(ViPipe, 0x3500, 0x00); + os04c10_write_register(ViPipe, 0x3501, 0x06); + os04c10_write_register(ViPipe, 0x3502, 0x1e); + os04c10_write_register(ViPipe, 0x3503, 0x88); + os04c10_write_register(ViPipe, 0x3508, 0x00); + os04c10_write_register(ViPipe, 0x3509, 0x80); + os04c10_write_register(ViPipe, 0x350a, 0x04); + os04c10_write_register(ViPipe, 0x350b, 0x00); + os04c10_write_register(ViPipe, 0x350c, 0x00); + os04c10_write_register(ViPipe, 0x350d, 0x80); + os04c10_write_register(ViPipe, 0x350e, 0x04); + os04c10_write_register(ViPipe, 0x350f, 0x00); + os04c10_write_register(ViPipe, 0x3510, 0x00); + os04c10_write_register(ViPipe, 0x3511, 0x00); + os04c10_write_register(ViPipe, 0x3512, 0x20); + os04c10_write_register(ViPipe, 0x3624, 0x02); + os04c10_write_register(ViPipe, 0x3625, 0x4c); + os04c10_write_register(ViPipe, 0x3660, 0x00); + os04c10_write_register(ViPipe, 0x3666, 0xa5); + os04c10_write_register(ViPipe, 0x3667, 0xa5); + os04c10_write_register(ViPipe, 0x366a, 0x60); + os04c10_write_register(ViPipe, 0x3673, 0x0d); + os04c10_write_register(ViPipe, 0x3672, 0x0d); + os04c10_write_register(ViPipe, 0x3671, 0x0d); + os04c10_write_register(ViPipe, 0x3670, 0x0d); + os04c10_write_register(ViPipe, 0x3685, 0x00); + os04c10_write_register(ViPipe, 0x3694, 0x0d); + os04c10_write_register(ViPipe, 0x3693, 0x0d); + os04c10_write_register(ViPipe, 0x3692, 0x0d); + os04c10_write_register(ViPipe, 0x3691, 0x0d); + os04c10_write_register(ViPipe, 0x3696, 0x4c); + os04c10_write_register(ViPipe, 0x3697, 0x4c); + os04c10_write_register(ViPipe, 0x3698, 0x40); + os04c10_write_register(ViPipe, 0x3699, 0x80); + os04c10_write_register(ViPipe, 0x369a, 0x18); + os04c10_write_register(ViPipe, 0x369b, 0x1f); + os04c10_write_register(ViPipe, 0x369c, 0x14); + os04c10_write_register(ViPipe, 0x369d, 0x80); + os04c10_write_register(ViPipe, 0x369e, 0x40); + os04c10_write_register(ViPipe, 0x369f, 0x21); + os04c10_write_register(ViPipe, 0x36a0, 0x12); + os04c10_write_register(ViPipe, 0x36a1, 0x5d); + os04c10_write_register(ViPipe, 0x36a2, 0x66); + os04c10_write_register(ViPipe, 0x370a, 0x02); + os04c10_write_register(ViPipe, 0x370e, 0x0c); + os04c10_write_register(ViPipe, 0x3710, 0x00); + os04c10_write_register(ViPipe, 0x3713, 0x00); + os04c10_write_register(ViPipe, 0x3725, 0x02); + os04c10_write_register(ViPipe, 0x372a, 0x03); + os04c10_write_register(ViPipe, 0x3738, 0xce); + os04c10_write_register(ViPipe, 0x3739, 0x10); + os04c10_write_register(ViPipe, 0x3748, 0x02); + os04c10_write_register(ViPipe, 0x374a, 0x02); + os04c10_write_register(ViPipe, 0x374c, 0x02); + os04c10_write_register(ViPipe, 0x374e, 0x02); + os04c10_write_register(ViPipe, 0x3756, 0x00); + os04c10_write_register(ViPipe, 0x3757, 0x0e); + os04c10_write_register(ViPipe, 0x3767, 0x00); + os04c10_write_register(ViPipe, 0x3771, 0x00); + os04c10_write_register(ViPipe, 0x377b, 0x20); + os04c10_write_register(ViPipe, 0x377c, 0x00); + os04c10_write_register(ViPipe, 0x377d, 0x0c); + os04c10_write_register(ViPipe, 0x3781, 0x03); + os04c10_write_register(ViPipe, 0x3782, 0x00); + os04c10_write_register(ViPipe, 0x3789, 0x14); + os04c10_write_register(ViPipe, 0x3795, 0x02); + os04c10_write_register(ViPipe, 0x379c, 0x00); + os04c10_write_register(ViPipe, 0x379d, 0x00); + os04c10_write_register(ViPipe, 0x37b8, 0x04); + os04c10_write_register(ViPipe, 0x37ba, 0x03); + os04c10_write_register(ViPipe, 0x37bb, 0x00); + os04c10_write_register(ViPipe, 0x37bc, 0x04); + os04c10_write_register(ViPipe, 0x37be, 0x08); + os04c10_write_register(ViPipe, 0x37c4, 0x11); + os04c10_write_register(ViPipe, 0x37c5, 0x80); + os04c10_write_register(ViPipe, 0x37c6, 0x14); + os04c10_write_register(ViPipe, 0x37c7, 0x08); + os04c10_write_register(ViPipe, 0x37da, 0x11); + os04c10_write_register(ViPipe, 0x381f, 0x08); + os04c10_write_register(ViPipe, 0x3829, 0x03); + os04c10_write_register(ViPipe, 0x3832, 0x00); + os04c10_write_register(ViPipe, 0x3881, 0x00); + os04c10_write_register(ViPipe, 0x3888, 0x04); + os04c10_write_register(ViPipe, 0x388b, 0x00); + os04c10_write_register(ViPipe, 0x3c80, 0x10); + os04c10_write_register(ViPipe, 0x3c86, 0x00); + os04c10_write_register(ViPipe, 0x3c9f, 0x01); + os04c10_write_register(ViPipe, 0x3d85, 0x1b); + os04c10_write_register(ViPipe, 0x3d8c, 0x71); + os04c10_write_register(ViPipe, 0x3d8d, 0xe2); + os04c10_write_register(ViPipe, 0x3f00, 0x0b); + os04c10_write_register(ViPipe, 0x3f06, 0x04); + os04c10_write_register(ViPipe, 0x400a, 0x01); + os04c10_write_register(ViPipe, 0x400b, 0x50); + os04c10_write_register(ViPipe, 0x400e, 0x08); + os04c10_write_register(ViPipe, 0x4040, 0x00); + os04c10_write_register(ViPipe, 0x4041, 0x07); + os04c10_write_register(ViPipe, 0x4043, 0x7e); + os04c10_write_register(ViPipe, 0x4045, 0x7e); + os04c10_write_register(ViPipe, 0x4047, 0x7e); + os04c10_write_register(ViPipe, 0x4049, 0x7e); + os04c10_write_register(ViPipe, 0x4090, 0x04); + os04c10_write_register(ViPipe, 0x40b0, 0x00); + os04c10_write_register(ViPipe, 0x40b1, 0x00); + os04c10_write_register(ViPipe, 0x40b2, 0x00); + os04c10_write_register(ViPipe, 0x40b3, 0x00); + os04c10_write_register(ViPipe, 0x40b4, 0x00); + os04c10_write_register(ViPipe, 0x40b5, 0x00); + os04c10_write_register(ViPipe, 0x40b7, 0x00); + os04c10_write_register(ViPipe, 0x40b8, 0x00); + os04c10_write_register(ViPipe, 0x40b9, 0x00); + os04c10_write_register(ViPipe, 0x40ba, 0x00); + os04c10_write_register(ViPipe, 0x4301, 0x00); + os04c10_write_register(ViPipe, 0x4303, 0x00); + os04c10_write_register(ViPipe, 0x4502, 0x04); + os04c10_write_register(ViPipe, 0x4503, 0x00); + os04c10_write_register(ViPipe, 0x4504, 0x06); + os04c10_write_register(ViPipe, 0x4506, 0x00); + os04c10_write_register(ViPipe, 0x4507, 0x64); + os04c10_write_register(ViPipe, 0x4803, 0x00); + os04c10_write_register(ViPipe, 0x480c, 0x32); + os04c10_write_register(ViPipe, 0x480e, 0x00); + os04c10_write_register(ViPipe, 0x4813, 0x00); + os04c10_write_register(ViPipe, 0x4819, 0x70); + os04c10_write_register(ViPipe, 0x481f, 0x30); + os04c10_write_register(ViPipe, 0x4823, 0x3f); + os04c10_write_register(ViPipe, 0x4825, 0x30); + os04c10_write_register(ViPipe, 0x4833, 0x10); + os04c10_write_register(ViPipe, 0x484b, 0x07); + os04c10_write_register(ViPipe, 0x488b, 0x00); + os04c10_write_register(ViPipe, 0x4d00, 0x04); + os04c10_write_register(ViPipe, 0x4d01, 0xad); + os04c10_write_register(ViPipe, 0x4d02, 0xbc); + os04c10_write_register(ViPipe, 0x4d03, 0xa1); + os04c10_write_register(ViPipe, 0x4d04, 0x1f); + os04c10_write_register(ViPipe, 0x4d05, 0x4c); + os04c10_write_register(ViPipe, 0x4d0b, 0x01); + os04c10_write_register(ViPipe, 0x4e00, 0x2a); + os04c10_write_register(ViPipe, 0x4e0d, 0x00); + os04c10_write_register(ViPipe, 0x5001, 0x09); + os04c10_write_register(ViPipe, 0x5004, 0x00); + os04c10_write_register(ViPipe, 0x5080, 0x04); + os04c10_write_register(ViPipe, 0x5036, 0x00); + os04c10_write_register(ViPipe, 0x5180, 0x70); + os04c10_write_register(ViPipe, 0x5181, 0x10); + os04c10_write_register(ViPipe, 0x520a, 0x03); + os04c10_write_register(ViPipe, 0x520b, 0x06); + os04c10_write_register(ViPipe, 0x520c, 0x0c); + os04c10_write_register(ViPipe, 0x580b, 0x0f); + os04c10_write_register(ViPipe, 0x580d, 0x00); + os04c10_write_register(ViPipe, 0x580f, 0x00); + os04c10_write_register(ViPipe, 0x5820, 0x00); + os04c10_write_register(ViPipe, 0x5821, 0x00); + os04c10_write_register(ViPipe, 0x301c, 0xf8); + os04c10_write_register(ViPipe, 0x301e, 0xb4); + os04c10_write_register(ViPipe, 0x301f, 0xd0); + os04c10_write_register(ViPipe, 0x3022, 0x61); + os04c10_write_register(ViPipe, 0x3109, 0xe7); + os04c10_write_register(ViPipe, 0x3600, 0x00); + os04c10_write_register(ViPipe, 0x3610, 0x95); + os04c10_write_register(ViPipe, 0x3611, 0x85); + os04c10_write_register(ViPipe, 0x3613, 0x3a); + os04c10_write_register(ViPipe, 0x3615, 0x60); + os04c10_write_register(ViPipe, 0x3621, 0xb0); + os04c10_write_register(ViPipe, 0x3620, 0x0c); + os04c10_write_register(ViPipe, 0x3629, 0x00); + os04c10_write_register(ViPipe, 0x3661, 0x04); + os04c10_write_register(ViPipe, 0x3662, 0x10); + os04c10_write_register(ViPipe, 0x3664, 0x70); + os04c10_write_register(ViPipe, 0x3665, 0x00); + os04c10_write_register(ViPipe, 0x3681, 0xa6); + os04c10_write_register(ViPipe, 0x3682, 0x53); + os04c10_write_register(ViPipe, 0x3683, 0x2a); + os04c10_write_register(ViPipe, 0x3684, 0x15); + os04c10_write_register(ViPipe, 0x3700, 0x2a); + os04c10_write_register(ViPipe, 0x3701, 0x12); + os04c10_write_register(ViPipe, 0x3703, 0x28); + os04c10_write_register(ViPipe, 0x3704, 0x0e); + os04c10_write_register(ViPipe, 0x3706, 0x9d); + os04c10_write_register(ViPipe, 0x3709, 0x4a); + os04c10_write_register(ViPipe, 0x370b, 0x48); + os04c10_write_register(ViPipe, 0x370c, 0x01); + os04c10_write_register(ViPipe, 0x370f, 0x04); + os04c10_write_register(ViPipe, 0x3714, 0x24); + os04c10_write_register(ViPipe, 0x3716, 0x24); + os04c10_write_register(ViPipe, 0x3719, 0x11); + os04c10_write_register(ViPipe, 0x371a, 0x1e); + os04c10_write_register(ViPipe, 0x3720, 0x00); + os04c10_write_register(ViPipe, 0x3724, 0x13); + os04c10_write_register(ViPipe, 0x373f, 0xb0); + os04c10_write_register(ViPipe, 0x3741, 0x9d); + os04c10_write_register(ViPipe, 0x3743, 0x9d); + os04c10_write_register(ViPipe, 0x3745, 0x9d); + os04c10_write_register(ViPipe, 0x3747, 0x9d); + os04c10_write_register(ViPipe, 0x3749, 0x48); + os04c10_write_register(ViPipe, 0x374b, 0x48); + os04c10_write_register(ViPipe, 0x374d, 0x48); + os04c10_write_register(ViPipe, 0x374f, 0x48); + os04c10_write_register(ViPipe, 0x3755, 0x10); + os04c10_write_register(ViPipe, 0x376c, 0x00); + os04c10_write_register(ViPipe, 0x378d, 0x3c); + os04c10_write_register(ViPipe, 0x3790, 0x01); + os04c10_write_register(ViPipe, 0x3791, 0x01); + os04c10_write_register(ViPipe, 0x3798, 0x40); + os04c10_write_register(ViPipe, 0x379e, 0x00); + os04c10_write_register(ViPipe, 0x379f, 0x04); + os04c10_write_register(ViPipe, 0x37a1, 0x10); + os04c10_write_register(ViPipe, 0x37a2, 0x1e); + os04c10_write_register(ViPipe, 0x37a8, 0x10); + os04c10_write_register(ViPipe, 0x37a9, 0x1e); + os04c10_write_register(ViPipe, 0x37ac, 0xa0); + os04c10_write_register(ViPipe, 0x37b9, 0x01); + os04c10_write_register(ViPipe, 0x37bd, 0x01); + os04c10_write_register(ViPipe, 0x37bf, 0x26); + os04c10_write_register(ViPipe, 0x37c0, 0x11); + os04c10_write_register(ViPipe, 0x37c2, 0x04); + os04c10_write_register(ViPipe, 0x37cd, 0x19); + os04c10_write_register(ViPipe, 0x37d8, 0x02); + os04c10_write_register(ViPipe, 0x37d9, 0x08); + os04c10_write_register(ViPipe, 0x37e5, 0x02); + os04c10_write_register(ViPipe, 0x3800, 0x00); + os04c10_write_register(ViPipe, 0x3801, 0x40); + os04c10_write_register(ViPipe, 0x3802, 0x00); + os04c10_write_register(ViPipe, 0x3803, 0x28); + os04c10_write_register(ViPipe, 0x3804, 0x0a); + os04c10_write_register(ViPipe, 0x3805, 0x4f); + os04c10_write_register(ViPipe, 0x3806, 0x05); + os04c10_write_register(ViPipe, 0x3807, 0xd7); + os04c10_write_register(ViPipe, 0x3808, 0x0a); + os04c10_write_register(ViPipe, 0x3809, 0x00); + os04c10_write_register(ViPipe, 0x380a, 0x05); + os04c10_write_register(ViPipe, 0x380b, 0xa0); + os04c10_write_register(ViPipe, 0x380c, 0x08); + os04c10_write_register(ViPipe, 0x380d, 0x5c); + os04c10_write_register(ViPipe, 0x380e, 0x06); + os04c10_write_register(ViPipe, 0x380f, 0x26); + os04c10_write_register(ViPipe, 0x3811, 0x08); + os04c10_write_register(ViPipe, 0x3813, 0x08); + os04c10_write_register(ViPipe, 0x3814, 0x01); + os04c10_write_register(ViPipe, 0x3815, 0x01); + os04c10_write_register(ViPipe, 0x3816, 0x01); + os04c10_write_register(ViPipe, 0x3817, 0x01); + os04c10_write_register(ViPipe, 0x3820, 0x88); + os04c10_write_register(ViPipe, 0x3821, 0x00); + os04c10_write_register(ViPipe, 0x3880, 0x25); + os04c10_write_register(ViPipe, 0x3882, 0x20); + os04c10_write_register(ViPipe, 0x3c91, 0x0b); + os04c10_write_register(ViPipe, 0x3c94, 0x45); + os04c10_write_register(ViPipe, 0x4000, 0xf3); + os04c10_write_register(ViPipe, 0x4001, 0x60); + os04c10_write_register(ViPipe, 0x4003, 0x80); + os04c10_write_register(ViPipe, 0x4008, 0x02); + os04c10_write_register(ViPipe, 0x4009, 0x0d); + os04c10_write_register(ViPipe, 0x4300, 0xff); + os04c10_write_register(ViPipe, 0x4302, 0x0f); + os04c10_write_register(ViPipe, 0x4305, 0x83); + os04c10_write_register(ViPipe, 0x4505, 0x84); + os04c10_write_register(ViPipe, 0x4809, 0x1e); + os04c10_write_register(ViPipe, 0x480a, 0x04); + os04c10_write_register(ViPipe, 0x4837, 0x23); + os04c10_write_register(ViPipe, 0x4c00, 0x08); + os04c10_write_register(ViPipe, 0x4c01, 0x08); + os04c10_write_register(ViPipe, 0x4c04, 0x00); + os04c10_write_register(ViPipe, 0x4c05, 0x00); + os04c10_write_register(ViPipe, 0x5000, 0xe9); + os04c10_write_register(ViPipe, 0x3624, 0x00); + os04c10_write_register(ViPipe, 0x3016, 0x32); + os04c10_write_register(ViPipe, 0x0306, 0x00); + os04c10_write_register(ViPipe, 0x4837, 0x12); + os04c10_write_register(ViPipe, 0x0305, 0x6a); + os04c10_write_register(ViPipe, 0x0325, 0x54); + os04c10_write_register(ViPipe, 0x3106, 0x25); + os04c10_default_reg_init(ViPipe); + + if (!g_au16Os04c10_UseHwSync[ViPipe]) { + /* freerun */ + os04c10_write_register(ViPipe, 0x3002, 0x21); + } else { + /* auto master */ + os04c10_write_register(ViPipe, 0x3002, 0x23); // [1] vsync_oen, [0]: fsin_oen + os04c10_write_register(ViPipe, 0x3690, 0x00); // [4]: 1'b0, 1st set vsync pulse + os04c10_write_register(ViPipe, 0x383e, 0x00); // vscyn_rise_rcnt_pt[23:16] + os04c10_write_register(ViPipe, 0x3818, 0x00); // Slave vsync pulse position cs [15:8] + os04c10_write_register(ViPipe, 0x3819, 0x00); // Slave vsync pulse position cs [7:0], + // max is HTS/4 + os04c10_write_register(ViPipe, 0x381a, 0x00); // vscyn_rise_rcnt_pt[15:8] + os04c10_write_register(ViPipe, 0x381b, 0x18); // vscyn_rise_rcnt_pt[7:0], max: + // VTS-12 for AHBIN 720p, (VTS -12)*2 for + // other formats + os04c10_write_register(ViPipe, 0x3832, 0xf8); // default, 8'h08, [7:4] vsync pulse width + os04c10_write_register(ViPipe, 0x368a, 0x04); // GPIO enable + } + os04c10_write_register(ViPipe, 0x0100, 0x01); + + usleep(50*1000); + + printf("ViPipe:%d,===OS04C10 1440P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +static void os04c10_wdr_1520p30_2to1_init(VI_PIPE ViPipe) +{ + os04c10_write_register(ViPipe, 0x0100, 0x00); + os04c10_write_register(ViPipe, 0x0103, 0x01); + os04c10_write_register(ViPipe, 0x0301, 0x84); + os04c10_write_register(ViPipe, 0x0303, 0x01); + os04c10_write_register(ViPipe, 0x0305, 0x61); + os04c10_write_register(ViPipe, 0x0306, 0x01); + os04c10_write_register(ViPipe, 0x0307, 0x17); + os04c10_write_register(ViPipe, 0x0323, 0x04); + os04c10_write_register(ViPipe, 0x0324, 0x01); + os04c10_write_register(ViPipe, 0x0325, 0x7a); + os04c10_write_register(ViPipe, 0x3012, 0x06); + os04c10_write_register(ViPipe, 0x3013, 0x02); + os04c10_write_register(ViPipe, 0x3016, 0x72); + os04c10_write_register(ViPipe, 0x3021, 0x03); + os04c10_write_register(ViPipe, 0x3106, 0x21); + os04c10_write_register(ViPipe, 0x3107, 0xa1); + os04c10_write_register(ViPipe, 0x3500, 0x00); + os04c10_write_register(ViPipe, 0x3501, 0x03); + os04c10_write_register(ViPipe, 0x3502, 0x08); + os04c10_write_register(ViPipe, 0x3503, 0x88); + os04c10_write_register(ViPipe, 0x3508, 0x00); + os04c10_write_register(ViPipe, 0x3509, 0x80); + os04c10_write_register(ViPipe, 0x350a, 0x04); + os04c10_write_register(ViPipe, 0x350b, 0x00); + os04c10_write_register(ViPipe, 0x350c, 0x00); + os04c10_write_register(ViPipe, 0x350d, 0x80); + os04c10_write_register(ViPipe, 0x350e, 0x04); + os04c10_write_register(ViPipe, 0x350f, 0x00); + os04c10_write_register(ViPipe, 0x3510, 0x00); + os04c10_write_register(ViPipe, 0x3511, 0x01); + os04c10_write_register(ViPipe, 0x3512, 0x08); + os04c10_write_register(ViPipe, 0x3624, 0x02); + os04c10_write_register(ViPipe, 0x3625, 0x4c); + os04c10_write_register(ViPipe, 0x3660, 0x04); + os04c10_write_register(ViPipe, 0x3666, 0xa5); + os04c10_write_register(ViPipe, 0x3667, 0xa5); + os04c10_write_register(ViPipe, 0x366a, 0x54); + os04c10_write_register(ViPipe, 0x3673, 0x0d); + os04c10_write_register(ViPipe, 0x3672, 0x0d); + os04c10_write_register(ViPipe, 0x3671, 0x0d); + os04c10_write_register(ViPipe, 0x3670, 0x0d); + os04c10_write_register(ViPipe, 0x3685, 0x00); + os04c10_write_register(ViPipe, 0x3694, 0x0d); + os04c10_write_register(ViPipe, 0x3693, 0x0d); + os04c10_write_register(ViPipe, 0x3692, 0x0d); + os04c10_write_register(ViPipe, 0x3691, 0x0d); + os04c10_write_register(ViPipe, 0x3696, 0x4c); + os04c10_write_register(ViPipe, 0x3697, 0x4c); + os04c10_write_register(ViPipe, 0x3698, 0x40); + os04c10_write_register(ViPipe, 0x3699, 0x80); + os04c10_write_register(ViPipe, 0x369a, 0x18); + os04c10_write_register(ViPipe, 0x369b, 0x1f); + os04c10_write_register(ViPipe, 0x369c, 0x14); + os04c10_write_register(ViPipe, 0x369d, 0x80); + os04c10_write_register(ViPipe, 0x369e, 0x40); + os04c10_write_register(ViPipe, 0x369f, 0x21); + os04c10_write_register(ViPipe, 0x36a0, 0x12); + os04c10_write_register(ViPipe, 0x36a1, 0x5d); + os04c10_write_register(ViPipe, 0x36a2, 0x66); + os04c10_write_register(ViPipe, 0x370a, 0x00); + os04c10_write_register(ViPipe, 0x370e, 0x0c); + os04c10_write_register(ViPipe, 0x3710, 0x00); + os04c10_write_register(ViPipe, 0x3713, 0x00); + os04c10_write_register(ViPipe, 0x3725, 0x02); + os04c10_write_register(ViPipe, 0x372a, 0x03); + os04c10_write_register(ViPipe, 0x3738, 0xce); + os04c10_write_register(ViPipe, 0x3748, 0x00); + os04c10_write_register(ViPipe, 0x374a, 0x00); + os04c10_write_register(ViPipe, 0x374c, 0x00); + os04c10_write_register(ViPipe, 0x374e, 0x00); + os04c10_write_register(ViPipe, 0x3756, 0x00); + os04c10_write_register(ViPipe, 0x3757, 0x00); + os04c10_write_register(ViPipe, 0x3767, 0x00); + os04c10_write_register(ViPipe, 0x3771, 0x00); + os04c10_write_register(ViPipe, 0x377b, 0x28); + os04c10_write_register(ViPipe, 0x377c, 0x00); + os04c10_write_register(ViPipe, 0x377d, 0x0c); + os04c10_write_register(ViPipe, 0x3781, 0x03); + os04c10_write_register(ViPipe, 0x3782, 0x00); + os04c10_write_register(ViPipe, 0x3789, 0x14); + os04c10_write_register(ViPipe, 0x3795, 0x02); + os04c10_write_register(ViPipe, 0x379c, 0x00); + os04c10_write_register(ViPipe, 0x379d, 0x00); + os04c10_write_register(ViPipe, 0x37b8, 0x04); + os04c10_write_register(ViPipe, 0x37ba, 0x03); + os04c10_write_register(ViPipe, 0x37bb, 0x00); + os04c10_write_register(ViPipe, 0x37bc, 0x04); + os04c10_write_register(ViPipe, 0x37be, 0x08); + os04c10_write_register(ViPipe, 0x37c4, 0x11); + os04c10_write_register(ViPipe, 0x37c5, 0x80); + os04c10_write_register(ViPipe, 0x37c6, 0x14); + os04c10_write_register(ViPipe, 0x37c7, 0x08); + os04c10_write_register(ViPipe, 0x37da, 0x11); + os04c10_write_register(ViPipe, 0x381f, 0x08); + os04c10_write_register(ViPipe, 0x3829, 0x03); + os04c10_write_register(ViPipe, 0x3881, 0x00); + os04c10_write_register(ViPipe, 0x3888, 0x04); + os04c10_write_register(ViPipe, 0x388b, 0x00); + os04c10_write_register(ViPipe, 0x3c80, 0x10); + os04c10_write_register(ViPipe, 0x3c86, 0x00); + os04c10_write_register(ViPipe, 0x3c8c, 0x20); + os04c10_write_register(ViPipe, 0x3c9f, 0x01); + os04c10_write_register(ViPipe, 0x3d85, 0x1b); + os04c10_write_register(ViPipe, 0x3d8c, 0x71); + os04c10_write_register(ViPipe, 0x3d8d, 0xe2); + os04c10_write_register(ViPipe, 0x3f00, 0x0b); + os04c10_write_register(ViPipe, 0x3f06, 0x04); + os04c10_write_register(ViPipe, 0x400a, 0x01); + os04c10_write_register(ViPipe, 0x400b, 0x50); + os04c10_write_register(ViPipe, 0x400e, 0x08); + os04c10_write_register(ViPipe, 0x4043, 0x7e); + os04c10_write_register(ViPipe, 0x4045, 0x7e); + os04c10_write_register(ViPipe, 0x4047, 0x7e); + os04c10_write_register(ViPipe, 0x4049, 0x7e); + os04c10_write_register(ViPipe, 0x4090, 0x14); + os04c10_write_register(ViPipe, 0x40b0, 0x00); + os04c10_write_register(ViPipe, 0x40b1, 0x00); + os04c10_write_register(ViPipe, 0x40b2, 0x00); + os04c10_write_register(ViPipe, 0x40b3, 0x00); + os04c10_write_register(ViPipe, 0x40b4, 0x00); + os04c10_write_register(ViPipe, 0x40b5, 0x00); + os04c10_write_register(ViPipe, 0x40b7, 0x00); + os04c10_write_register(ViPipe, 0x40b8, 0x00); + os04c10_write_register(ViPipe, 0x40b9, 0x00); + os04c10_write_register(ViPipe, 0x40ba, 0x01); + os04c10_write_register(ViPipe, 0x4301, 0x00); + os04c10_write_register(ViPipe, 0x4303, 0x00); + os04c10_write_register(ViPipe, 0x4502, 0x04); + os04c10_write_register(ViPipe, 0x4503, 0x00); + os04c10_write_register(ViPipe, 0x4504, 0x06); + os04c10_write_register(ViPipe, 0x4506, 0x00); + os04c10_write_register(ViPipe, 0x4507, 0x47); + os04c10_write_register(ViPipe, 0x4803, 0x00); + os04c10_write_register(ViPipe, 0x480c, 0x32); + os04c10_write_register(ViPipe, 0x480e, 0x04); + os04c10_write_register(ViPipe, 0x4813, 0xe4); + os04c10_write_register(ViPipe, 0x4819, 0x70); + os04c10_write_register(ViPipe, 0x481f, 0x30); + os04c10_write_register(ViPipe, 0x4823, 0x3f); + os04c10_write_register(ViPipe, 0x4825, 0x30); + os04c10_write_register(ViPipe, 0x4833, 0x10); + os04c10_write_register(ViPipe, 0x484b, 0x27); + os04c10_write_register(ViPipe, 0x488b, 0x00); + os04c10_write_register(ViPipe, 0x4d00, 0x04); + os04c10_write_register(ViPipe, 0x4d01, 0xad); + os04c10_write_register(ViPipe, 0x4d02, 0xbc); + os04c10_write_register(ViPipe, 0x4d03, 0xa1); + os04c10_write_register(ViPipe, 0x4d04, 0x1f); + os04c10_write_register(ViPipe, 0x4d05, 0x4c); + os04c10_write_register(ViPipe, 0x4d0b, 0x01); + os04c10_write_register(ViPipe, 0x4e00, 0x2a); + os04c10_write_register(ViPipe, 0x4e0d, 0x00); + os04c10_write_register(ViPipe, 0x5001, 0x09); + os04c10_write_register(ViPipe, 0x5004, 0x00); + os04c10_write_register(ViPipe, 0x5080, 0x04); + os04c10_write_register(ViPipe, 0x5036, 0x80); + os04c10_write_register(ViPipe, 0x5180, 0x70); + os04c10_write_register(ViPipe, 0x5181, 0x10); + os04c10_write_register(ViPipe, 0x520a, 0x03); + os04c10_write_register(ViPipe, 0x520b, 0x06); + os04c10_write_register(ViPipe, 0x520c, 0x0c); + os04c10_write_register(ViPipe, 0x580b, 0x0f); + os04c10_write_register(ViPipe, 0x580d, 0x00); + os04c10_write_register(ViPipe, 0x580f, 0x00); + os04c10_write_register(ViPipe, 0x5820, 0x00); + os04c10_write_register(ViPipe, 0x5821, 0x00); + os04c10_write_register(ViPipe, 0x301c, 0xf8); + os04c10_write_register(ViPipe, 0x301e, 0xb4); + os04c10_write_register(ViPipe, 0x301f, 0xf0); + os04c10_write_register(ViPipe, 0x3022, 0x01); + os04c10_write_register(ViPipe, 0x3109, 0xe7); + os04c10_write_register(ViPipe, 0x3600, 0x00); + os04c10_write_register(ViPipe, 0x3610, 0x75); + os04c10_write_register(ViPipe, 0x3611, 0x85); + os04c10_write_register(ViPipe, 0x3613, 0x3a); + os04c10_write_register(ViPipe, 0x3615, 0x60); + os04c10_write_register(ViPipe, 0x3621, 0x90); + os04c10_write_register(ViPipe, 0x3620, 0x0c); + os04c10_write_register(ViPipe, 0x3629, 0x00); + os04c10_write_register(ViPipe, 0x3661, 0x04); + os04c10_write_register(ViPipe, 0x3664, 0x70); + os04c10_write_register(ViPipe, 0x3665, 0x00); + os04c10_write_register(ViPipe, 0x3681, 0xa6); + os04c10_write_register(ViPipe, 0x3682, 0x53); + os04c10_write_register(ViPipe, 0x3683, 0x2a); + os04c10_write_register(ViPipe, 0x3684, 0x15); + os04c10_write_register(ViPipe, 0x3700, 0x2a); + os04c10_write_register(ViPipe, 0x3701, 0x12); + os04c10_write_register(ViPipe, 0x3703, 0x28); + os04c10_write_register(ViPipe, 0x3704, 0x0e); + os04c10_write_register(ViPipe, 0x3706, 0x4a); + os04c10_write_register(ViPipe, 0x3709, 0x4a); + os04c10_write_register(ViPipe, 0x370b, 0xa2); + os04c10_write_register(ViPipe, 0x370c, 0x01); + os04c10_write_register(ViPipe, 0x370f, 0x04); + os04c10_write_register(ViPipe, 0x3714, 0x24); + os04c10_write_register(ViPipe, 0x3716, 0x24); + os04c10_write_register(ViPipe, 0x3719, 0x11); + os04c10_write_register(ViPipe, 0x371a, 0x1e); + os04c10_write_register(ViPipe, 0x3720, 0x00); + os04c10_write_register(ViPipe, 0x3724, 0x13); + os04c10_write_register(ViPipe, 0x373f, 0xb0); + os04c10_write_register(ViPipe, 0x3741, 0x4a); + os04c10_write_register(ViPipe, 0x3743, 0x4a); + os04c10_write_register(ViPipe, 0x3745, 0x4a); + os04c10_write_register(ViPipe, 0x3747, 0x4a); + os04c10_write_register(ViPipe, 0x3749, 0xa2); + os04c10_write_register(ViPipe, 0x374b, 0xa2); + os04c10_write_register(ViPipe, 0x374d, 0xa2); + os04c10_write_register(ViPipe, 0x374f, 0xa2); + os04c10_write_register(ViPipe, 0x3755, 0x10); + os04c10_write_register(ViPipe, 0x376c, 0x00); + os04c10_write_register(ViPipe, 0x378d, 0x30); + os04c10_write_register(ViPipe, 0x3790, 0x4a); + os04c10_write_register(ViPipe, 0x3791, 0xa2); + os04c10_write_register(ViPipe, 0x3798, 0x40); + os04c10_write_register(ViPipe, 0x379e, 0x00); + os04c10_write_register(ViPipe, 0x379f, 0x04); + os04c10_write_register(ViPipe, 0x37a1, 0x10); + os04c10_write_register(ViPipe, 0x37a2, 0x1e); + os04c10_write_register(ViPipe, 0x37a8, 0x10); + os04c10_write_register(ViPipe, 0x37a9, 0x1e); + os04c10_write_register(ViPipe, 0x37ac, 0xa0); + os04c10_write_register(ViPipe, 0x37b9, 0x01); + os04c10_write_register(ViPipe, 0x37bd, 0x01); + os04c10_write_register(ViPipe, 0x37bf, 0x26); + os04c10_write_register(ViPipe, 0x37c0, 0x11); + os04c10_write_register(ViPipe, 0x37c2, 0x04); + os04c10_write_register(ViPipe, 0x37cd, 0x19); + os04c10_write_register(ViPipe, 0x37e0, 0x08); + os04c10_write_register(ViPipe, 0x37e6, 0x04); + os04c10_write_register(ViPipe, 0x37e5, 0x02); + os04c10_write_register(ViPipe, 0x37e1, 0x0c); + os04c10_write_register(ViPipe, 0x3737, 0x04); + os04c10_write_register(ViPipe, 0x37d8, 0x02); + os04c10_write_register(ViPipe, 0x37e2, 0x10); + os04c10_write_register(ViPipe, 0x3739, 0x10); + os04c10_write_register(ViPipe, 0x3662, 0x10); + os04c10_write_register(ViPipe, 0x37e4, 0x20); + os04c10_write_register(ViPipe, 0x37e3, 0x08); + os04c10_write_register(ViPipe, 0x37d9, 0x08); + os04c10_write_register(ViPipe, 0x4040, 0x00); + os04c10_write_register(ViPipe, 0x4041, 0x07); + os04c10_write_register(ViPipe, 0x4008, 0x02); + os04c10_write_register(ViPipe, 0x4009, 0x0d); + os04c10_write_register(ViPipe, 0x3800, 0x00); + os04c10_write_register(ViPipe, 0x3801, 0x00); + os04c10_write_register(ViPipe, 0x3802, 0x00); + os04c10_write_register(ViPipe, 0x3803, 0x00); + os04c10_write_register(ViPipe, 0x3804, 0x0a); + os04c10_write_register(ViPipe, 0x3805, 0x8f); + os04c10_write_register(ViPipe, 0x3806, 0x05); + os04c10_write_register(ViPipe, 0x3807, 0xff); + os04c10_write_register(ViPipe, 0x3808, 0x0a); + os04c10_write_register(ViPipe, 0x3809, 0x80); + os04c10_write_register(ViPipe, 0x380a, 0x05); + os04c10_write_register(ViPipe, 0x380b, 0xf0); + os04c10_write_register(ViPipe, 0x380c, 0x04); + os04c10_write_register(ViPipe, 0x380d, 0x2e); + os04c10_write_register(ViPipe, 0x380e, 0x06); + os04c10_write_register(ViPipe, 0x380f, 0x92); + os04c10_write_register(ViPipe, 0x3811, 0x08); + os04c10_write_register(ViPipe, 0x3813, 0x08); + os04c10_write_register(ViPipe, 0x3814, 0x01); + os04c10_write_register(ViPipe, 0x3815, 0x01); + os04c10_write_register(ViPipe, 0x3816, 0x01); + os04c10_write_register(ViPipe, 0x3817, 0x01); + os04c10_write_register(ViPipe, 0x3820, 0x88); + os04c10_write_register(ViPipe, 0x3821, 0x04); + os04c10_write_register(ViPipe, 0x3880, 0x25); + os04c10_write_register(ViPipe, 0x3882, 0x20); + os04c10_write_register(ViPipe, 0x3c91, 0x0b); + os04c10_write_register(ViPipe, 0x3c94, 0x45); + os04c10_write_register(ViPipe, 0x4000, 0xf3); + os04c10_write_register(ViPipe, 0x4001, 0x60); + os04c10_write_register(ViPipe, 0x4003, 0x40); + os04c10_write_register(ViPipe, 0x4300, 0xff); + os04c10_write_register(ViPipe, 0x4302, 0x0f); + os04c10_write_register(ViPipe, 0x4305, 0x83); + os04c10_write_register(ViPipe, 0x4505, 0x84); + os04c10_write_register(ViPipe, 0x4809, 0x0e); + os04c10_write_register(ViPipe, 0x480a, 0x04); + os04c10_write_register(ViPipe, 0x4837, 0x14); + os04c10_write_register(ViPipe, 0x4c00, 0x08); + os04c10_write_register(ViPipe, 0x4c01, 0x08); + os04c10_write_register(ViPipe, 0x4c04, 0x00); + os04c10_write_register(ViPipe, 0x4c05, 0x00); + os04c10_write_register(ViPipe, 0x5000, 0xf9); + os04c10_write_register(ViPipe, 0x3624, 0x00); + os04c10_write_register(ViPipe, 0x3016, 0x32); + os04c10_write_register(ViPipe, 0x0306, 0x00); + os04c10_write_register(ViPipe, 0x4837, 0x0a); + os04c10_write_register(ViPipe, 0x0305, 0x5a); + os04c10_write_register(ViPipe, 0x0325, 0x6b); + os04c10_write_register(ViPipe, 0x3106, 0x25); + /* LCG-LCG */ + os04c10_write_register(ViPipe, 0x320d, 0x00); + os04c10_write_register(ViPipe, 0x3208, 0x00); + os04c10_write_register(ViPipe, 0x3698, 0x00); + os04c10_write_register(ViPipe, 0x3699, 0x80); + os04c10_write_register(ViPipe, 0x369a, 0x80); + os04c10_write_register(ViPipe, 0x369b, 0x1f); + os04c10_write_register(ViPipe, 0x369c, 0x1f); + os04c10_write_register(ViPipe, 0x369d, 0x80); + os04c10_write_register(ViPipe, 0x369e, 0x40); + os04c10_write_register(ViPipe, 0x369f, 0x21); + os04c10_write_register(ViPipe, 0x36a0, 0x12); + os04c10_write_register(ViPipe, 0x36a1, 0xdd); + os04c10_write_register(ViPipe, 0x370e, 0x00); + os04c10_write_register(ViPipe, 0x3713, 0x04); + os04c10_write_register(ViPipe, 0x379c, 0x00); + os04c10_write_register(ViPipe, 0x379d, 0x00); + os04c10_write_register(ViPipe, 0x37be, 0x26); + os04c10_write_register(ViPipe, 0x37c7, 0xa8); + os04c10_write_register(ViPipe, 0x3881, 0x00); + os04c10_write_register(ViPipe, 0x3681, 0x80); + os04c10_write_register(ViPipe, 0x3682, 0x40); + os04c10_write_register(ViPipe, 0x3683, 0x21); + os04c10_write_register(ViPipe, 0x3684, 0x12); + os04c10_write_register(ViPipe, 0x370f, 0x00); + os04c10_write_register(ViPipe, 0x379f, 0x04); + os04c10_write_register(ViPipe, 0x37ac, 0xa0); + os04c10_write_register(ViPipe, 0x37bf, 0x26); + os04c10_write_register(ViPipe, 0x3880, 0x00); + os04c10_write_register(ViPipe, 0x3208, 0x10); + os04c10_write_register(ViPipe, 0x320d, 0x00); + os04c10_write_register(ViPipe, 0x3208, 0xa0); + + os04c10_default_reg_init(ViPipe); + + if (!g_au16Os04c10_UseHwSync[ViPipe]) { + /* freerun */ + os04c10_write_register(ViPipe, 0x3002, 0x21); + } else { + /* auto master */ +#if HW_SYNC_AUTO + os04c10_write_register(ViPipe, 0x3002, 0x22); // [1] vsync_oen, [0]: fsin_oen + os04c10_write_register(ViPipe, 0x3690, 0x00); // [4]: 1'b0, 1st set vsync pulse + os04c10_write_register(ViPipe, 0x383e, 0x00); // vscyn_rise_rcnt_pt[23:16] + os04c10_write_register(ViPipe, 0x3818, 0x00); // Slave vsync pulse position cs [15:8] + os04c10_write_register(ViPipe, 0x3819, 0x00); // Slave vsync pulse position cs [7:0], + // max is HTS/4 + os04c10_write_register(ViPipe, 0x381a, 0x00); // vscyn_rise_rcnt_pt[15:8] + os04c10_write_register(ViPipe, 0x381b, 0x00); // vscyn_rise_rcnt_pt[7:0], max: + // VTS-12 for AHBIN 720p, (VTS -12)*2 for + // other formats + os04c10_write_register(ViPipe, 0x3832, 0xf8); // default, 8'h08, [7:4] vsync pulse width + os04c10_write_register(ViPipe, 0x368a, 0x04); // GPIO enable +#else + /* manual master */ + os04c10_write_register(ViPipe, 0x3002, 0x22); // [1] vsync_oen, [0]: fsin_oen + os04c10_write_register(ViPipe, 0x3690, 0x00); // [4]: 1'b0, 1st set vsync pulse + os04c10_write_register(ViPipe, 0x383e, 0x00); // vscyn_rise_rcnt_pt[23:16] + os04c10_write_register(ViPipe, 0x3818, 0x00); // Slave vsync pulse position cs [15:8] + os04c10_write_register(ViPipe, 0x3819, 0x00); // Slave vsync pulse position cs [7:0], + // max is HTS/4 + os04c10_write_register(ViPipe, 0x381a, 0x00); // vscyn_rise_rcnt_pt[15:8] + os04c10_write_register(ViPipe, 0x381b, 0x18); // vscyn_rise_rcnt_pt[7:0], max: + // VTS-12 for AHBIN 720p, (VTS -12)*2 for + // other formats + os04c10_write_register(ViPipe, 0x3832, 0xf8); // default, 8'h08, [7:4] vsync pulse width + os04c10_write_register(ViPipe, 0x368a, 0x04); // GPIO enable +#endif + } + + os04c10_write_register(ViPipe, 0x0100, 0x01); + + usleep(50*1000); + + printf("===Os04c10 sensor 1520P30fps 10bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} + +static void os04c10_wdr_1440p30_2to1_init(VI_PIPE ViPipe) +{ + os04c10_write_register(ViPipe, 0x0100, 0x00); + os04c10_write_register(ViPipe, 0x0103, 0x01); + os04c10_write_register(ViPipe, 0x0301, 0x84); + os04c10_write_register(ViPipe, 0x0303, 0x01); + os04c10_write_register(ViPipe, 0x0305, 0x61); + os04c10_write_register(ViPipe, 0x0306, 0x01); + os04c10_write_register(ViPipe, 0x0307, 0x17); + os04c10_write_register(ViPipe, 0x0323, 0x04); + os04c10_write_register(ViPipe, 0x0324, 0x01); + os04c10_write_register(ViPipe, 0x0325, 0x7a); + os04c10_write_register(ViPipe, 0x3012, 0x06); + os04c10_write_register(ViPipe, 0x3013, 0x02); + os04c10_write_register(ViPipe, 0x3016, 0x72); + os04c10_write_register(ViPipe, 0x3021, 0x03); + os04c10_write_register(ViPipe, 0x3106, 0x21); + os04c10_write_register(ViPipe, 0x3107, 0xa1); + os04c10_write_register(ViPipe, 0x3500, 0x00); + os04c10_write_register(ViPipe, 0x3501, 0x03); + os04c10_write_register(ViPipe, 0x3502, 0x08); + os04c10_write_register(ViPipe, 0x3503, 0x88); + os04c10_write_register(ViPipe, 0x3508, 0x00); + os04c10_write_register(ViPipe, 0x3509, 0x80); + os04c10_write_register(ViPipe, 0x350a, 0x04); + os04c10_write_register(ViPipe, 0x350b, 0x00); + os04c10_write_register(ViPipe, 0x350c, 0x00); + os04c10_write_register(ViPipe, 0x350d, 0x80); + os04c10_write_register(ViPipe, 0x350e, 0x04); + os04c10_write_register(ViPipe, 0x350f, 0x00); + os04c10_write_register(ViPipe, 0x3510, 0x00); + os04c10_write_register(ViPipe, 0x3511, 0x01); + os04c10_write_register(ViPipe, 0x3512, 0x08); + os04c10_write_register(ViPipe, 0x3624, 0x02); + os04c10_write_register(ViPipe, 0x3625, 0x4c); + os04c10_write_register(ViPipe, 0x3660, 0x04); + os04c10_write_register(ViPipe, 0x3666, 0xa5); + os04c10_write_register(ViPipe, 0x3667, 0xa5); + os04c10_write_register(ViPipe, 0x366a, 0x54); + os04c10_write_register(ViPipe, 0x3673, 0x0d); + os04c10_write_register(ViPipe, 0x3672, 0x0d); + os04c10_write_register(ViPipe, 0x3671, 0x0d); + os04c10_write_register(ViPipe, 0x3670, 0x0d); + os04c10_write_register(ViPipe, 0x3685, 0x00); + os04c10_write_register(ViPipe, 0x3694, 0x0d); + os04c10_write_register(ViPipe, 0x3693, 0x0d); + os04c10_write_register(ViPipe, 0x3692, 0x0d); + os04c10_write_register(ViPipe, 0x3691, 0x0d); + os04c10_write_register(ViPipe, 0x3696, 0x4c); + os04c10_write_register(ViPipe, 0x3697, 0x4c); + os04c10_write_register(ViPipe, 0x3698, 0x40); + os04c10_write_register(ViPipe, 0x3699, 0x80); + os04c10_write_register(ViPipe, 0x369a, 0x18); + os04c10_write_register(ViPipe, 0x369b, 0x1f); + os04c10_write_register(ViPipe, 0x369c, 0x14); + os04c10_write_register(ViPipe, 0x369d, 0x80); + os04c10_write_register(ViPipe, 0x369e, 0x40); + os04c10_write_register(ViPipe, 0x369f, 0x21); + os04c10_write_register(ViPipe, 0x36a0, 0x12); + os04c10_write_register(ViPipe, 0x36a1, 0x5d); + os04c10_write_register(ViPipe, 0x36a2, 0x66); + os04c10_write_register(ViPipe, 0x370a, 0x00); + os04c10_write_register(ViPipe, 0x370e, 0x0c); + os04c10_write_register(ViPipe, 0x3710, 0x00); + os04c10_write_register(ViPipe, 0x3713, 0x00); + os04c10_write_register(ViPipe, 0x3725, 0x02); + os04c10_write_register(ViPipe, 0x372a, 0x03); + os04c10_write_register(ViPipe, 0x3738, 0xce); + os04c10_write_register(ViPipe, 0x3748, 0x00); + os04c10_write_register(ViPipe, 0x374a, 0x00); + os04c10_write_register(ViPipe, 0x374c, 0x00); + os04c10_write_register(ViPipe, 0x374e, 0x00); + os04c10_write_register(ViPipe, 0x3756, 0x00); + os04c10_write_register(ViPipe, 0x3757, 0x00); + os04c10_write_register(ViPipe, 0x3767, 0x00); + os04c10_write_register(ViPipe, 0x3771, 0x00); + os04c10_write_register(ViPipe, 0x377b, 0x28); + os04c10_write_register(ViPipe, 0x377c, 0x00); + os04c10_write_register(ViPipe, 0x377d, 0x0c); + os04c10_write_register(ViPipe, 0x3781, 0x03); + os04c10_write_register(ViPipe, 0x3782, 0x00); + os04c10_write_register(ViPipe, 0x3789, 0x14); + os04c10_write_register(ViPipe, 0x3795, 0x02); + os04c10_write_register(ViPipe, 0x379c, 0x00); + os04c10_write_register(ViPipe, 0x379d, 0x00); + os04c10_write_register(ViPipe, 0x37b8, 0x04); + os04c10_write_register(ViPipe, 0x37ba, 0x03); + os04c10_write_register(ViPipe, 0x37bb, 0x00); + os04c10_write_register(ViPipe, 0x37bc, 0x04); + os04c10_write_register(ViPipe, 0x37be, 0x08); + os04c10_write_register(ViPipe, 0x37c4, 0x11); + os04c10_write_register(ViPipe, 0x37c5, 0x80); + os04c10_write_register(ViPipe, 0x37c6, 0x14); + os04c10_write_register(ViPipe, 0x37c7, 0x08); + os04c10_write_register(ViPipe, 0x37da, 0x11); + os04c10_write_register(ViPipe, 0x381f, 0x08); + os04c10_write_register(ViPipe, 0x3829, 0x03); + os04c10_write_register(ViPipe, 0x3881, 0x00); + os04c10_write_register(ViPipe, 0x3888, 0x04); + os04c10_write_register(ViPipe, 0x388b, 0x00); + os04c10_write_register(ViPipe, 0x3c80, 0x10); + os04c10_write_register(ViPipe, 0x3c86, 0x00); + os04c10_write_register(ViPipe, 0x3c8c, 0x20); + os04c10_write_register(ViPipe, 0x3c9f, 0x01); + os04c10_write_register(ViPipe, 0x3d85, 0x1b); + os04c10_write_register(ViPipe, 0x3d8c, 0x71); + os04c10_write_register(ViPipe, 0x3d8d, 0xe2); + os04c10_write_register(ViPipe, 0x3f00, 0x0b); + os04c10_write_register(ViPipe, 0x3f06, 0x04); + os04c10_write_register(ViPipe, 0x400a, 0x01); + os04c10_write_register(ViPipe, 0x400b, 0x50); + os04c10_write_register(ViPipe, 0x400e, 0x08); + os04c10_write_register(ViPipe, 0x4043, 0x7e); + os04c10_write_register(ViPipe, 0x4045, 0x7e); + os04c10_write_register(ViPipe, 0x4047, 0x7e); + os04c10_write_register(ViPipe, 0x4049, 0x7e); + os04c10_write_register(ViPipe, 0x4090, 0x14); + os04c10_write_register(ViPipe, 0x40b0, 0x00); + os04c10_write_register(ViPipe, 0x40b1, 0x00); + os04c10_write_register(ViPipe, 0x40b2, 0x00); + os04c10_write_register(ViPipe, 0x40b3, 0x00); + os04c10_write_register(ViPipe, 0x40b4, 0x00); + os04c10_write_register(ViPipe, 0x40b5, 0x00); + os04c10_write_register(ViPipe, 0x40b7, 0x00); + os04c10_write_register(ViPipe, 0x40b8, 0x00); + os04c10_write_register(ViPipe, 0x40b9, 0x00); + os04c10_write_register(ViPipe, 0x40ba, 0x01); + os04c10_write_register(ViPipe, 0x4301, 0x00); + os04c10_write_register(ViPipe, 0x4303, 0x00); + os04c10_write_register(ViPipe, 0x4502, 0x04); + os04c10_write_register(ViPipe, 0x4503, 0x00); + os04c10_write_register(ViPipe, 0x4504, 0x06); + os04c10_write_register(ViPipe, 0x4506, 0x00); + os04c10_write_register(ViPipe, 0x4507, 0x47); + os04c10_write_register(ViPipe, 0x4803, 0x00); + os04c10_write_register(ViPipe, 0x480c, 0x32); + os04c10_write_register(ViPipe, 0x480e, 0x04); + os04c10_write_register(ViPipe, 0x4813, 0xe4); + os04c10_write_register(ViPipe, 0x4819, 0x70); + os04c10_write_register(ViPipe, 0x481f, 0x30); + os04c10_write_register(ViPipe, 0x4823, 0x3f); + os04c10_write_register(ViPipe, 0x4825, 0x30); + os04c10_write_register(ViPipe, 0x4833, 0x10); + os04c10_write_register(ViPipe, 0x484b, 0x27); + os04c10_write_register(ViPipe, 0x488b, 0x00); + os04c10_write_register(ViPipe, 0x4d00, 0x04); + os04c10_write_register(ViPipe, 0x4d01, 0xad); + os04c10_write_register(ViPipe, 0x4d02, 0xbc); + os04c10_write_register(ViPipe, 0x4d03, 0xa1); + os04c10_write_register(ViPipe, 0x4d04, 0x1f); + os04c10_write_register(ViPipe, 0x4d05, 0x4c); + os04c10_write_register(ViPipe, 0x4d0b, 0x01); + os04c10_write_register(ViPipe, 0x4e00, 0x2a); + os04c10_write_register(ViPipe, 0x4e0d, 0x00); + os04c10_write_register(ViPipe, 0x5001, 0x09); + os04c10_write_register(ViPipe, 0x5004, 0x00); + os04c10_write_register(ViPipe, 0x5080, 0x04); + os04c10_write_register(ViPipe, 0x5036, 0x80); + os04c10_write_register(ViPipe, 0x5180, 0x70); + os04c10_write_register(ViPipe, 0x5181, 0x10); + os04c10_write_register(ViPipe, 0x520a, 0x03); + os04c10_write_register(ViPipe, 0x520b, 0x06); + os04c10_write_register(ViPipe, 0x520c, 0x0c); + os04c10_write_register(ViPipe, 0x580b, 0x0f); + os04c10_write_register(ViPipe, 0x580d, 0x00); + os04c10_write_register(ViPipe, 0x580f, 0x00); + os04c10_write_register(ViPipe, 0x5820, 0x00); + os04c10_write_register(ViPipe, 0x5821, 0x00); + os04c10_write_register(ViPipe, 0x301c, 0xf8); + os04c10_write_register(ViPipe, 0x301e, 0xb4); + os04c10_write_register(ViPipe, 0x301f, 0xf0); + os04c10_write_register(ViPipe, 0x3022, 0x01); + os04c10_write_register(ViPipe, 0x3109, 0xe7); + os04c10_write_register(ViPipe, 0x3600, 0x00); + os04c10_write_register(ViPipe, 0x3610, 0x75); + os04c10_write_register(ViPipe, 0x3611, 0x85); + os04c10_write_register(ViPipe, 0x3613, 0x3a); + os04c10_write_register(ViPipe, 0x3615, 0x60); + os04c10_write_register(ViPipe, 0x3621, 0x90); + os04c10_write_register(ViPipe, 0x3620, 0x0c); + os04c10_write_register(ViPipe, 0x3629, 0x00); + os04c10_write_register(ViPipe, 0x3661, 0x04); + os04c10_write_register(ViPipe, 0x3664, 0x70); + os04c10_write_register(ViPipe, 0x3665, 0x00); + os04c10_write_register(ViPipe, 0x3681, 0xa6); + os04c10_write_register(ViPipe, 0x3682, 0x53); + os04c10_write_register(ViPipe, 0x3683, 0x2a); + os04c10_write_register(ViPipe, 0x3684, 0x15); + os04c10_write_register(ViPipe, 0x3700, 0x2a); + os04c10_write_register(ViPipe, 0x3701, 0x12); + os04c10_write_register(ViPipe, 0x3703, 0x28); + os04c10_write_register(ViPipe, 0x3704, 0x0e); + os04c10_write_register(ViPipe, 0x3706, 0x4a); + os04c10_write_register(ViPipe, 0x3709, 0x4a); + os04c10_write_register(ViPipe, 0x370b, 0xa2); + os04c10_write_register(ViPipe, 0x370c, 0x01); + os04c10_write_register(ViPipe, 0x370f, 0x04); + os04c10_write_register(ViPipe, 0x3714, 0x24); + os04c10_write_register(ViPipe, 0x3716, 0x24); + os04c10_write_register(ViPipe, 0x3719, 0x11); + os04c10_write_register(ViPipe, 0x371a, 0x1e); + os04c10_write_register(ViPipe, 0x3720, 0x00); + os04c10_write_register(ViPipe, 0x3724, 0x13); + os04c10_write_register(ViPipe, 0x373f, 0xb0); + os04c10_write_register(ViPipe, 0x3741, 0x4a); + os04c10_write_register(ViPipe, 0x3743, 0x4a); + os04c10_write_register(ViPipe, 0x3745, 0x4a); + os04c10_write_register(ViPipe, 0x3747, 0x4a); + os04c10_write_register(ViPipe, 0x3749, 0xa2); + os04c10_write_register(ViPipe, 0x374b, 0xa2); + os04c10_write_register(ViPipe, 0x374d, 0xa2); + os04c10_write_register(ViPipe, 0x374f, 0xa2); + os04c10_write_register(ViPipe, 0x3755, 0x10); + os04c10_write_register(ViPipe, 0x376c, 0x00); + os04c10_write_register(ViPipe, 0x378d, 0x30); + os04c10_write_register(ViPipe, 0x3790, 0x4a); + os04c10_write_register(ViPipe, 0x3791, 0xa2); + os04c10_write_register(ViPipe, 0x3798, 0x40); + os04c10_write_register(ViPipe, 0x379e, 0x00); + os04c10_write_register(ViPipe, 0x379f, 0x04); + os04c10_write_register(ViPipe, 0x37a1, 0x10); + os04c10_write_register(ViPipe, 0x37a2, 0x1e); + os04c10_write_register(ViPipe, 0x37a8, 0x10); + os04c10_write_register(ViPipe, 0x37a9, 0x1e); + os04c10_write_register(ViPipe, 0x37ac, 0xa0); + os04c10_write_register(ViPipe, 0x37b9, 0x01); + os04c10_write_register(ViPipe, 0x37bd, 0x01); + os04c10_write_register(ViPipe, 0x37bf, 0x26); + os04c10_write_register(ViPipe, 0x37c0, 0x11); + os04c10_write_register(ViPipe, 0x37c2, 0x04); + os04c10_write_register(ViPipe, 0x37cd, 0x19); + os04c10_write_register(ViPipe, 0x37e0, 0x08); + os04c10_write_register(ViPipe, 0x37e6, 0x04); + os04c10_write_register(ViPipe, 0x37e5, 0x02); + os04c10_write_register(ViPipe, 0x37e1, 0x0c); + os04c10_write_register(ViPipe, 0x3737, 0x04); + os04c10_write_register(ViPipe, 0x37d8, 0x02); + os04c10_write_register(ViPipe, 0x37e2, 0x10); + os04c10_write_register(ViPipe, 0x3739, 0x10); + os04c10_write_register(ViPipe, 0x3662, 0x10); + os04c10_write_register(ViPipe, 0x37e4, 0x20); + os04c10_write_register(ViPipe, 0x37e3, 0x08); + os04c10_write_register(ViPipe, 0x37d9, 0x08); + os04c10_write_register(ViPipe, 0x4040, 0x00); + os04c10_write_register(ViPipe, 0x4041, 0x07); + os04c10_write_register(ViPipe, 0x4008, 0x02); + os04c10_write_register(ViPipe, 0x4009, 0x0d); + os04c10_write_register(ViPipe, 0x3800, 0x00); + os04c10_write_register(ViPipe, 0x3801, 0x40); + os04c10_write_register(ViPipe, 0x3802, 0x00); + os04c10_write_register(ViPipe, 0x3803, 0x28); + os04c10_write_register(ViPipe, 0x3804, 0x0a); + os04c10_write_register(ViPipe, 0x3805, 0x4f); + os04c10_write_register(ViPipe, 0x3806, 0x05); + os04c10_write_register(ViPipe, 0x3807, 0xd7); + os04c10_write_register(ViPipe, 0x3808, 0x0a); + os04c10_write_register(ViPipe, 0x3809, 0x00); + os04c10_write_register(ViPipe, 0x380a, 0x05); + os04c10_write_register(ViPipe, 0x380b, 0xa0); + os04c10_write_register(ViPipe, 0x380c, 0x04); + os04c10_write_register(ViPipe, 0x380d, 0x2e); + os04c10_write_register(ViPipe, 0x380e, 0x06); + os04c10_write_register(ViPipe, 0x380f, 0x92); + os04c10_write_register(ViPipe, 0x3811, 0x08); + os04c10_write_register(ViPipe, 0x3813, 0x08); + os04c10_write_register(ViPipe, 0x3814, 0x01); + os04c10_write_register(ViPipe, 0x3815, 0x01); + os04c10_write_register(ViPipe, 0x3816, 0x01); + os04c10_write_register(ViPipe, 0x3817, 0x01); + os04c10_write_register(ViPipe, 0x3820, 0x88); + os04c10_write_register(ViPipe, 0x3821, 0x04); + os04c10_write_register(ViPipe, 0x3880, 0x25); + os04c10_write_register(ViPipe, 0x3882, 0x20); + os04c10_write_register(ViPipe, 0x3c91, 0x0b); + os04c10_write_register(ViPipe, 0x3c94, 0x45); + os04c10_write_register(ViPipe, 0x4000, 0xf3); + os04c10_write_register(ViPipe, 0x4001, 0x60); + os04c10_write_register(ViPipe, 0x4003, 0x40); + os04c10_write_register(ViPipe, 0x4300, 0xff); + os04c10_write_register(ViPipe, 0x4302, 0x0f); + os04c10_write_register(ViPipe, 0x4305, 0x83); + os04c10_write_register(ViPipe, 0x4505, 0x84); + os04c10_write_register(ViPipe, 0x4809, 0x0e); + os04c10_write_register(ViPipe, 0x480a, 0x04); + os04c10_write_register(ViPipe, 0x4837, 0x14); + os04c10_write_register(ViPipe, 0x4c00, 0x08); + os04c10_write_register(ViPipe, 0x4c01, 0x08); + os04c10_write_register(ViPipe, 0x4c04, 0x00); + os04c10_write_register(ViPipe, 0x4c05, 0x00); + os04c10_write_register(ViPipe, 0x5000, 0xe9); + os04c10_write_register(ViPipe, 0x3624, 0x00); + os04c10_write_register(ViPipe, 0x3016, 0x32); + os04c10_write_register(ViPipe, 0x0306, 0x00); + os04c10_write_register(ViPipe, 0x4837, 0x0a); + os04c10_write_register(ViPipe, 0x0305, 0x5a); + os04c10_write_register(ViPipe, 0x0325, 0x6b); + os04c10_write_register(ViPipe, 0x3106, 0x25); + os04c10_default_reg_init(ViPipe); + + if (!g_au16Os04c10_UseHwSync[ViPipe]) { + /* freerun */ + os04c10_write_register(ViPipe, 0x3002, 0x21); + } else { + /* auto master */ + os04c10_write_register(ViPipe, 0x3002, 0x22); // [1] vsync_oen, [0]: fsin_oen + os04c10_write_register(ViPipe, 0x3690, 0x00); // [4]: 1'b0, 1st set vsync pulse + os04c10_write_register(ViPipe, 0x383e, 0x00); // vscyn_rise_rcnt_pt[23:16] + os04c10_write_register(ViPipe, 0x3818, 0x00); // Slave vsync pulse position cs [15:8] + os04c10_write_register(ViPipe, 0x3819, 0x00); // Slave vsync pulse position cs [7:0], + // max is HTS/4 + os04c10_write_register(ViPipe, 0x381a, 0x00); // vscyn_rise_rcnt_pt[15:8] + os04c10_write_register(ViPipe, 0x381b, 0x00); // vscyn_rise_rcnt_pt[7:0], max: + // VTS-12 for AHBIN 720p, (VTS -12)*2 for + // other formats + os04c10_write_register(ViPipe, 0x3832, 0xf8); // default, 8'h08, [7:4] vsync pulse width + os04c10_write_register(ViPipe, 0x368a, 0x04); // GPIO enable + } + + os04c10_write_register(ViPipe, 0x0100, 0x01); + + usleep(50*1000); + + printf("===Os04c10 sensor 1440P30fps 10bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} \ No newline at end of file diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_os08a20/Makefile b/middleware/v2/component/isp/sensor/cv181x/ov_os08a20/Makefile new file mode 100644 index 000000000..3a9655ed2 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_os08a20/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_os08a20.a +TARGET_SO = $(MW_LIB)/libsns_os08a20.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_os08a20/os08a20_cmos.c b/middleware/v2/component/isp/sensor/cv181x/ov_os08a20/os08a20_cmos.c new file mode 100644 index 000000000..80e81bee0 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_os08a20/os08a20_cmos.c @@ -0,0 +1,1083 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "os08a20_cmos_ex.h" +#include "os08a20_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define OS08A20_ID 820 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastOs08a20[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define OS08A20_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastOs08a20[dev]) +#define OS08A20_SENSOR_SET_CTX(dev, pstCtx) (g_pastOs08a20[dev] = pstCtx) +#define OS08A20_SENSOR_RESET_CTX(dev) (g_pastOs08a20[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunOs08a20_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Os08a20_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Os08a20_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +OS08A20_STATE_S g_astOs08a20_State[VI_MAX_PIPE_NUM] = {{0} }; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Os08a20 Lines Range*****/ +#define OS08A20_FULL_LINES_MAX (0xFFFF) +#define OS08A20_FULL_LINES_MAX_2TO1_WDR (0xFFFF) + +/*****Os08a20 Register Address*****/ +#define OS08A20_HOLD1_ADDR 0x320D +#define OS08A20_HOLD2_ADDR 0x3208 +#define OS08A20_HOLD3_ADDR 0x0808 +#define OS08A20_EXP1_ADDR 0x3501 +#define OS08A20_EXP2_ADDR 0x3511 +#define OS08A20_AGAIN1_ADDR 0x3508 +#define OS08A20_DGAIN1_ADDR 0x350A +#define OS08A20_AGAIN2_ADDR 0x350C +#define OS08A20_DGAIN2_ADDR 0x350E +#define OS08A20_VTS_ADDR 0x380E +#define OS08A20_TABLE_END 0xffff + +#define OS08A20_RES_IS_1944P(w, h) ((w) <= 2592 && (h) <= 1944) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const OS08A20_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astOs08a20_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = OS08A20_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astOs08a20_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astOs08a20_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astOs08a20_mode[pstSnsState->u8ImgMode].f32MinFps; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OS08A20_FULL_LINES_MAX) ? OS08A20_FULL_LINES_MAX : u32VMAX; + + pstSnsRegsInfo->astI2cData[LINEAR_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_1].u32Data = (u32VMAX & 0xFF); + } else { + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OS08A20_FULL_LINES_MAX_2TO1_WDR) ? OS08A20_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + pstSnsRegsInfo->astI2cData[WDR2_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_VTS_1].u32Data = (u32VMAX & 0xFF); + } + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + /* sanity check for HDR-VC mode */ + if (u32IntTime[0] >= u32IntTime[1]) { + CVI_TRACE_SNS(CVI_DBG_ERR, "shutter : sef %d shall not be greater than sef %d\n", + u32IntTime[0], u32IntTime[1]); + return CVI_FAILURE; + } + if ((u32IntTime[0] + u32IntTime[1]) >= (pstSnsState->au32FL[0] - 4)) { + CVI_TRACE_SNS(CVI_DBG_ERR, "shutter : total shutter %d shall not be greater than %d\n", + u32IntTime[0] + u32IntTime[1], pstSnsState->au32FL[0] - 4); + return CVI_FAILURE; + } + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32IntTime[0]; + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = u32IntTime[1]; + + pstSnsRegsInfo->astI2cData[WDR2_EXP1_0].u32Data = ((pstSnsState->au32WDRIntTime[1] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_EXP1_1].u32Data = (pstSnsState->au32WDRIntTime[1] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_EXP2_0].u32Data = ((pstSnsState->au32WDRIntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_EXP2_1].u32Data = (pstSnsState->au32WDRIntTime[0] & 0xFF); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + pstSnsRegsInfo->astI2cData[LINEAR_EXP_0].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_1].u32Data = (u32IntTime[0] & 0xFF); + } + + return CVI_SUCCESS; + +} + +/* + * GainReg {0x3508, 0x3509} Real Gain + * 0x0080~0x00FF INT(GainReg/8)/16 + * 0x0100~0x01FF INT(GainReg/16)/8 + * 0x0200~0x03FF INT(GainReg/32)/4 + * 0x0400~0x07FF INT(GainReg/64)/2 + */ + +static CVI_U32 gain_table[64] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[63]) { + *pu32AgainLin = gain_table[63]; + *pu32AgainDb = (63 - 48) * 64 + 1024; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + i--; + if (i < 16) + *pu32AgainDb = i * 8 + 128; + else if (i < 32) + *pu32AgainDb = (i - 16) * 16 + 256; + else if (i < 48) + *pu32AgainDb = (i - 32) * 32 + 512; + else + *pu32AgainDb = (i - 48) * 64 + 1024; + + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin <= 1024) { + *pu32DgainLin = 1024; + } else if (*pu32DgainLin > 16383) { + *pu32DgainLin = 16383; + } + *pu32DgainDb = *pu32DgainLin; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0].u32Data = ((u32Again & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_1].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0].u32Data = ((u32Dgain & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1].u32Data = (u32Dgain & 0xFF); + } else { + /* DOL mode */ + u32Again = pu32Again[1]; + u32Dgain = pu32Dgain[1]; + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_0].u32Data = ((u32Again & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_1].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_0].u32Data = ((u32Dgain & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_1].u32Data = (u32Dgain & 0xFF); + + if (g_au16Os08a20_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[1]; + u32Dgain = pu32Dgain[1]; + } else if (g_au16Os08a20_GainMode[ViPipe] == SNS_GAIN_MODE_WDR_2F) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + } else { + return CVI_SUCCESS; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_0].u32Data = ((u32Again & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_1].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_0].u32Data = ((u32Dgain & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_1].u32Data = (u32Dgain & 0xFF); + + } + + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 8 : 8; + /* + * Long exp + Short exp < VTS - 4, choose even number VTS - 6. + */ + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + syslog(LOG_DEBUG, "Max inttime0 = %u\n", u32IntTimeMaxTmp); + + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio is too large!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const OS08A20_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astOs08a20_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == OS08A20_MODE_2592X1944P30_WDR) + pstSnsState->u8ImgMode = OS08A20_MODE_2592X1944P30; + else { + } + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOs08a20_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == OS08A20_MODE_2592X1944P30) { + pstSnsState->u8ImgMode = OS08A20_MODE_2592X1944P30_WDR; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1944p mode(60fps->30fps)\n"); + } else { + } + + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astOs08a20_mode[pstSnsState->u8ImgMode].u32VtsDef; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunOs08a20_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = os08a20_i2c_addr; + pstI2c_data[i].u32AddrByteNum = os08a20_addr_byte; + pstI2c_data[i].u32DataByteNum = os08a20_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[WDR2_HOLD1].u32RegAddr = OS08A20_HOLD1_ADDR; + pstI2c_data[WDR2_HOLD1].u32Data = 0; + pstI2c_data[WDR2_HOLD2].u32RegAddr = OS08A20_HOLD2_ADDR; + pstI2c_data[WDR2_HOLD2].u32Data = 0; + pstI2c_data[WDR2_HOLD3].u32RegAddr = OS08A20_HOLD3_ADDR; + pstI2c_data[WDR2_HOLD3].u32Data = 0; + pstI2c_data[WDR2_EXP1_0].u32RegAddr = OS08A20_EXP1_ADDR; + pstI2c_data[WDR2_EXP1_1].u32RegAddr = OS08A20_EXP1_ADDR + 1; + pstI2c_data[WDR2_EXP2_0].u32RegAddr = OS08A20_EXP2_ADDR; + pstI2c_data[WDR2_EXP2_1].u32RegAddr = OS08A20_EXP2_ADDR + 1; + pstI2c_data[WDR2_AGAIN1_0].u32RegAddr = OS08A20_AGAIN1_ADDR; + pstI2c_data[WDR2_AGAIN1_1].u32RegAddr = OS08A20_AGAIN1_ADDR + 1; + pstI2c_data[WDR2_AGAIN2_0].u32RegAddr = OS08A20_AGAIN2_ADDR; + pstI2c_data[WDR2_AGAIN2_1].u32RegAddr = OS08A20_AGAIN2_ADDR + 1; + pstI2c_data[WDR2_DGAIN1_0].u32RegAddr = OS08A20_DGAIN1_ADDR; + pstI2c_data[WDR2_DGAIN1_1].u32RegAddr = OS08A20_DGAIN1_ADDR + 1; + pstI2c_data[WDR2_DGAIN2_0].u32RegAddr = OS08A20_DGAIN2_ADDR; + pstI2c_data[WDR2_DGAIN2_1].u32RegAddr = OS08A20_DGAIN2_ADDR + 1; + pstI2c_data[WDR2_VTS_0].u32RegAddr = OS08A20_VTS_ADDR; + pstI2c_data[WDR2_VTS_1].u32RegAddr = OS08A20_VTS_ADDR + 1; + pstI2c_data[WDR2_REL1].u32RegAddr = OS08A20_HOLD2_ADDR; + pstI2c_data[WDR2_REL1].u32Data = 0x10; + pstI2c_data[WDR2_REL2].u32RegAddr = OS08A20_HOLD1_ADDR; + pstI2c_data[WDR2_REL2].u32Data = 0x0; + pstI2c_data[WDR2_REL3].u32RegAddr = OS08A20_HOLD2_ADDR; + pstI2c_data[WDR2_REL3].u32Data = 0xE0; + break; + default: + pstI2c_data[LINEAR_HOLD1].u32RegAddr = OS08A20_HOLD1_ADDR; + pstI2c_data[LINEAR_HOLD1].u32Data = 0; + pstI2c_data[LINEAR_HOLD2].u32RegAddr = OS08A20_HOLD2_ADDR; + pstI2c_data[LINEAR_HOLD2].u32Data = 0; + pstI2c_data[LINEAR_HOLD3].u32RegAddr = OS08A20_HOLD3_ADDR; + pstI2c_data[LINEAR_HOLD3].u32Data = 0; + pstI2c_data[LINEAR_EXP_0].u32RegAddr = OS08A20_EXP1_ADDR; + pstI2c_data[LINEAR_EXP_1].u32RegAddr = OS08A20_EXP1_ADDR + 1; + pstI2c_data[LINEAR_AGAIN_0].u32RegAddr = OS08A20_AGAIN1_ADDR; + pstI2c_data[LINEAR_AGAIN_1].u32RegAddr = OS08A20_AGAIN1_ADDR + 1; + pstI2c_data[LINEAR_DGAIN_0].u32RegAddr = OS08A20_DGAIN1_ADDR; + pstI2c_data[LINEAR_DGAIN_1].u32RegAddr = OS08A20_DGAIN1_ADDR + 1; + pstI2c_data[LINEAR_VTS_0].u32RegAddr = OS08A20_VTS_ADDR; + pstI2c_data[LINEAR_VTS_1].u32RegAddr = OS08A20_VTS_ADDR + 1; + pstI2c_data[LINEAR_REL1].u32RegAddr = OS08A20_HOLD2_ADDR; + pstI2c_data[LINEAR_REL1].u32Data = 0x10; + pstI2c_data[LINEAR_REL2].u32RegAddr = OS08A20_HOLD1_ADDR; + pstI2c_data[LINEAR_REL2].u32Data = 0x0; + pstI2c_data[LINEAR_REL3].u32RegAddr = OS08A20_HOLD2_ADDR; + pstI2c_data[LINEAR_REL3].u32Data = 0xE0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[WDR2_HOLD1].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_HOLD2].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_HOLD3].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_REL1].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_REL2].bUpdate = CVI_TRUE; + pstI2c_data[WDR2_REL3].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD1].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_HOLD2].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_HOLD3].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL1].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL2].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL3].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (OS08A20_RES_IS_1944P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OS08A20_MODE_2592X1944P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (OS08A20_RES_IS_1944P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OS08A20_MODE_2592X1944P30_WDR; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = OS08A20_MODE_2592X1944P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOs08a20_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astOs08a20_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astOs08a20_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OS08A20_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &os08a20_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astOs08a20_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astOs08a20_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &os08a20_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = os08a20_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = os08a20_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 os08a20_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunOs08a20_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OS08A20_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + OS08A20_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OS08A20_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + OS08A20_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = OS08A20_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, OS08A20_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, OS08A20_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, OS08A20_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Os08a20_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Os08a20_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsOs08a20_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = os08a20_standby, + .pfnRestart = os08a20_restart, + .pfnMirrorFlip = CVI_NULL, + .pfnWriteReg = os08a20_write_register, + .pfnReadReg = os08a20_read_register, + .pfnSetBusInfo = os08a20_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_os08a20/os08a20_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/ov_os08a20/os08a20_cmos_ex.h new file mode 100644 index 000000000..ce48bf901 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_os08a20/os08a20_cmos_ex.h @@ -0,0 +1,116 @@ +#ifndef __OS08A20_CMOS_EX_H_ +#define __OS08A20_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum os08a20_linear_regs_e { + LINEAR_HOLD1 = 0, + LINEAR_HOLD2, + LINEAR_HOLD3, + LINEAR_EXP_0, + LINEAR_EXP_1, + LINEAR_AGAIN_0, + LINEAR_AGAIN_1, + LINEAR_DGAIN_0, + LINEAR_DGAIN_1, + LINEAR_VTS_0, + LINEAR_VTS_1, + LINEAR_REL1, + LINEAR_REL2, + LINEAR_REL3, + LINEAR_REGS_NUM +}; + +enum os08a20_wdr2_regs_e { + WDR2_HOLD1 = 0, + WDR2_HOLD2, + WDR2_HOLD3, + WDR2_EXP1_0, + WDR2_EXP1_1, + WDR2_EXP2_0, + WDR2_EXP2_1, + WDR2_AGAIN1_0, + WDR2_AGAIN1_1, + WDR2_AGAIN2_0, + WDR2_AGAIN2_1, + WDR2_DGAIN1_0, + WDR2_DGAIN1_1, + WDR2_DGAIN2_0, + WDR2_DGAIN2_1, + WDR2_VTS_0, + WDR2_VTS_1, + WDR2_REL1, + WDR2_REL2, + WDR2_REL3, + WDR2_REGS_NUM +}; + +typedef enum _OS08A20_MODE_E { + OS08A20_MODE_2592X1944P30 = 0, + OS08A20_MODE_LINEAR_NUM, + OS08A20_MODE_2592X1944P30_WDR = OS08A20_MODE_LINEAR_NUM, + OS08A20_MODE_NUM +} OS08A20_MODE_E; + +typedef struct _OS08A20_STATE_S { + CVI_U32 u32Sexp_MAX; +} OS08A20_STATE_S; + +typedef struct _OS08A20_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + CVI_U16 u16L2sOffset; + CVI_U16 u16TopBoundary; + CVI_U16 u16BotBoundary; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U32 u32L2S_MAX; + char name[64]; +} OS08A20_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastOs08a20[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunOs08a20_BusInfo[]; +extern CVI_U16 g_au16Os08a20_GainMode[]; +extern CVI_U16 g_au16Os08a20_L2SMode[VI_MAX_PIPE_NUM]; +extern const CVI_U8 os08a20_i2c_addr; +extern const CVI_U32 os08a20_addr_byte; +extern const CVI_U32 os08a20_data_byte; +extern void os08a20_init(VI_PIPE ViPipe); +extern void os08a20_exit(VI_PIPE ViPipe); +extern void os08a20_standby(VI_PIPE ViPipe); +extern void os08a20_restart(VI_PIPE ViPipe); +extern int os08a20_write_register(VI_PIPE ViPipe, int addr, int data); +extern int os08a20_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OS08A20_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_os08a20/os08a20_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/ov_os08a20/os08a20_cmos_param.h new file mode 100644 index 000000000..692e7313c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_os08a20/os08a20_cmos_param.h @@ -0,0 +1,300 @@ +#ifndef __OS08A20_CMOS_PARAM_H_ +#define __OS08A20_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "os08a20_cmos_ex.h" + +static const OS08A20_MODE_S g_astOs08a20_mode[OS08A20_MODE_NUM] = { + [OS08A20_MODE_2592X1944P30] = { + .name = "2592x1944p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2592, + .u32Height = 1944, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2592, + .u32Height = 1944, + }, + .stMaxSize = { + .u32Width = 2592, + .u32Height = 1944, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.06, /* 0x90a * 30 / 0xFFFF */ + .u32HtsDef = 0x818, + .u32VtsDef = 0x90a, + .stExp[0] = { + .u16Min = 8, + .u16Max = 0x90a - 8, + .u16Def = 0x462, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 16383, + .u16Def = 1024, + .u16Step = 1, + }, + }, + [OS08A20_MODE_2592X1944P30_WDR] = { + .name = "2592x1944p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2592, + .u32Height = 1944, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2592, + .u32Height = 1944, + }, + .stMaxSize = { + .u32Width = 2592, + .u32Height = 1944, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 2592, + .u32Height = 1944, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2592, + .u32Height = 1944, + }, + .stMaxSize = { + .u32Width = 2592, + .u32Height = 1944, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.08, /* 0x92a * 30 / 0xFFFF */ + .u32HtsDef = 0x40c, + .u32VtsDef = 0x92a, + .u16L2sOffset = 4, + .u16TopBoundary = 36, + .u16BotBoundary = 8, + .stExp[0] = { + .u16Min = 8, + .u16Max = 312, + .u16Def = 100, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 8, + .u16Max = 0x486 - 4 - 312, + .u16Def = 500, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 16383, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 16383, + .u16Def = 1024, + .u16Step = 1, + }, + .u32L2S_MAX = 0x13D, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.03190412744879722595, 3.86617159843444824219}, //B: slope, intercept + {0.02441397681832313538, 4.87663412094116210938}, //Gb: slope, intercept + {0.02471913769841194153, 4.85860157012939453125}, //Gr: slope, intercept + {0.02652409672737121582, 4.48996973037719726563}, //R: slope, intercept + }, + { //iso 200 + {0.04349273815751075745, 5.49785566329956054688}, //B: slope, intercept + {0.03087714128196239471, 7.49881792068481445313}, //Gb: slope, intercept + {0.03145518898963928223, 7.35760211944580078125}, //Gr: slope, intercept + {0.03530855849385261536, 6.56339693069458007813}, //R: slope, intercept + }, + { //iso 400 + {0.05788951739668846130, 8.34851074218750000000}, //B: slope, intercept + {0.04015926644206047058, 11.21226787567138671875}, //Gb: slope, intercept + {0.04018958285450935364, 11.29319286346435546875}, //Gr: slope, intercept + {0.04840981587767601013, 9.35622310638427734375}, //R: slope, intercept + }, + { //iso 800 + {0.08085585385560989380, 11.91084861755371093750}, //B: slope, intercept + {0.05333026498556137085, 16.38746833801269531250}, //Gb: slope, intercept + {0.05413141101598739624, 16.21148872375488281250}, //Gr: slope, intercept + {0.06530260294675827026, 13.91790008544921875000}, //R: slope, intercept + }, + { //iso 1600 + {0.09407941251993179321, 17.58893775939941406250}, //B: slope, intercept + {0.05309880897402763367, 24.13221168518066406250}, //Gb: slope, intercept + {0.05440055206418037415, 23.84361267089843750000}, //Gr: slope, intercept + {0.06805266439914703369, 20.56119728088378906250}, //R: slope, intercept + }, + { //iso 3200 + {0.09407941251993179321, 17.58893775939941406250}, //B: slope, intercept + {0.05309880897402763367, 24.13221168518066406250}, //Gb: slope, intercept + {0.05440055206418037415, 23.84361267089843750000}, //Gr: slope, intercept + {0.06805266439914703369, 20.56119728088378906250}, //R: slope, intercept + }, + { //iso 6400 + {0.09407941251993179321, 17.58893775939941406250}, //B: slope, intercept + {0.05309880897402763367, 24.13221168518066406250}, //Gb: slope, intercept + {0.05440055206418037415, 23.84361267089843750000}, //Gr: slope, intercept + {0.06805266439914703369, 20.56119728088378906250}, //R: slope, intercept + }, + { //iso 12800 + {0.09407941251993179321, 17.58893775939941406250}, //B: slope, intercept + {0.05309880897402763367, 24.13221168518066406250}, //Gb: slope, intercept + {0.05440055206418037415, 23.84361267089843750000}, //Gr: slope, intercept + {0.06805266439914703369, 20.56119728088378906250}, //R: slope, intercept + }, + { //iso 25600 + {0.48950406908988952637, 67.73629760742187500000}, //B: slope, intercept + {0.25487670302391052246, 101.95156860351562500000}, //Gb: slope, intercept + {0.24315287172794342041, 105.36353302001953125000}, //Gr: slope, intercept + {0.33707463741302490234, 86.65032958984375000000}, //R: slope, intercept + }, + { //iso 51200 + {0.48950406908988952637, 67.73629760742187500000}, //B: slope, intercept + {0.25487670302391052246, 101.95156860351562500000}, //Gb: slope, intercept + {0.24315287172794342041, 105.36353302001953125000}, //Gr: slope, intercept + {0.33707463741302490234, 86.65032958984375000000}, //R: slope, intercept + }, + { //iso 102400 + {0.48950406908988952637, 67.73629760742187500000}, //B: slope, intercept + {0.25487670302391052246, 101.95156860351562500000}, //Gb: slope, intercept + {0.24315287172794342041, 105.36353302001953125000}, //Gr: slope, intercept + {0.33707463741302490234, 86.65032958984375000000}, //R: slope, intercept + }, + { //iso 204800 + {0.48950406908988952637, 67.73629760742187500000}, //B: slope, intercept + {0.25487670302391052246, 101.95156860351562500000}, //Gb: slope, intercept + {0.24315287172794342041, 105.36353302001953125000}, //Gr: slope, intercept + {0.33707463741302490234, 86.65032958984375000000}, //R: slope, intercept + }, + { //iso 409600 + {0.48950406908988952637, 67.73629760742187500000}, //B: slope, intercept + {0.25487670302391052246, 101.95156860351562500000}, //Gb: slope, intercept + {0.24315287172794342041, 105.36353302001953125000}, //Gr: slope, intercept + {0.33707463741302490234, 86.65032958984375000000}, //R: slope, intercept + }, + { //iso 819200 + {0.48950406908988952637, 67.73629760742187500000}, //B: slope, intercept + {0.25487670302391052246, 101.95156860351562500000}, //Gb: slope, intercept + {0.24315287172794342041, 105.36353302001953125000}, //Gr: slope, intercept + {0.33707463741302490234, 86.65032958984375000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.48950406908988952637, 67.73629760742187500000}, //B: slope, intercept + {0.25487670302391052246, 101.95156860351562500000}, //Gb: slope, intercept + {0.24315287172794342041, 105.36353302001953125000}, //Gr: slope, intercept + {0.33707463741302490234, 86.65032958984375000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.48950406908988952637, 67.73629760742187500000}, //B: slope, intercept + {0.25487670302391052246, 101.95156860351562500000}, //Gb: slope, intercept + {0.24315287172794342041, 105.36353302001953125000}, //Gr: slope, intercept + {0.33707463741302490234, 86.65032958984375000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, +#endif + }, + }, +}; + +struct combo_dev_attr_s os08a20_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_600M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {3, 2, 1, 4, 0}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_25M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OS08A20_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_os08a20/os08a20_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/ov_os08a20/os08a20_sensor_ctl.c new file mode 100644 index 000000000..f9bfe49c6 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_os08a20/os08a20_sensor_ctl.c @@ -0,0 +1,585 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "os08a20_cmos_ex.h" + +static void os08a20_wdr_1944p30_2to1_init(VI_PIPE ViPipe); +static void os08a20_linear_1944p30_init(VI_PIPE ViPipe); + +const CVI_U8 os08a20_i2c_addr = 0x36; /* I2C Address of OS08A20 */ +const CVI_U32 os08a20_addr_byte = 2; +const CVI_U32 os08a20_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int os08a20_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunOs08a20_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, os08a20_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int os08a20_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int os08a20_read_register(VI_PIPE ViPipe, int addr) +{ + /* TODO:*/ + (void) ViPipe; + (void) addr; + + return CVI_SUCCESS; +} + + +int os08a20_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (os08a20_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (os08a20_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, os08a20_addr_byte + os08a20_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void os08a20_standby(VI_PIPE ViPipe) +{ + os08a20_write_register(ViPipe, 0x0100, 0x00); /* STANDBY */ +} + +void os08a20_restart(VI_PIPE ViPipe) +{ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ +} + +void os08a20_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + /* by pass the group hold and clear registers since it won't update when stream is off. */ + for (i = 3; i < g_pastOs08a20[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum - 3; i++) { + os08a20_write_register(ViPipe, + g_pastOs08a20[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastOs08a20[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void os08a20_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastOs08a20[ViPipe]->enWDRMode; + u8ImgMode = g_pastOs08a20[ViPipe]->u8ImgMode; + + os08a20_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == OS08A20_MODE_2592X1944P30_WDR) + os08a20_wdr_1944p30_2to1_init(ViPipe); + else { + } + } else { + if (u8ImgMode == OS08A20_MODE_2592X1944P30) + os08a20_linear_1944p30_init(ViPipe); + else { + } + } + g_pastOs08a20[ViPipe]->bInit = CVI_TRUE; +} + +void os08a20_exit(VI_PIPE ViPipe) +{ + os08a20_i2c_exit(ViPipe); +} + +/* 1944P30 and 1944P25 */ +static void os08a20_linear_1944p30_init(VI_PIPE ViPipe) +{ + os08a20_write_register(ViPipe, 0x0100, 0x00); + os08a20_write_register(ViPipe, 0x0103, 0x01); + os08a20_write_register(ViPipe, 0x0303, 0x01); + os08a20_write_register(ViPipe, 0x0305, 0x5a); + os08a20_write_register(ViPipe, 0x0306, 0x00); + os08a20_write_register(ViPipe, 0x0308, 0x03); + os08a20_write_register(ViPipe, 0x0309, 0x04); + os08a20_write_register(ViPipe, 0x032a, 0x00); + os08a20_write_register(ViPipe, 0x300f, 0x11); + os08a20_write_register(ViPipe, 0x3010, 0x01); + os08a20_write_register(ViPipe, 0x3011, 0x04); + os08a20_write_register(ViPipe, 0x3012, 0x41); + os08a20_write_register(ViPipe, 0x3016, 0xf0); + os08a20_write_register(ViPipe, 0x301e, 0x98); + os08a20_write_register(ViPipe, 0x3031, 0xa9); + os08a20_write_register(ViPipe, 0x3103, 0x92); + os08a20_write_register(ViPipe, 0x3104, 0x01); + os08a20_write_register(ViPipe, 0x3106, 0x10); + os08a20_write_register(ViPipe, 0x3400, 0x04); + os08a20_write_register(ViPipe, 0x3025, 0x03); + os08a20_write_register(ViPipe, 0x3425, 0x01); + os08a20_write_register(ViPipe, 0x3428, 0x01); + os08a20_write_register(ViPipe, 0x3406, 0x08); + os08a20_write_register(ViPipe, 0x3408, 0x03); + os08a20_write_register(ViPipe, 0x340c, 0xff); + os08a20_write_register(ViPipe, 0x340d, 0xff); + os08a20_write_register(ViPipe, 0x031e, 0x09); + os08a20_write_register(ViPipe, 0x3501, 0x08); + os08a20_write_register(ViPipe, 0x3502, 0xe5); + os08a20_write_register(ViPipe, 0x3505, 0x83); + os08a20_write_register(ViPipe, 0x3508, 0x00); + os08a20_write_register(ViPipe, 0x3509, 0x80); + os08a20_write_register(ViPipe, 0x350a, 0x04); + os08a20_write_register(ViPipe, 0x350b, 0x00); + os08a20_write_register(ViPipe, 0x350c, 0x00); + os08a20_write_register(ViPipe, 0x350d, 0x80); + os08a20_write_register(ViPipe, 0x350e, 0x04); + os08a20_write_register(ViPipe, 0x350f, 0x00); + os08a20_write_register(ViPipe, 0x3600, 0x00); + os08a20_write_register(ViPipe, 0x3603, 0x2c); + os08a20_write_register(ViPipe, 0x3605, 0x50); + os08a20_write_register(ViPipe, 0x3609, 0xb5); + os08a20_write_register(ViPipe, 0x3610, 0x39); + os08a20_write_register(ViPipe, 0x360c, 0x01); + os08a20_write_register(ViPipe, 0x3628, 0xa4); + os08a20_write_register(ViPipe, 0x362d, 0x10); + os08a20_write_register(ViPipe, 0x3660, 0x43); + os08a20_write_register(ViPipe, 0x3661, 0x06); + os08a20_write_register(ViPipe, 0x3662, 0x00); + os08a20_write_register(ViPipe, 0x3663, 0x28); + os08a20_write_register(ViPipe, 0x3664, 0x0d); + os08a20_write_register(ViPipe, 0x366a, 0x38); + os08a20_write_register(ViPipe, 0x366b, 0xa0); + os08a20_write_register(ViPipe, 0x366d, 0x00); + os08a20_write_register(ViPipe, 0x366e, 0x00); + os08a20_write_register(ViPipe, 0x3680, 0x00); + os08a20_write_register(ViPipe, 0x36c0, 0x00); + os08a20_write_register(ViPipe, 0x3701, 0x02); + os08a20_write_register(ViPipe, 0x373b, 0x02); + os08a20_write_register(ViPipe, 0x373c, 0x02); + os08a20_write_register(ViPipe, 0x3736, 0x02); + os08a20_write_register(ViPipe, 0x3737, 0x02); + os08a20_write_register(ViPipe, 0x3705, 0x00); + os08a20_write_register(ViPipe, 0x3706, 0x39); + os08a20_write_register(ViPipe, 0x370a, 0x00); + os08a20_write_register(ViPipe, 0x370b, 0x98); + os08a20_write_register(ViPipe, 0x3709, 0x49); + os08a20_write_register(ViPipe, 0x3714, 0x21); + os08a20_write_register(ViPipe, 0x371c, 0x00); + os08a20_write_register(ViPipe, 0x371d, 0x08); + os08a20_write_register(ViPipe, 0x3740, 0x1b); + os08a20_write_register(ViPipe, 0x3741, 0x04); + os08a20_write_register(ViPipe, 0x375e, 0x0b); + os08a20_write_register(ViPipe, 0x3760, 0x10); + os08a20_write_register(ViPipe, 0x3776, 0x10); + os08a20_write_register(ViPipe, 0x3781, 0x02); + os08a20_write_register(ViPipe, 0x3782, 0x04); + os08a20_write_register(ViPipe, 0x3783, 0x02); + os08a20_write_register(ViPipe, 0x3784, 0x08); + os08a20_write_register(ViPipe, 0x3785, 0x08); + os08a20_write_register(ViPipe, 0x3788, 0x01); + os08a20_write_register(ViPipe, 0x3789, 0x01); + os08a20_write_register(ViPipe, 0x3797, 0x04); + os08a20_write_register(ViPipe, 0x3762, 0x11); + os08a20_write_register(ViPipe, 0x3800, 0x00); + os08a20_write_register(ViPipe, 0x3801, 0x00); + os08a20_write_register(ViPipe, 0x3802, 0x00); + os08a20_write_register(ViPipe, 0x3803, 0x0c); + os08a20_write_register(ViPipe, 0x3804, 0x0e); + os08a20_write_register(ViPipe, 0x3805, 0xff); + os08a20_write_register(ViPipe, 0x3806, 0x08); + os08a20_write_register(ViPipe, 0x3807, 0x6f); + os08a20_write_register(ViPipe, 0x3808, 0x0f); + os08a20_write_register(ViPipe, 0x3809, 0x00); + os08a20_write_register(ViPipe, 0x380a, 0x08); + os08a20_write_register(ViPipe, 0x380b, 0x70); + os08a20_write_register(ViPipe, 0x380c, 0x04); + os08a20_write_register(ViPipe, 0x380d, 0x0c); + os08a20_write_register(ViPipe, 0x380e, 0x09); + os08a20_write_register(ViPipe, 0x380f, 0x0a); + os08a20_write_register(ViPipe, 0x3813, 0x10); + os08a20_write_register(ViPipe, 0x3814, 0x01); + os08a20_write_register(ViPipe, 0x3815, 0x01); + os08a20_write_register(ViPipe, 0x3816, 0x01); + os08a20_write_register(ViPipe, 0x3817, 0x01); + os08a20_write_register(ViPipe, 0x381c, 0x00); + os08a20_write_register(ViPipe, 0x3820, 0x00); + os08a20_write_register(ViPipe, 0x3821, 0x04); + os08a20_write_register(ViPipe, 0x3823, 0x08); + os08a20_write_register(ViPipe, 0x3826, 0x00); + os08a20_write_register(ViPipe, 0x3827, 0x08); + os08a20_write_register(ViPipe, 0x382d, 0x08); + os08a20_write_register(ViPipe, 0x3832, 0x02); + os08a20_write_register(ViPipe, 0x3833, 0x00); + os08a20_write_register(ViPipe, 0x383c, 0x48); + os08a20_write_register(ViPipe, 0x383d, 0xff); + os08a20_write_register(ViPipe, 0x3d85, 0x0b); + os08a20_write_register(ViPipe, 0x3d84, 0x40); + os08a20_write_register(ViPipe, 0x3d8c, 0x63); + os08a20_write_register(ViPipe, 0x3d8d, 0xd7); + os08a20_write_register(ViPipe, 0x4000, 0xf8); + os08a20_write_register(ViPipe, 0x4001, 0x2b); + os08a20_write_register(ViPipe, 0x4004, 0x00); + os08a20_write_register(ViPipe, 0x4005, 0x40); + os08a20_write_register(ViPipe, 0x400a, 0x01); + os08a20_write_register(ViPipe, 0x400f, 0xa0); + os08a20_write_register(ViPipe, 0x4010, 0x12); + os08a20_write_register(ViPipe, 0x4018, 0x00); + os08a20_write_register(ViPipe, 0x4008, 0x02); + os08a20_write_register(ViPipe, 0x4009, 0x0d); + os08a20_write_register(ViPipe, 0x401a, 0x58); + os08a20_write_register(ViPipe, 0x4050, 0x00); + os08a20_write_register(ViPipe, 0x4051, 0x01); + os08a20_write_register(ViPipe, 0x4028, 0x2f); + os08a20_write_register(ViPipe, 0x4052, 0x00); + os08a20_write_register(ViPipe, 0x4053, 0x80); + os08a20_write_register(ViPipe, 0x4054, 0x00); + os08a20_write_register(ViPipe, 0x4055, 0x80); + os08a20_write_register(ViPipe, 0x4056, 0x00); + os08a20_write_register(ViPipe, 0x4057, 0x80); + os08a20_write_register(ViPipe, 0x4058, 0x00); + os08a20_write_register(ViPipe, 0x4059, 0x80); + os08a20_write_register(ViPipe, 0x430b, 0xff); + os08a20_write_register(ViPipe, 0x430c, 0xff); + os08a20_write_register(ViPipe, 0x430d, 0x00); + os08a20_write_register(ViPipe, 0x430e, 0x00); + os08a20_write_register(ViPipe, 0x4501, 0x18); + os08a20_write_register(ViPipe, 0x4502, 0x00); + os08a20_write_register(ViPipe, 0x4643, 0x00); + os08a20_write_register(ViPipe, 0x4640, 0x01); + os08a20_write_register(ViPipe, 0x4641, 0x04); + os08a20_write_register(ViPipe, 0x4800, 0x64); + os08a20_write_register(ViPipe, 0x4809, 0x2b); + os08a20_write_register(ViPipe, 0x4813, 0x90); + os08a20_write_register(ViPipe, 0x4817, 0x04); + os08a20_write_register(ViPipe, 0x4833, 0x18); + os08a20_write_register(ViPipe, 0x4837, 0x0b); + os08a20_write_register(ViPipe, 0x483b, 0x00); + os08a20_write_register(ViPipe, 0x484b, 0x03); + os08a20_write_register(ViPipe, 0x4850, 0x7c); + os08a20_write_register(ViPipe, 0x4852, 0x06); + os08a20_write_register(ViPipe, 0x4856, 0x58); + os08a20_write_register(ViPipe, 0x4857, 0xaa); + os08a20_write_register(ViPipe, 0x4862, 0x0a); + os08a20_write_register(ViPipe, 0x4869, 0x18); + os08a20_write_register(ViPipe, 0x486a, 0xaa); + os08a20_write_register(ViPipe, 0x486e, 0x03); + os08a20_write_register(ViPipe, 0x486f, 0x55); + os08a20_write_register(ViPipe, 0x4875, 0xf0); + os08a20_write_register(ViPipe, 0x5000, 0x89); + os08a20_write_register(ViPipe, 0x5001, 0x42); + os08a20_write_register(ViPipe, 0x5004, 0x40); + os08a20_write_register(ViPipe, 0x5005, 0x00); + os08a20_write_register(ViPipe, 0x5180, 0x00); + os08a20_write_register(ViPipe, 0x5181, 0x10); + os08a20_write_register(ViPipe, 0x580b, 0x03); + os08a20_write_register(ViPipe, 0x4d00, 0x03); + os08a20_write_register(ViPipe, 0x4d01, 0xc9); + os08a20_write_register(ViPipe, 0x4d02, 0xbc); + os08a20_write_register(ViPipe, 0x4d03, 0xc6); + os08a20_write_register(ViPipe, 0x4d04, 0x4a); + os08a20_write_register(ViPipe, 0x4d05, 0x25); + os08a20_write_register(ViPipe, 0x4700, 0x2b); + os08a20_write_register(ViPipe, 0x4e00, 0x2b); + os08a20_write_register(ViPipe, 0x3501, 0x09); + os08a20_write_register(ViPipe, 0x3502, 0x01); + os08a20_write_register(ViPipe, 0x0305, 0x57); + os08a20_write_register(ViPipe, 0x380c, 0x08); + os08a20_write_register(ViPipe, 0x380d, 0x18); + os08a20_write_register(ViPipe, 0x380e, 0x09); + os08a20_write_register(ViPipe, 0x380f, 0x0a); + os08a20_write_register(ViPipe, 0x3501, 0x09); + os08a20_write_register(ViPipe, 0x3502, 0x02); + os08a20_write_register(ViPipe, 0x3808, 0x0a); + os08a20_write_register(ViPipe, 0x3809, 0x20); + os08a20_write_register(ViPipe, 0x380a, 0x07); + os08a20_write_register(ViPipe, 0x380b, 0x98); + + os08a20_default_reg_init(ViPipe); + + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + + delay_ms(50); + + printf("ViPipe:%d,===OS08A20 1944P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +static void os08a20_wdr_1944p30_2to1_init(VI_PIPE ViPipe) +{ + os08a20_write_register(ViPipe, 0x0100, 0x00); + os08a20_write_register(ViPipe, 0x0103, 0x01); + os08a20_write_register(ViPipe, 0x0303, 0x01); + os08a20_write_register(ViPipe, 0x0305, 0x5a); + os08a20_write_register(ViPipe, 0x0306, 0x00); + os08a20_write_register(ViPipe, 0x0308, 0x03); + os08a20_write_register(ViPipe, 0x0309, 0x04); + os08a20_write_register(ViPipe, 0x032a, 0x00); + os08a20_write_register(ViPipe, 0x300f, 0x11); + os08a20_write_register(ViPipe, 0x3010, 0x01); + os08a20_write_register(ViPipe, 0x3011, 0x04); + os08a20_write_register(ViPipe, 0x3012, 0x41); + os08a20_write_register(ViPipe, 0x3016, 0xf0); + os08a20_write_register(ViPipe, 0x301e, 0x98); + os08a20_write_register(ViPipe, 0x3031, 0xa9); + os08a20_write_register(ViPipe, 0x3103, 0x92); + os08a20_write_register(ViPipe, 0x3104, 0x01); + os08a20_write_register(ViPipe, 0x3106, 0x10); + os08a20_write_register(ViPipe, 0x340c, 0xff); + os08a20_write_register(ViPipe, 0x340d, 0xff); + os08a20_write_register(ViPipe, 0x031e, 0x09); + os08a20_write_register(ViPipe, 0x3501, 0x08); + os08a20_write_register(ViPipe, 0x3502, 0xe5); + os08a20_write_register(ViPipe, 0x3505, 0x83); + os08a20_write_register(ViPipe, 0x3508, 0x00); + os08a20_write_register(ViPipe, 0x3509, 0x80); + os08a20_write_register(ViPipe, 0x350a, 0x04); + os08a20_write_register(ViPipe, 0x350b, 0x00); + os08a20_write_register(ViPipe, 0x350c, 0x00); + os08a20_write_register(ViPipe, 0x350d, 0x80); + os08a20_write_register(ViPipe, 0x350e, 0x04); + os08a20_write_register(ViPipe, 0x350f, 0x00); + os08a20_write_register(ViPipe, 0x3600, 0x00); + os08a20_write_register(ViPipe, 0x3603, 0x2c); + os08a20_write_register(ViPipe, 0x3605, 0x50); + os08a20_write_register(ViPipe, 0x3609, 0xb5); + os08a20_write_register(ViPipe, 0x3610, 0x39); + os08a20_write_register(ViPipe, 0x360c, 0x01); + os08a20_write_register(ViPipe, 0x3628, 0xa4); + os08a20_write_register(ViPipe, 0x362d, 0x10); + os08a20_write_register(ViPipe, 0x3660, 0x42); + os08a20_write_register(ViPipe, 0x3661, 0x07); + os08a20_write_register(ViPipe, 0x3662, 0x00); + os08a20_write_register(ViPipe, 0x3663, 0x28); + os08a20_write_register(ViPipe, 0x3664, 0x0d); + os08a20_write_register(ViPipe, 0x366a, 0x38); + os08a20_write_register(ViPipe, 0x366b, 0xa0); + os08a20_write_register(ViPipe, 0x366d, 0x00); + os08a20_write_register(ViPipe, 0x366e, 0x00); + os08a20_write_register(ViPipe, 0x3680, 0x00); + os08a20_write_register(ViPipe, 0x36c0, 0x00); + os08a20_write_register(ViPipe, 0x3701, 0x02); + os08a20_write_register(ViPipe, 0x373b, 0x02); + os08a20_write_register(ViPipe, 0x373c, 0x02); + os08a20_write_register(ViPipe, 0x3736, 0x02); + os08a20_write_register(ViPipe, 0x3737, 0x02); + os08a20_write_register(ViPipe, 0x3705, 0x00); + os08a20_write_register(ViPipe, 0x3706, 0x39); + os08a20_write_register(ViPipe, 0x370a, 0x00); + os08a20_write_register(ViPipe, 0x370b, 0x98); + os08a20_write_register(ViPipe, 0x3709, 0x49); + os08a20_write_register(ViPipe, 0x3714, 0x21); + os08a20_write_register(ViPipe, 0x371c, 0x00); + os08a20_write_register(ViPipe, 0x371d, 0x08); + os08a20_write_register(ViPipe, 0x3740, 0x1b); + os08a20_write_register(ViPipe, 0x3741, 0x04); + os08a20_write_register(ViPipe, 0x375e, 0x0b); + os08a20_write_register(ViPipe, 0x3760, 0x10); + os08a20_write_register(ViPipe, 0x3776, 0x10); + os08a20_write_register(ViPipe, 0x3781, 0x02); + os08a20_write_register(ViPipe, 0x3782, 0x04); + os08a20_write_register(ViPipe, 0x3783, 0x02); + os08a20_write_register(ViPipe, 0x3784, 0x08); + os08a20_write_register(ViPipe, 0x3785, 0x08); + os08a20_write_register(ViPipe, 0x3788, 0x01); + os08a20_write_register(ViPipe, 0x3789, 0x01); + os08a20_write_register(ViPipe, 0x3797, 0x04); + os08a20_write_register(ViPipe, 0x3762, 0x11); + os08a20_write_register(ViPipe, 0x3800, 0x00); + os08a20_write_register(ViPipe, 0x3801, 0x00); + os08a20_write_register(ViPipe, 0x3802, 0x00); + os08a20_write_register(ViPipe, 0x3803, 0x0c); + os08a20_write_register(ViPipe, 0x3804, 0x0e); + os08a20_write_register(ViPipe, 0x3805, 0xff); + os08a20_write_register(ViPipe, 0x3806, 0x08); + os08a20_write_register(ViPipe, 0x3807, 0x6f); + os08a20_write_register(ViPipe, 0x3808, 0x0a); + os08a20_write_register(ViPipe, 0x3809, 0x20); + os08a20_write_register(ViPipe, 0x380a, 0x07); + os08a20_write_register(ViPipe, 0x380b, 0x98); + os08a20_write_register(ViPipe, 0x380c, 0x04); + os08a20_write_register(ViPipe, 0x380d, 0x0c); + os08a20_write_register(ViPipe, 0x380e, 0x09); + os08a20_write_register(ViPipe, 0x380f, 0x0a); + os08a20_write_register(ViPipe, 0x3813, 0x10); + os08a20_write_register(ViPipe, 0x3814, 0x01); + os08a20_write_register(ViPipe, 0x3815, 0x01); + os08a20_write_register(ViPipe, 0x3816, 0x01); + os08a20_write_register(ViPipe, 0x3817, 0x01); + os08a20_write_register(ViPipe, 0x381c, 0x08); + os08a20_write_register(ViPipe, 0x3820, 0x00); + os08a20_write_register(ViPipe, 0x3821, 0x24); + os08a20_write_register(ViPipe, 0x3823, 0x08); + os08a20_write_register(ViPipe, 0x3826, 0x00); + os08a20_write_register(ViPipe, 0x3827, 0x08); + os08a20_write_register(ViPipe, 0x382d, 0x08); + os08a20_write_register(ViPipe, 0x3832, 0x02); + os08a20_write_register(ViPipe, 0x3833, 0x01); + os08a20_write_register(ViPipe, 0x383c, 0x48); + os08a20_write_register(ViPipe, 0x383d, 0xff); + os08a20_write_register(ViPipe, 0x3d85, 0x0b); + os08a20_write_register(ViPipe, 0x3d84, 0x40); + os08a20_write_register(ViPipe, 0x3d8c, 0x63); + os08a20_write_register(ViPipe, 0x3d8d, 0xd7); + os08a20_write_register(ViPipe, 0x4000, 0xf8); + os08a20_write_register(ViPipe, 0x4001, 0x2b); + os08a20_write_register(ViPipe, 0x4004, 0x00); + os08a20_write_register(ViPipe, 0x4005, 0x40); + os08a20_write_register(ViPipe, 0x400a, 0x01); + os08a20_write_register(ViPipe, 0x400f, 0xa0); + os08a20_write_register(ViPipe, 0x4010, 0x12); + os08a20_write_register(ViPipe, 0x4018, 0x00); + os08a20_write_register(ViPipe, 0x4008, 0x02); + os08a20_write_register(ViPipe, 0x4009, 0x0d); + os08a20_write_register(ViPipe, 0x401a, 0x58); + os08a20_write_register(ViPipe, 0x4050, 0x00); + os08a20_write_register(ViPipe, 0x4051, 0x01); + os08a20_write_register(ViPipe, 0x4028, 0x2f); + os08a20_write_register(ViPipe, 0x4052, 0x00); + os08a20_write_register(ViPipe, 0x4053, 0x80); + os08a20_write_register(ViPipe, 0x4054, 0x00); + os08a20_write_register(ViPipe, 0x4055, 0x80); + os08a20_write_register(ViPipe, 0x4056, 0x00); + os08a20_write_register(ViPipe, 0x4057, 0x80); + os08a20_write_register(ViPipe, 0x4058, 0x00); + os08a20_write_register(ViPipe, 0x4059, 0x80); + os08a20_write_register(ViPipe, 0x430b, 0xff); + os08a20_write_register(ViPipe, 0x430c, 0xff); + os08a20_write_register(ViPipe, 0x430d, 0x00); + os08a20_write_register(ViPipe, 0x430e, 0x00); + os08a20_write_register(ViPipe, 0x4501, 0x18); + os08a20_write_register(ViPipe, 0x4502, 0x00); + os08a20_write_register(ViPipe, 0x4643, 0x00); + os08a20_write_register(ViPipe, 0x4640, 0x01); + os08a20_write_register(ViPipe, 0x4641, 0x04); + os08a20_write_register(ViPipe, 0x4800, 0x64); + os08a20_write_register(ViPipe, 0x4809, 0x2b); + os08a20_write_register(ViPipe, 0x4813, 0x98); + os08a20_write_register(ViPipe, 0x4817, 0x04); + os08a20_write_register(ViPipe, 0x4833, 0x18); + os08a20_write_register(ViPipe, 0x4837, 0x0b); + os08a20_write_register(ViPipe, 0x483b, 0x00); + os08a20_write_register(ViPipe, 0x484b, 0x03); + os08a20_write_register(ViPipe, 0x4850, 0x7c); + os08a20_write_register(ViPipe, 0x4852, 0x06); + os08a20_write_register(ViPipe, 0x4856, 0x58); + os08a20_write_register(ViPipe, 0x4857, 0xaa); + os08a20_write_register(ViPipe, 0x4862, 0x0a); + os08a20_write_register(ViPipe, 0x4869, 0x18); + os08a20_write_register(ViPipe, 0x486a, 0xaa); + os08a20_write_register(ViPipe, 0x486e, 0x07); + os08a20_write_register(ViPipe, 0x486f, 0x55); + os08a20_write_register(ViPipe, 0x4875, 0xf0); + os08a20_write_register(ViPipe, 0x5000, 0x89); + os08a20_write_register(ViPipe, 0x5001, 0x42); + os08a20_write_register(ViPipe, 0x5004, 0x40); + os08a20_write_register(ViPipe, 0x5005, 0x00); + os08a20_write_register(ViPipe, 0x5180, 0x00); + os08a20_write_register(ViPipe, 0x5181, 0x10); + os08a20_write_register(ViPipe, 0x580b, 0x03); + os08a20_write_register(ViPipe, 0x4d00, 0x03); + os08a20_write_register(ViPipe, 0x4d01, 0xc9); + os08a20_write_register(ViPipe, 0x4d02, 0xbc); + os08a20_write_register(ViPipe, 0x4d03, 0xc6); + os08a20_write_register(ViPipe, 0x4d04, 0x4a); + os08a20_write_register(ViPipe, 0x4d05, 0x25); + os08a20_write_register(ViPipe, 0x4700, 0x2b); + os08a20_write_register(ViPipe, 0x4e00, 0x2b); + os08a20_write_register(ViPipe, 0x3501, 0x08); + os08a20_write_register(ViPipe, 0x3502, 0xe1); + os08a20_write_register(ViPipe, 0x3511, 0x00); + os08a20_write_register(ViPipe, 0x3512, 0x20); + os08a20_write_register(ViPipe, 0x3833, 0x01); + os08a20_write_register(ViPipe, 0x0305, 0x57); + os08a20_write_register(ViPipe, 0x0325, 0x46); + os08a20_write_register(ViPipe, 0x380e, 0x09); + os08a20_write_register(ViPipe, 0x380f, 0x2a); + os08a20_write_register(ViPipe, 0x4028, 0x4f); + os08a20_write_register(ViPipe, 0x4029, 0x1f); + os08a20_write_register(ViPipe, 0x402a, 0x7f); + os08a20_write_register(ViPipe, 0x402b, 0x01); + + os08a20_default_reg_init(ViPipe); + + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + os08a20_write_register(ViPipe, 0x0100, 0x01); /* standby */ + + delay_ms(50); + + printf("===Os08a20 sensor 1944P30fps 10bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} + diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_ov4689/Makefile b/middleware/v2/component/isp/sensor/cv181x/ov_ov4689/Makefile new file mode 100644 index 000000000..b492c96f8 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_ov4689/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_ov4689.a +TARGET_SO = $(MW_LIB)/libsns_ov4689.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_ov4689/ov4689_cmos.c b/middleware/v2/component/isp/sensor/cv181x/ov_ov4689/ov4689_cmos.c new file mode 100644 index 000000000..2cba827c7 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_ov4689/ov4689_cmos.c @@ -0,0 +1,1034 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "ov4689_cmos_ex.h" +#include "ov4689_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define OV4689_ID 0x530243 +#define OV4689_I2C_ADDR_1 0x36 +#define OV4689_I2C_ADDR_2 0x10 +#define OV4689_I2C_ADDR_IS_VALID(addr) \ + ((addr) == OV4689_I2C_ADDR_1 || (addr) == OV4689_I2C_ADDR_2) +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastOv4689[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define OV4689_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastOv4689[dev]) +#define OV4689_SENSOR_SET_CTX(dev, pstCtx) (g_pastOv4689[dev] = pstCtx) +#define OV4689_SENSOR_RESET_CTX(dev) (g_pastOv4689[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunOv4689_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Ov4689_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Ov4689_UseHwSync[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeOv4689_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Ov4689 Lines Range*****/ +#define OV4689_FULL_LINES_MAX (0xFFFF) + +/*****Ov4689 Register Address*****/ +#define OV4689_HOLD_3208 0x3208 +#define OV4689_HOLD_320B 0x320B +#define OV4689_EXP1_ADDR 0x3500 +#define OV4689_AGAIN1_ADDR 0x3507 +#define OV4689_DGAIN1_ADDR 0x352A +#define OV4689_VTS_ADDR 0x380E +#define OV4689_TABLE_END 0xffff + +#define OV4689_RES_IS_1520P(w, h) ((w) == 2688 && (h) == 1520) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const OV4689_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astOv4689_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = OV4689_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + /* OV sensor cannot update new setting before the old setting takes effect */ + pstAeSnsDft->u8AERunInterval = 1; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astOv4689_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astOv4689_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astOv4689_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case OV4689_MODE_2688X1520P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OV4689_FULL_LINES_MAX) ? OV4689_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_1].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 4 + * max : vts - 4 + * step : 1 + */ + CVI_U32 u32TmpIntTime = u32IntTime[0]; + CVI_U32 mimExp = 4; + CVI_U32 maxExp = pstSnsState->au32FL[0] - 4; + + u32TmpIntTime = (u32TmpIntTime > maxExp) ? maxExp : u32TmpIntTime; + u32TmpIntTime = (u32TmpIntTime < mimExp) ? mimExp : u32TmpIntTime; + u32IntTime[0] = u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_0].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_1].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_2].u32Data = ((u32TmpIntTime & 0x000F) << 4); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +typedef struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} gain_tbl_info_s; + +static struct gain_tbl_info_s AgainInfo[15] = { + { + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 8, + }, + { + .gainMax = 3008, + .idxBase = 16, + .regGain = 0x01, + .regGainFineBase = 0x78, + .regGainFineStep = 4, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x01, + .regGainFineBase = 0xb8, + .regGainFineStep = 4, + }, + { + .gainMax = 5056, + .idxBase = 48, + .regGain = 0x03, + .regGainFineBase = 0x74, + .regGainFineStep = 2, + }, + { + .gainMax = 6080, + .idxBase = 64, + .regGain = 0x03, + .regGainFineBase = 0x94, + .regGainFineStep = 2, + }, + { + .gainMax = 7104, + .idxBase = 80, + .regGain = 0x03, + .regGainFineBase = 0xb4, + .regGainFineStep = 2, + }, + { + .gainMax = 8128, + .idxBase = 96, + .regGain = 0x03, + .regGainFineBase = 0xd4, + .regGainFineStep = 2, + }, + { + .gainMax = 9152, + .idxBase = 112, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + }, + { + .gainMax = 10176, + .idxBase = 120, + .regGain = 0x07, + .regGainFineBase = 0x88, + .regGainFineStep = 1, + }, + { + .gainMax = 11200, + .idxBase = 136, + .regGain = 0x07, + .regGainFineBase = 0x98, + .regGainFineStep = 1, + }, + { + .gainMax = 12224, + .idxBase = 152, + .regGain = 0x07, + .regGainFineBase = 0xa8, + .regGainFineStep = 1, + }, + { + .gainMax = 13248, + .idxBase = 168, + .regGain = 0x07, + .regGainFineBase = 0xb8, + .regGainFineStep = 1, + }, + { + .gainMax = 14272, + .idxBase = 184, + .regGain = 0x07, + .regGainFineBase = 0xc8, + .regGainFineStep = 1, + }, + { + .gainMax = 15296, + .idxBase = 200, + .regGain = 0x07, + .regGainFineBase = 0xd8, + .regGainFineStep = 1, + }, + { + .gainMax = 16320, + .idxBase = 216, + .regGain = 0x07, + .regGainFineBase = 0xe8, + .regGainFineStep = 1, + }, + +}; + +static CVI_U32 Again_table[] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, 1856, 1920, + 1984, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, + 2944, 3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, + 3904, 3968, 4032, 4096, 4160, 4224, 4288, 4352, 4416, 4480, 4544, 4608, 4672, 4736, 4800, + 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, 5504, 5568, 5632, 5696, 5760, + 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, 6464, 6528, 6592, 6656, 6720, + 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, 7424, 7488, 7552, 7616, 7680, + 7744, 7808, 7872, 7936, 8000, 8064, 8128, 8704, 8768, 8832, 8896, 8960, 9024, 9088, 9152, + 9216, 9280, 9344, 9408, 9472, 9536, 9600, 9664, 9728, 9792, 9856, 9920, 9984, 10048, 10112, + 10176, 10240, 10304, 10368, 10432, 10496, 10560, 10624, 10688, 10752, 10816, 10880, 10944, + 11008, 11072, 11136, 11200, 11264, 11328, 11392, 11456, 11520, 11584, 11648, 11712, 11776, + 11840, 11904, 11968, 12032, 12096, 12160, 12224, 12288, 12352, 12416, 12480, 12544, 12608, + 12672, 12736, 12800, 12864, 12928, 12992, 13056, 13120, 13184, 13248, 13312, 13376, 13440, + 13504, 13568, 13632, 13696, 13760, 13824, 13888, 13952, 14016, 14080, 14144, 14208, 14272, + 14336, 14400, 14464, 14528, 14592, 14656, 14720, 14784, 14848, 14912, 14976, 15040, 15104, + 15168, 15232, 15296, 15360, 15424, 15488, 15552, 15616, 15680, 15744, 15808, 15872, 15936, + 16000, 16064, 16128, 16192, 16256, 16320 +}; + +static CVI_U32 Dgain_table[] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, 1856, 1920, + 1984, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, + 2944, 3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, + 3904, 3968, 4032, 4096, 4160, 4224, 4288, 4352, 4416, 4480, 4544, 4608, 4672, 4736, 4800, + 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, 5504, 5568, 5632, 5696, 5760, + 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, 6464, 6528, 6592, 6656, 6720, + 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, 7424, 7488, 7552, 7616, 7680, + 7744, 7808, 7872, 7936, 8000, 8064, 8128, 8192, 8256, 8320, 8384, 8448, 8512, 8576, 8640, + 8704, 8768, 8832, 8896, 8960, 9024, 9088, 9152, 9216, 9280, 9344, 9408, 9472, 9536, 9600, + 9664, 9728, 9792, 9856, 9920, 9984, 10048, 10112, 10176, 10240, 10304, 10368, 10432, 10496, + 10560, 10624, 10688, 10752, 10816, 10880, 10944, 11008, 11072, 11136, 11200, 11264, 11328, + 11392, 11456, 11520, 11584, 11648, 11712, 11776, 11840, 11904, 11968, 12032, 12096, 12160, + 12224, 12288, 12352, 12416, 12480, 12544, 12608, 12672, 12736, 12800, 12864, 12928, 12992, + 13056, 13120, 13184, 13248, 13312, 13376, 13440, 13504, 13568, 13632, 13696, 13760, 13824, + 13888, 13952, 14016, 14080, 14144, 14208, 14272, 14336, 14400, 14464, 14528, 14592, 14656, + 14720, 14784, 14848, 14912, 14976, 15040, 15104, 15168, 15232, 15296, 15360, 15424, 15488, + 15552, 15616, 15680, 15744, 15808, 15872, 15936, 16000, 16064, 16128, 16192, 16256, 16320 +}; + +static const CVI_U32 again_table_size = ARRAY_SIZE(Again_table); +static const CVI_U32 dgain_table_size = ARRAY_SIZE(Dgain_table); + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[again_table_size - 1]) { + *pu32AgainLin = Again_table[again_table_size - 1]; + *pu32AgainDb = again_table_size - 1; + return CVI_SUCCESS; + } + + for (i = 1; i < again_table_size; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[dgain_table_size - 1]) { + *pu32DgainLin = Dgain_table[dgain_table_size - 1]; + *pu32DgainDb = dgain_table_size - 1; + return CVI_SUCCESS; + } + + for (i = 1; i < dgain_table_size; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u32Again = pu32Again[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0].u32Data = 0; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_1].u32Data = info->regGain & 0xFF; + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_2].u32Data = u32Again & 0xFF; + + /* find Dgain register setting. */ + u32Dgain = Dgain_table[pu32Dgain[0]] * 2; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0].u32Data = (u32Dgain & 0xFF00) >> 8; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1].u32Data = u32Dgain & 0xFF; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const OV4689_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astOv4689_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = OV4689_MODE_2688X1520P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOv4689_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunOv4689_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = ov4689_i2c_addr; + pstI2c_data[i].u32AddrByteNum = ov4689_addr_byte; + pstI2c_data[i].u32DataByteNum = ov4689_data_byte; + } + + switch (pstSnsState->enWDRMode) { + default: + pstI2c_data[LINEAR_HOLD_START].u32RegAddr = OV4689_HOLD_3208; + pstI2c_data[LINEAR_HOLD_START].u32Data = 0x00; + pstI2c_data[LINEAR_EXP_0].u32RegAddr = OV4689_EXP1_ADDR; + pstI2c_data[LINEAR_EXP_1].u32RegAddr = OV4689_EXP1_ADDR + 1; + pstI2c_data[LINEAR_EXP_2].u32RegAddr = OV4689_EXP1_ADDR + 2; + pstI2c_data[LINEAR_AGAIN_0].u32RegAddr = OV4689_AGAIN1_ADDR; + pstI2c_data[LINEAR_AGAIN_1].u32RegAddr = OV4689_AGAIN1_ADDR + 1; + pstI2c_data[LINEAR_AGAIN_2].u32RegAddr = OV4689_AGAIN1_ADDR + 2; + pstI2c_data[LINEAR_DGAIN_0].u32RegAddr = OV4689_DGAIN1_ADDR; + pstI2c_data[LINEAR_DGAIN_1].u32RegAddr = OV4689_DGAIN1_ADDR + 1; + pstI2c_data[LINEAR_VTS_0].u32RegAddr = OV4689_VTS_ADDR; + pstI2c_data[LINEAR_VTS_1].u32RegAddr = OV4689_VTS_ADDR + 1; + pstI2c_data[LINEAR_HOLD_END].u32RegAddr = OV4689_HOLD_3208; + pstI2c_data[LINEAR_HOLD_END].u32Data = 0x10; + pstI2c_data[LINEAR_LAUNCH_0].u32RegAddr = OV4689_HOLD_320B; + pstI2c_data[LINEAR_LAUNCH_0].u32Data = 0x00; + pstI2c_data[LINEAR_LAUNCH_0].u8DelayFrmNum = 0; + pstI2c_data[LINEAR_LAUNCH_1].u32RegAddr = OV4689_HOLD_3208; + pstI2c_data[LINEAR_LAUNCH_1].u32Data = 0xE0; + pstI2c_data[LINEAR_LAUNCH_1].u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + pstI2c_data[LINEAR_HOLD_START].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_HOLD_END].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_LAUNCH_0].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_LAUNCH_1].bUpdate = CVI_TRUE; + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (OV4689_RES_IS_1520P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OV4689_MODE_2688X1520P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeOv4689_MirrorFip[ViPipe] != eSnsMirrorFlip) { + ov4689_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeOv4689_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = OV4689_MODE_2688X1520P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOv4689_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astOv4689_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astOv4689_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV4689_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &ov4689_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astOv4689_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astOv4689_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &ov4689_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = ov4689_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = ov4689_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (OV4689_I2C_ADDR_IS_VALID(s32I2cAddr)) + ov4689_i2c_addr = s32I2cAddr; +} + +static CVI_S32 ov4689_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunOv4689_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OV4689_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + OV4689_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OV4689_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + OV4689_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = OV4689_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, OV4689_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, OV4689_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, OV4689_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Ov4689_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Ov4689_UseHwSync[ViPipe] = pstInitAttr->u16UseHwSync; + + return CVI_SUCCESS; +} +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return ov4689_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsOv4689_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = ov4689_standby, + .pfnRestart = ov4689_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = ov4689_write_register, + .pfnReadReg = ov4689_read_register, + .pfnSetBusInfo = ov4689_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_ov4689/ov4689_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/ov_ov4689/ov4689_cmos_ex.h new file mode 100644 index 000000000..cbbf6dc17 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_ov4689/ov4689_cmos_ex.h @@ -0,0 +1,95 @@ +#ifndef __OV4689_CMOS_EX_H_ +#define __OV4689_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum ov4689_linear_regs_e { + LINEAR_HOLD_START = 0, + LINEAR_EXP_0, + LINEAR_EXP_1, + LINEAR_EXP_2, + LINEAR_AGAIN_0, + LINEAR_AGAIN_1, + LINEAR_AGAIN_2, + LINEAR_DGAIN_0, + LINEAR_DGAIN_1, + LINEAR_VTS_0, + LINEAR_VTS_1, + LINEAR_HOLD_END, + LINEAR_LAUNCH_0, + LINEAR_LAUNCH_1, + LINEAR_REGS_NUM +}; + +typedef enum _OV4689_MODE_E { + OV4689_MODE_2688X1520P30 = 0, + OV4689_MODE_LINEAR_NUM, + OV4689_MODE_NUM +} OV4689_MODE_E; + +typedef struct _OV4689_STATE_S { + CVI_U32 u32Sexp_MAX; +} OV4689_STATE_S; + +typedef struct _OV4689_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + CVI_U16 u16L2sOffset; + CVI_U16 u16TopBoundary; + CVI_U16 u16BotBoundary; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + CVI_U32 u32L2S_offset; + CVI_U32 u32IspResTime; + CVI_U32 u32HdrMargin; + char name[64]; +} OV4689_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastOv4689[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunOv4689_BusInfo[]; +extern CVI_U16 g_au16Ov4689_GainMode[]; +extern CVI_U16 g_au16Ov4689_UseHwSync[VI_MAX_PIPE_NUM]; +extern CVI_U8 ov4689_i2c_addr; +extern const CVI_U32 ov4689_addr_byte; +extern const CVI_U32 ov4689_data_byte; +extern void ov4689_init(VI_PIPE ViPipe); +extern void ov4689_exit(VI_PIPE ViPipe); +extern void ov4689_standby(VI_PIPE ViPipe); +extern void ov4689_restart(VI_PIPE ViPipe); +extern int ov4689_write_register(VI_PIPE ViPipe, int addr, int data); +extern int ov4689_read_register(VI_PIPE ViPipe, int addr); +extern void ov4689_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int ov4689_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OV4689_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_ov4689/ov4689_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/ov_ov4689/ov4689_cmos_param.h new file mode 100644 index 000000000..d8c6c1bdb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_ov4689/ov4689_cmos_param.h @@ -0,0 +1,124 @@ +#ifndef __OV4689_CMOS_PARAM_H_ +#define __OV4689_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "ov4689_cmos_ex.h" + +static const OV4689_MODE_S g_astOv4689_mode[OV4689_MODE_NUM] = { + [OV4689_MODE_2688X1520P30] = { + .name = "2688x1520p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2688, + .u32Height = 1520, + }, + .stMaxSize = { + .u32Width = 2688, + .u32Height = 1520, + }, + }, + + .f32MaxFps = 30, + .f32MinFps = 0.711, /* 0x4e2 * 30 / 0xFFFF */ + .u32HtsDef = 2584, + .u32VtsDef = 1554, + .stExp[0] = { + .u16Min = 4, + .u16Max = 1554 - 4, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 16320, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16320, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {60, 60, 60, 60, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1039, 1039, 1039, 1039 +#endif + }, + .stAuto = { + {60, 60, 60, 60, 60, 60, 60, 60, /*8*/60, 60, 60, 60, 60, 60, 60, 60}, + {60, 60, 60, 60, 60, 60, 60, 60, /*8*/60, 60, 60, 60, 60, 60, 60, 60}, + {60, 60, 60, 60, 60, 60, 60, 60, /*8*/60, 60, 60, 60, 60, 60, 60, 60}, + {60, 60, 60, 60, 60, 60, 60, 60, /*8*/60, 60, 60, 60, 60, 60, 60, 60}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, + /*8*/1039, 1039, 1039, 1039, 1204, 1039, 1039, 1039}, + {1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, + /*8*/1039, 1039, 1039, 1039, 1204, 1039, 1039, 1039}, + {1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, + /*8*/1039, 1039, 1039, 1039, 1204, 1039, 1039, 1039}, + {1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, + /*8*/1039, 1039, 1039, 1039, 1204, 1039, 1039, 1039}, +#endif + }, + }, +}; + + +struct combo_dev_attr_s ov4689_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_400M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {0, 1, 2, -1, -1}, + .pn_swap = {0, 0, 0, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OV4689_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_ov4689/ov4689_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/ov_ov4689/ov4689_sensor_ctl.c new file mode 100644 index 000000000..ca9479135 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_ov4689/ov4689_sensor_ctl.c @@ -0,0 +1,509 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "ov4689_cmos_ex.h" + +static void ov4689_linear_1520p30_init(VI_PIPE ViPipe); + +CVI_U8 ov4689_i2c_addr = 0x36; /* I2C Address of OV4689 */ +const CVI_U32 ov4689_addr_byte = 2; +const CVI_U32 ov4689_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int ov4689_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunOv4689_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, ov4689_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int ov4689_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int ov4689_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (ov4689_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, ov4689_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, ov4689_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (ov4689_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + + return data; +} + +int ov4689_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (ov4689_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (ov4689_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, ov4689_addr_byte + ov4689_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void ov4689_standby(VI_PIPE ViPipe) +{ + ov4689_write_register(ViPipe, 0x0100, 0x00); /* STANDBY */ +} + +void ov4689_restart(VI_PIPE ViPipe) +{ + ov4689_write_register(ViPipe, 0x0100, 0x01); /* standby */ +} + +void ov4689_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + CVI_U32 start = 1; + CVI_U32 end = g_pastOv4689[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum - 3; + + for (i = start; i < end; i++) { + ov4689_write_register(ViPipe, + g_pastOv4689[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastOv4689[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define OV4689_FLIP 0x3820 +#define OV4689_MIRROR 0x3821 +void ov4689_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 flip, mirror; + + flip = ov4689_read_register(ViPipe, OV4689_FLIP); + mirror = ov4689_read_register(ViPipe, OV4689_MIRROR); + flip &= ~(0x3 << 1); + mirror &= ~(0x3 << 1); + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + mirror |= 0x3 << 1; + break; + case ISP_SNS_FLIP: + flip |= 0x3 << 1; + break; + case ISP_SNS_MIRROR_FLIP: + flip |= 0x3 << 1; + mirror |= 0x3 << 1; + break; + default: + return; + } + + ov4689_write_register(ViPipe, OV4689_FLIP, flip); + ov4689_write_register(ViPipe, OV4689_MIRROR, mirror); +} + +#define OV4689_CHIP_ID_ADDR_H 0x300A +#define OV4689_CHIP_ID_ADDR_L 0x300B +#define OV4689_CHIP_ID 0x4688 + +int ov4689_probe(VI_PIPE ViPipe) +{ + int nVal, nVal2; + + usleep(1000); + if (ov4689_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = ov4689_read_register(ViPipe, OV4689_CHIP_ID_ADDR_H); + nVal2 = ov4689_read_register(ViPipe, OV4689_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != OV4689_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + return CVI_SUCCESS; +} + +void ov4689_init(VI_PIPE ViPipe) +{ + ov4689_i2c_init(ViPipe); + + delay_ms(10); + + ov4689_linear_1520p30_init(ViPipe); + + g_pastOv4689[ViPipe]->bInit = CVI_TRUE; +} + +void ov4689_exit(VI_PIPE ViPipe) +{ + ov4689_i2c_exit(ViPipe); +} + +/* 1080P30 */ +static void ov4689_linear_1520p30_init(VI_PIPE ViPipe) +{ + ov4689_write_register(ViPipe, 0x0103, 0x01); + ov4689_write_register(ViPipe, 0x3638, 0x00); + ov4689_write_register(ViPipe, 0x0300, 0x00); + ov4689_write_register(ViPipe, 0x0302, 0x2a); + ov4689_write_register(ViPipe, 0x0303, 0x00); + ov4689_write_register(ViPipe, 0x0304, 0x03); + ov4689_write_register(ViPipe, 0x030b, 0x00); + ov4689_write_register(ViPipe, 0x030d, 0x1e); + ov4689_write_register(ViPipe, 0x030e, 0x04); + ov4689_write_register(ViPipe, 0x030f, 0x01); + ov4689_write_register(ViPipe, 0x0312, 0x01); + ov4689_write_register(ViPipe, 0x031e, 0x00); + ov4689_write_register(ViPipe, 0x3000, 0x20); + ov4689_write_register(ViPipe, 0x3002, 0x00); + ov4689_write_register(ViPipe, 0x3018, 0x32); + ov4689_write_register(ViPipe, 0x3020, 0x93); + ov4689_write_register(ViPipe, 0x3021, 0x03); + ov4689_write_register(ViPipe, 0x3022, 0x01); + ov4689_write_register(ViPipe, 0x3031, 0x0a); + ov4689_write_register(ViPipe, 0x303f, 0x0c); + ov4689_write_register(ViPipe, 0x3305, 0xf1); + ov4689_write_register(ViPipe, 0x3307, 0x04); + ov4689_write_register(ViPipe, 0x3309, 0x29); + ov4689_write_register(ViPipe, 0x3500, 0x00); + ov4689_write_register(ViPipe, 0x3501, 0x60); + ov4689_write_register(ViPipe, 0x3502, 0x00); + ov4689_write_register(ViPipe, 0x3503, 0x04); + ov4689_write_register(ViPipe, 0x3504, 0x00); + ov4689_write_register(ViPipe, 0x3505, 0x00); + ov4689_write_register(ViPipe, 0x3506, 0x00); + ov4689_write_register(ViPipe, 0x3507, 0x00); + ov4689_write_register(ViPipe, 0x3508, 0x00); + ov4689_write_register(ViPipe, 0x3509, 0x80); + ov4689_write_register(ViPipe, 0x350a, 0x00); + ov4689_write_register(ViPipe, 0x350b, 0x00); + ov4689_write_register(ViPipe, 0x350c, 0x00); + ov4689_write_register(ViPipe, 0x350d, 0x00); + ov4689_write_register(ViPipe, 0x350e, 0x00); + ov4689_write_register(ViPipe, 0x350f, 0x80); + ov4689_write_register(ViPipe, 0x3510, 0x00); + ov4689_write_register(ViPipe, 0x3511, 0x00); + ov4689_write_register(ViPipe, 0x3512, 0x00); + ov4689_write_register(ViPipe, 0x3513, 0x00); + ov4689_write_register(ViPipe, 0x3514, 0x00); + ov4689_write_register(ViPipe, 0x3515, 0x80); + ov4689_write_register(ViPipe, 0x3516, 0x00); + ov4689_write_register(ViPipe, 0x3517, 0x00); + ov4689_write_register(ViPipe, 0x3518, 0x00); + ov4689_write_register(ViPipe, 0x3519, 0x00); + ov4689_write_register(ViPipe, 0x351a, 0x00); + ov4689_write_register(ViPipe, 0x351b, 0x80); + ov4689_write_register(ViPipe, 0x351c, 0x00); + ov4689_write_register(ViPipe, 0x351d, 0x00); + ov4689_write_register(ViPipe, 0x351e, 0x00); + ov4689_write_register(ViPipe, 0x351f, 0x00); + ov4689_write_register(ViPipe, 0x3520, 0x00); + ov4689_write_register(ViPipe, 0x3521, 0x80); + ov4689_write_register(ViPipe, 0x3522, 0x08); + ov4689_write_register(ViPipe, 0x3524, 0x08); + ov4689_write_register(ViPipe, 0x3526, 0x08); + ov4689_write_register(ViPipe, 0x3528, 0x08); + ov4689_write_register(ViPipe, 0x352a, 0x08); + ov4689_write_register(ViPipe, 0x3602, 0x00); + ov4689_write_register(ViPipe, 0x3603, 0x40); + ov4689_write_register(ViPipe, 0x3604, 0x02); + ov4689_write_register(ViPipe, 0x3605, 0x00); + ov4689_write_register(ViPipe, 0x3606, 0x00); + ov4689_write_register(ViPipe, 0x3607, 0x00); + ov4689_write_register(ViPipe, 0x3609, 0x12); + ov4689_write_register(ViPipe, 0x360a, 0x40); + ov4689_write_register(ViPipe, 0x360c, 0x08); + ov4689_write_register(ViPipe, 0x360f, 0xe5); + ov4689_write_register(ViPipe, 0x3608, 0x8f); + ov4689_write_register(ViPipe, 0x3611, 0x00); + ov4689_write_register(ViPipe, 0x3613, 0xf7); + ov4689_write_register(ViPipe, 0x3616, 0x58); + ov4689_write_register(ViPipe, 0x3619, 0x99); + ov4689_write_register(ViPipe, 0x361b, 0x60); + ov4689_write_register(ViPipe, 0x361c, 0x7a); + ov4689_write_register(ViPipe, 0x361e, 0x79); + ov4689_write_register(ViPipe, 0x361f, 0x02); + ov4689_write_register(ViPipe, 0x3632, 0x00); + ov4689_write_register(ViPipe, 0x3633, 0x10); + ov4689_write_register(ViPipe, 0x3634, 0x10); + ov4689_write_register(ViPipe, 0x3635, 0x10); + ov4689_write_register(ViPipe, 0x3636, 0x15); + ov4689_write_register(ViPipe, 0x3646, 0x86); + ov4689_write_register(ViPipe, 0x364a, 0x0b); + ov4689_write_register(ViPipe, 0x3700, 0x17); + ov4689_write_register(ViPipe, 0x3701, 0x22); + ov4689_write_register(ViPipe, 0x3703, 0x10); + ov4689_write_register(ViPipe, 0x370a, 0x37); + ov4689_write_register(ViPipe, 0x3705, 0x00); + ov4689_write_register(ViPipe, 0x3706, 0x63); + ov4689_write_register(ViPipe, 0x3709, 0x3c); + ov4689_write_register(ViPipe, 0x370b, 0x01); + ov4689_write_register(ViPipe, 0x370c, 0x30); + ov4689_write_register(ViPipe, 0x3710, 0x24); + ov4689_write_register(ViPipe, 0x3711, 0x0c); + ov4689_write_register(ViPipe, 0x3716, 0x00); + ov4689_write_register(ViPipe, 0x3720, 0x28); + ov4689_write_register(ViPipe, 0x3729, 0x7b); + ov4689_write_register(ViPipe, 0x372a, 0x84); + ov4689_write_register(ViPipe, 0x372b, 0xbd); + ov4689_write_register(ViPipe, 0x372c, 0xbc); + ov4689_write_register(ViPipe, 0x372e, 0x52); + ov4689_write_register(ViPipe, 0x373c, 0x0e); + ov4689_write_register(ViPipe, 0x373e, 0x33); + ov4689_write_register(ViPipe, 0x3743, 0x10); + ov4689_write_register(ViPipe, 0x3744, 0x88); + ov4689_write_register(ViPipe, 0x3745, 0xc0); + ov4689_write_register(ViPipe, 0x374a, 0x43); + ov4689_write_register(ViPipe, 0x374c, 0x00); + ov4689_write_register(ViPipe, 0x374e, 0x23); + ov4689_write_register(ViPipe, 0x3751, 0x7b); + ov4689_write_register(ViPipe, 0x3752, 0x84); + ov4689_write_register(ViPipe, 0x3753, 0xbd); + ov4689_write_register(ViPipe, 0x3754, 0xbc); + ov4689_write_register(ViPipe, 0x3756, 0x52); + ov4689_write_register(ViPipe, 0x375c, 0x00); + ov4689_write_register(ViPipe, 0x3760, 0x00); + ov4689_write_register(ViPipe, 0x3761, 0x00); + ov4689_write_register(ViPipe, 0x3762, 0x00); + ov4689_write_register(ViPipe, 0x3763, 0x00); + ov4689_write_register(ViPipe, 0x3764, 0x00); + ov4689_write_register(ViPipe, 0x3767, 0x04); + ov4689_write_register(ViPipe, 0x3768, 0x04); + ov4689_write_register(ViPipe, 0x3769, 0x08); + ov4689_write_register(ViPipe, 0x376a, 0x08); + ov4689_write_register(ViPipe, 0x376b, 0x20); + ov4689_write_register(ViPipe, 0x376c, 0x00); + ov4689_write_register(ViPipe, 0x376d, 0x00); + ov4689_write_register(ViPipe, 0x376e, 0x00); + ov4689_write_register(ViPipe, 0x3773, 0x00); + ov4689_write_register(ViPipe, 0x3774, 0x51); + ov4689_write_register(ViPipe, 0x3776, 0xbd); + ov4689_write_register(ViPipe, 0x3777, 0xbd); + ov4689_write_register(ViPipe, 0x3781, 0x18); + ov4689_write_register(ViPipe, 0x3783, 0x25); + ov4689_write_register(ViPipe, 0x3798, 0x1b); + ov4689_write_register(ViPipe, 0x3800, 0x00); + ov4689_write_register(ViPipe, 0x3801, 0x08); + ov4689_write_register(ViPipe, 0x3802, 0x00); + ov4689_write_register(ViPipe, 0x3803, 0x04); + ov4689_write_register(ViPipe, 0x3804, 0x0a); + ov4689_write_register(ViPipe, 0x3805, 0x97); + ov4689_write_register(ViPipe, 0x3806, 0x05); + ov4689_write_register(ViPipe, 0x3807, 0xfb); + ov4689_write_register(ViPipe, 0x3808, 0x0a); + ov4689_write_register(ViPipe, 0x3809, 0x80); + ov4689_write_register(ViPipe, 0x380a, 0x05); + ov4689_write_register(ViPipe, 0x380b, 0xf0); + ov4689_write_register(ViPipe, 0x380c, 0x0A); + ov4689_write_register(ViPipe, 0x380d, 0x18); + ov4689_write_register(ViPipe, 0x380e, 0x06); + ov4689_write_register(ViPipe, 0x380f, 0x12); + ov4689_write_register(ViPipe, 0x3810, 0x00); + ov4689_write_register(ViPipe, 0x3811, 0x08); + ov4689_write_register(ViPipe, 0x3812, 0x00); + ov4689_write_register(ViPipe, 0x3813, 0x04); + ov4689_write_register(ViPipe, 0x3814, 0x01); + ov4689_write_register(ViPipe, 0x3815, 0x01); + ov4689_write_register(ViPipe, 0x3819, 0x01); + ov4689_write_register(ViPipe, 0x3820, 0x00); + ov4689_write_register(ViPipe, 0x3821, 0x00); + ov4689_write_register(ViPipe, 0x3829, 0x00); + ov4689_write_register(ViPipe, 0x382a, 0x01); + ov4689_write_register(ViPipe, 0x382b, 0x01); + ov4689_write_register(ViPipe, 0x382d, 0x7f); + ov4689_write_register(ViPipe, 0x3830, 0x04); + ov4689_write_register(ViPipe, 0x3836, 0x01); + ov4689_write_register(ViPipe, 0x3837, 0x00); + ov4689_write_register(ViPipe, 0x3841, 0x02); + ov4689_write_register(ViPipe, 0x3846, 0x08); + ov4689_write_register(ViPipe, 0x3847, 0x07); + ov4689_write_register(ViPipe, 0x3d85, 0x36); + ov4689_write_register(ViPipe, 0x3d8c, 0x71); + ov4689_write_register(ViPipe, 0x3d8d, 0xcb); + ov4689_write_register(ViPipe, 0x3f0a, 0x00); + ov4689_write_register(ViPipe, 0x4000, 0xf1); + ov4689_write_register(ViPipe, 0x4001, 0x40); + ov4689_write_register(ViPipe, 0x4002, 0x04); + ov4689_write_register(ViPipe, 0x4003, 0x14); + ov4689_write_register(ViPipe, 0x400e, 0x00); + ov4689_write_register(ViPipe, 0x4011, 0x00); + ov4689_write_register(ViPipe, 0x401a, 0x00); + ov4689_write_register(ViPipe, 0x401b, 0x00); + ov4689_write_register(ViPipe, 0x401c, 0x00); + ov4689_write_register(ViPipe, 0x401d, 0x00); + ov4689_write_register(ViPipe, 0x401f, 0x00); + ov4689_write_register(ViPipe, 0x4020, 0x00); + ov4689_write_register(ViPipe, 0x4021, 0x10); + ov4689_write_register(ViPipe, 0x4022, 0x07); + ov4689_write_register(ViPipe, 0x4023, 0xcf); + ov4689_write_register(ViPipe, 0x4024, 0x09); + ov4689_write_register(ViPipe, 0x4025, 0x60); + ov4689_write_register(ViPipe, 0x4026, 0x09); + ov4689_write_register(ViPipe, 0x4027, 0x6f); + ov4689_write_register(ViPipe, 0x4028, 0x00); + ov4689_write_register(ViPipe, 0x4029, 0x02); + ov4689_write_register(ViPipe, 0x402a, 0x06); + ov4689_write_register(ViPipe, 0x402b, 0x04); + ov4689_write_register(ViPipe, 0x402c, 0x02); + ov4689_write_register(ViPipe, 0x402d, 0x02); + ov4689_write_register(ViPipe, 0x402e, 0x0e); + ov4689_write_register(ViPipe, 0x402f, 0x04); + ov4689_write_register(ViPipe, 0x4302, 0xff); + ov4689_write_register(ViPipe, 0x4303, 0xff); + ov4689_write_register(ViPipe, 0x4304, 0x00); + ov4689_write_register(ViPipe, 0x4305, 0x00); + ov4689_write_register(ViPipe, 0x4306, 0x00); + ov4689_write_register(ViPipe, 0x4308, 0x02); + ov4689_write_register(ViPipe, 0x4500, 0x6c); + ov4689_write_register(ViPipe, 0x4501, 0xc4); + ov4689_write_register(ViPipe, 0x4502, 0x40); + ov4689_write_register(ViPipe, 0x4503, 0x01); + ov4689_write_register(ViPipe, 0x4601, 0xA7); + ov4689_write_register(ViPipe, 0x4800, 0x04); + ov4689_write_register(ViPipe, 0x4813, 0x08); + ov4689_write_register(ViPipe, 0x481f, 0x40); + ov4689_write_register(ViPipe, 0x4829, 0x78); + ov4689_write_register(ViPipe, 0x4837, 0x10); + ov4689_write_register(ViPipe, 0x4b00, 0x2a); + ov4689_write_register(ViPipe, 0x4b0d, 0x00); + ov4689_write_register(ViPipe, 0x4d00, 0x04); + ov4689_write_register(ViPipe, 0x4d01, 0x42); + ov4689_write_register(ViPipe, 0x4d02, 0xd1); + ov4689_write_register(ViPipe, 0x4d03, 0x93); + ov4689_write_register(ViPipe, 0x4d04, 0xf5); + ov4689_write_register(ViPipe, 0x4d05, 0xc1); + ov4689_write_register(ViPipe, 0x5000, 0xf3); + ov4689_write_register(ViPipe, 0x5001, 0x11); + ov4689_write_register(ViPipe, 0x5004, 0x00); + ov4689_write_register(ViPipe, 0x500a, 0x00); + ov4689_write_register(ViPipe, 0x500b, 0x00); + ov4689_write_register(ViPipe, 0x5032, 0x00); + ov4689_write_register(ViPipe, 0x5040, 0x00); + ov4689_write_register(ViPipe, 0x5050, 0x0c); + ov4689_write_register(ViPipe, 0x5500, 0x00); + ov4689_write_register(ViPipe, 0x5501, 0x10); + ov4689_write_register(ViPipe, 0x5502, 0x01); + ov4689_write_register(ViPipe, 0x5503, 0x0f); + ov4689_write_register(ViPipe, 0x8000, 0x00); + ov4689_write_register(ViPipe, 0x8001, 0x00); + ov4689_write_register(ViPipe, 0x8002, 0x00); + ov4689_write_register(ViPipe, 0x8003, 0x00); + ov4689_write_register(ViPipe, 0x8004, 0x00); + ov4689_write_register(ViPipe, 0x8005, 0x00); + ov4689_write_register(ViPipe, 0x8006, 0x00); + ov4689_write_register(ViPipe, 0x8007, 0x00); + ov4689_write_register(ViPipe, 0x8008, 0x00); + ov4689_write_register(ViPipe, 0x3638, 0x00); + + ov4689_default_reg_init(ViPipe); + + ov4689_write_register(ViPipe, 0x0100, 0x01); + + delay_ms(100); + + printf("ViPipe:%d,===OV4689 1520P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + + + + diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_ov6211/Makefile b/middleware/v2/component/isp/sensor/cv181x/ov_ov6211/Makefile new file mode 100644 index 000000000..ec5cc8cb4 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_ov6211/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_ov6211.a +TARGET_SO = $(MW_LIB)/libsns_ov6211.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_ov6211/ov6211_cmos.c b/middleware/v2/component/isp/sensor/cv181x/ov_ov6211/ov6211_cmos.c new file mode 100644 index 000000000..4c3ce796b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_ov6211/ov6211_cmos.c @@ -0,0 +1,966 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "ov6211_cmos_ex.h" +#include "ov6211_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define OV6211_ID 6211 +#define OV6211_I2C_ADDR_1 0x60 +#define OV6211_I2C_ADDR_2 0x70 +#define OV6211_I2C_ADDR_IS_VALID(addr) ((addr) == OV6211_I2C_ADDR_1 || (addr) == OV6211_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastOv6211[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define OV6211_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastOv6211[dev]) +#define OV6211_SENSOR_SET_CTX(dev, pstCtx) (g_pastOv6211[dev] = pstCtx) +#define OV6211_SENSOR_RESET_CTX(dev) (g_pastOv6211[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunOv6211_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Ov6211_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Ov6211_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeOv6211_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Ov6211 Lines Range*****/ +#define OV6211_FULL_LINES_MAX (0xFFFF) + +/*****Ov6211 Register Address*****/ +#define OV6211_EXP_ADDR 0x3500 +#define OV6211_AGAIN_ADDR 0x350a +#define OV6211_VTS_ADDR 0x380E + +#define OV6211_RES_IS_400P(w, h) ((w) == 400 && (h) == 400) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const OV6211_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astOv6211_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = OV6211_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astOv6211_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astOv6211_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astOv6211_mode[pstSnsState->u8ImgMode].f32MinFps; + + + switch (pstSnsState->u8ImgMode) { + case OV6211_MODE_400X400P120: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OV6211_FULL_LINES_MAX) ? OV6211_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_1].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 1 + * max : vts - 4 + * step : 1 + */ + u32MinTime = 1; + u32MaxTime = pstSnsState->au32FL[0] - 4; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_0].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_1].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_2].u32Data = ((u32TmpIntTime & 0x000F) << 4); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +typedef struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} gain_tbl_info_s; + +static struct gain_tbl_info_s AgainInfo[15] = { + { + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x01, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 2944, + .idxBase = 16, + .regGain = 0x02, + .regGainFineBase = 0x00, + .regGainFineStep = 2, + }, + { + .gainMax = 3968, + .idxBase = 24, + .regGain = 0x03, + .regGainFineBase = 0x00, + .regGainFineStep = 2, + }, + { + .gainMax = 4864, + .idxBase = 32, + .regGain = 0x04, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 5888, + .idxBase = 36, + .regGain = 0x05, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 6912, + .idxBase = 40, + .regGain = 0x06, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 7936, + .idxBase = 44, + .regGain = 0x07, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 8704, + .idxBase = 48, + .regGain = 0x08, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 9728, + .idxBase = 50, + .regGain = 0x09, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 10752, + .idxBase = 52, + .regGain = 0x0a, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 11776, + .idxBase = 54, + .regGain = 0x0b, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 12800, + .idxBase = 56, + .regGain = 0x0c, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 13824, + .idxBase = 58, + .regGain = 0x0d, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 14848, + .idxBase = 60, + .regGain = 0x0e, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 15872, + .idxBase = 62, + .regGain = 0x0f, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, +}; + +static CVI_U32 Again_table[64] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[63]) { + *pu32AgainLin = Again_table[63]; + *pu32AgainDb = 63; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + struct gain_tbl_info_s *info; + int i, tbl_num; + + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN0].u32Data = 0x00; + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN1].u32Data = (info->regGain & 0x0F) << 4; + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN1].u32Data |= (u32Again & 0x0F); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const OV6211_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astOv6211_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = OV6211_MODE_400X400P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOv6211_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunOv6211_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = ov6211_i2c_addr; + pstI2c_data[i].u32AddrByteNum = ov6211_addr_byte; + pstI2c_data[i].u32DataByteNum = ov6211_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + pstI2c_data[LINEAR_EXP_0].u32RegAddr = OV6211_EXP_ADDR; + pstI2c_data[LINEAR_EXP_1].u32RegAddr = OV6211_EXP_ADDR + 1; + pstI2c_data[LINEAR_EXP_2].u32RegAddr = OV6211_EXP_ADDR + 2; + pstI2c_data[LINEAR_AGAIN0].u32RegAddr = OV6211_AGAIN_ADDR; + pstI2c_data[LINEAR_AGAIN1].u32RegAddr = OV6211_AGAIN_ADDR + 1; + pstI2c_data[LINEAR_VTS_0].u32RegAddr = OV6211_VTS_ADDR; + pstI2c_data[LINEAR_VTS_1].u32RegAddr = OV6211_VTS_ADDR + 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 120) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (OV6211_RES_IS_400P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OV6211_MODE_400X400P120; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeOv6211_MirrorFip[ViPipe] != eSnsMirrorFlip) { + ov6211_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeOv6211_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = OV6211_MODE_400X400P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOv6211_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astOv6211_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astOv6211_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV6211_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &ov6211_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astOv6211_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astOv6211_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &ov6211_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = ov6211_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = ov6211_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (OV6211_I2C_ADDR_IS_VALID(s32I2cAddr)) + ov6211_i2c_addr = s32I2cAddr; +} + +static CVI_S32 ov6211_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunOv6211_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OV6211_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + OV6211_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OV6211_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + OV6211_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = OV6211_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, OV6211_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, OV6211_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, OV6211_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Ov6211_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Ov6211_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return ov6211_probe(ViPipe); +} + + +ISP_SNS_OBJ_S stSnsOv6211_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = ov6211_standby, + .pfnRestart = ov6211_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = ov6211_write_register, + .pfnReadReg = ov6211_read_register, + .pfnSetBusInfo = ov6211_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_ov6211/ov6211_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/ov_ov6211/ov6211_cmos_ex.h new file mode 100644 index 000000000..d8427c342 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_ov6211/ov6211_cmos_ex.h @@ -0,0 +1,86 @@ +#ifndef __OV6211_CMOS_EX_H_ +#define __OV6211_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum ov6211_linear_regs_e { + LINEAR_EXP_0 = 0, + LINEAR_EXP_1, + LINEAR_EXP_2, + LINEAR_AGAIN0, + LINEAR_AGAIN1, + LINEAR_VTS_0, + LINEAR_VTS_1, + LINEAR_REGS_NUM +}; + +typedef enum _OV6211_MODE_E { + OV6211_MODE_400X400P120 = 0, + OV6211_MODE_LINEAR_NUM, + OV6211_MODE_NUM +} OV6211_MODE_E; + +typedef struct _OV6211_STATE_S { + CVI_U32 u32Sexp_MAX; +} OV6211_STATE_S; + +typedef struct _OV6211_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + CVI_U16 u16L2sOffset; + CVI_U16 u16TopBoundary; + CVI_U16 u16BotBoundary; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U32 u32L2S_MAX; + char name[64]; +} OV6211_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastOv6211[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunOv6211_BusInfo[]; +extern CVI_U16 g_au16Ov6211_GainMode[]; +extern CVI_U16 g_au16Ov6211_L2SMode[VI_MAX_PIPE_NUM]; +extern CVI_U8 ov6211_i2c_addr; +extern const CVI_U32 ov6211_addr_byte; +extern const CVI_U32 ov6211_data_byte; +extern void ov6211_init(VI_PIPE ViPipe); +extern void ov6211_exit(VI_PIPE ViPipe); +extern void ov6211_standby(VI_PIPE ViPipe); +extern void ov6211_restart(VI_PIPE ViPipe); +extern int ov6211_write_register(VI_PIPE ViPipe, int addr, int data); +extern int ov6211_read_register(VI_PIPE ViPipe, int addr); +extern void ov6211_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int ov6211_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OV6211_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_ov6211/ov6211_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/ov_ov6211/ov6211_cmos_param.h new file mode 100644 index 000000000..1274eb2ab --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_ov6211/ov6211_cmos_param.h @@ -0,0 +1,126 @@ +#ifndef __OV6211_CMOS_PARAM_H_ +#define __OV6211_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "ov6211_cmos_ex.h" + +static const OV6211_MODE_S g_astOv6211_mode[OV6211_MODE_NUM] = { + [OV6211_MODE_400X400P120] = { + .name = "400X400P120", + .astImg[0] = { + .stSnsSize = { + .u32Width = 400, + .u32Height = 400, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 400, + .u32Height = 400, + }, + .stMaxSize = { + .u32Width = 400, + .u32Height = 400, + }, + }, + .f32MaxFps = 120, + .f32MinFps = 0.80, /* 0x1b6 * 120 / 0xFFFF */ + .u32HtsDef = 1522, + .u32VtsDef = 438, + .stExp[0] = { + .u16Min = 1, + .u16Max = 438 - 4, + .u16Def = 100, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {128, 128, 128, 128, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1057, 1057, 1057, 1057 +#endif + }, + .stAuto = { + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {128, 128, 128, 128, 128, 128, 128, 128, /*8*/128, 128, 128, 128, 128, 128, 128, 128}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, + {1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + /*8*/1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057}, +#endif + }, + }, +}; + +struct combo_dev_attr_s ov6211_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {1, 0, -1, -1, -1}, + .pn_swap = {1, 1, 0, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 8, + } + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OV6211_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_ov6211/ov6211_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/ov_ov6211/ov6211_sensor_ctl.c new file mode 100644 index 000000000..56cef42fe --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_ov6211/ov6211_sensor_ctl.c @@ -0,0 +1,391 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "ov6211_cmos_ex.h" + +static void ov6211_linear_400p120_init(VI_PIPE ViPipe); + +CVI_U8 ov6211_i2c_addr = 0x60; /* I2C Address of OV6211 */ +const CVI_U32 ov6211_addr_byte = 2; +const CVI_U32 ov6211_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int ov6211_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunOv6211_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, ov6211_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int ov6211_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int ov6211_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (ov6211_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, ov6211_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, ov6211_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (ov6211_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; + +} + +int ov6211_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (ov6211_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (ov6211_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, ov6211_addr_byte + ov6211_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void ov6211_standby(VI_PIPE ViPipe) +{ + ov6211_write_register(ViPipe, 0x0100, 0x00); /* standby */ +} + +void ov6211_restart(VI_PIPE ViPipe) +{ + ov6211_write_register(ViPipe, 0x0100, 0x01); /* restart */ +} + +void ov6211_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastOv6211[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastOv6211[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + ov6211_write_register(ViPipe, + g_pastOv6211[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastOv6211[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void ov6211_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 flip, mirror; + + flip = ov6211_read_register(ViPipe, 0x3820); + mirror = ov6211_read_register(ViPipe, 0x3821); + + flip &= ~(0x1 << 2); + mirror &= ~(0x1 << 2); + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + mirror |= 0x1 << 2; + break; + case ISP_SNS_FLIP: + flip |= 0x1 << 2; + break; + case ISP_SNS_MIRROR_FLIP: + flip |= 0x1 << 2; + mirror |= 0x1 << 2; + break; + default: + return; + } + + ov6211_write_register(ViPipe, 0x3820, flip); + ov6211_write_register(ViPipe, 0x3821, mirror); +} + +#define OV6211_CHIP_ID_ADDR_H 0x300A +#define OV6211_CHIP_ID_ADDR_L 0x300B +#define OV6211_CHIP_ID 0x6710 + +int ov6211_probe(VI_PIPE ViPipe) +{ + int nVal, nVal2; + + usleep(500); + if (ov6211_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = ov6211_read_register(ViPipe, OV6211_CHIP_ID_ADDR_H); + nVal2 = ov6211_read_register(ViPipe, OV6211_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | ((nVal2 & 0xFF) << 0)) != OV6211_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void ov6211_init(VI_PIPE ViPipe) +{ + ov6211_i2c_init(ViPipe); + delay_ms(50); + ov6211_linear_400p120_init(ViPipe); + + g_pastOv6211[ViPipe]->bInit = CVI_TRUE; +} + +void ov6211_exit(VI_PIPE ViPipe) +{ + ov6211_i2c_exit(ViPipe); +} + +/* 1944P30 and 1944P25 */ +static void ov6211_linear_400p120_init(VI_PIPE ViPipe) +{ + ov6211_write_register(ViPipe, 0x0103, 0x01); + ov6211_write_register(ViPipe, 0x0100, 0x00); + ov6211_write_register(ViPipe, 0x3005, 0x00); + ov6211_write_register(ViPipe, 0x3013, 0x12); + ov6211_write_register(ViPipe, 0x3014, 0x04); + ov6211_write_register(ViPipe, 0x3016, 0x10); + ov6211_write_register(ViPipe, 0x3017, 0x00); + ov6211_write_register(ViPipe, 0x3018, 0x00); + ov6211_write_register(ViPipe, 0x301a, 0x00); + ov6211_write_register(ViPipe, 0x301b, 0x00); + ov6211_write_register(ViPipe, 0x301c, 0x00); + ov6211_write_register(ViPipe, 0x3037, 0xf0); + ov6211_write_register(ViPipe, 0x3080, 0x01); + ov6211_write_register(ViPipe, 0x3081, 0x00); + ov6211_write_register(ViPipe, 0x3082, 0x01); + ov6211_write_register(ViPipe, 0x3098, 0x04); + ov6211_write_register(ViPipe, 0x3099, 0x28); + ov6211_write_register(ViPipe, 0x309a, 0x06); + ov6211_write_register(ViPipe, 0x309b, 0x04); + ov6211_write_register(ViPipe, 0x309c, 0x00); + ov6211_write_register(ViPipe, 0x309d, 0x00); + ov6211_write_register(ViPipe, 0x309e, 0x01); + ov6211_write_register(ViPipe, 0x309f, 0x00); + ov6211_write_register(ViPipe, 0x30b0, 0x0a); + ov6211_write_register(ViPipe, 0x30b1, 0x02); + ov6211_write_register(ViPipe, 0x30b2, 0x00); + ov6211_write_register(ViPipe, 0x30b3, 0x32); + ov6211_write_register(ViPipe, 0x30b4, 0x02); + ov6211_write_register(ViPipe, 0x30b5, 0x05); + ov6211_write_register(ViPipe, 0x3106, 0xd9); + ov6211_write_register(ViPipe, 0x3500, 0x00); + ov6211_write_register(ViPipe, 0x3501, 0x1b); + ov6211_write_register(ViPipe, 0x3502, 0x20); + ov6211_write_register(ViPipe, 0x3503, 0x07); + ov6211_write_register(ViPipe, 0x3509, 0x10); + ov6211_write_register(ViPipe, 0x350b, 0x10); + ov6211_write_register(ViPipe, 0x3600, 0xfc); + ov6211_write_register(ViPipe, 0x3620, 0xb7); + ov6211_write_register(ViPipe, 0x3621, 0x05); + ov6211_write_register(ViPipe, 0x3626, 0x31); + ov6211_write_register(ViPipe, 0x3627, 0x40); + ov6211_write_register(ViPipe, 0x3632, 0xa3); + ov6211_write_register(ViPipe, 0x3633, 0x34); + ov6211_write_register(ViPipe, 0x3634, 0x40); + ov6211_write_register(ViPipe, 0x3636, 0x00); + ov6211_write_register(ViPipe, 0x3660, 0x80); + ov6211_write_register(ViPipe, 0x3662, 0x01); + ov6211_write_register(ViPipe, 0x3664, 0xf0); + ov6211_write_register(ViPipe, 0x366a, 0x10); + ov6211_write_register(ViPipe, 0x366b, 0x06); + ov6211_write_register(ViPipe, 0x3680, 0xf4); + ov6211_write_register(ViPipe, 0x3681, 0x50); + ov6211_write_register(ViPipe, 0x3682, 0x00); + ov6211_write_register(ViPipe, 0x3708, 0x20); + ov6211_write_register(ViPipe, 0x3709, 0x40); + ov6211_write_register(ViPipe, 0x370d, 0x03); + ov6211_write_register(ViPipe, 0x373b, 0x02); + ov6211_write_register(ViPipe, 0x373c, 0x08); + ov6211_write_register(ViPipe, 0x3742, 0x00); + ov6211_write_register(ViPipe, 0x3744, 0x16); + ov6211_write_register(ViPipe, 0x3745, 0x08); + ov6211_write_register(ViPipe, 0x3781, 0xfc); + ov6211_write_register(ViPipe, 0x3788, 0x00); + ov6211_write_register(ViPipe, 0x3800, 0x00); + ov6211_write_register(ViPipe, 0x3801, 0x04); + ov6211_write_register(ViPipe, 0x3802, 0x00); + ov6211_write_register(ViPipe, 0x3803, 0x04); + ov6211_write_register(ViPipe, 0x3804, 0x01); + ov6211_write_register(ViPipe, 0x3805, 0x9b); + ov6211_write_register(ViPipe, 0x3806, 0x01); + ov6211_write_register(ViPipe, 0x3807, 0x9b); + ov6211_write_register(ViPipe, 0x3808, 0x01); + ov6211_write_register(ViPipe, 0x3809, 0x90); + ov6211_write_register(ViPipe, 0x380a, 0x01); + ov6211_write_register(ViPipe, 0x380b, 0x90); + ov6211_write_register(ViPipe, 0x380c, 0x05); + ov6211_write_register(ViPipe, 0x380d, 0xf2); + ov6211_write_register(ViPipe, 0x380e, 0x01); + ov6211_write_register(ViPipe, 0x380f, 0xb6); + ov6211_write_register(ViPipe, 0x3810, 0x00); + ov6211_write_register(ViPipe, 0x3811, 0x04); + ov6211_write_register(ViPipe, 0x3812, 0x00); + ov6211_write_register(ViPipe, 0x3813, 0x04); + ov6211_write_register(ViPipe, 0x3814, 0x11); + ov6211_write_register(ViPipe, 0x3815, 0x11); + ov6211_write_register(ViPipe, 0x3820, 0x00); + ov6211_write_register(ViPipe, 0x3821, 0x00); + ov6211_write_register(ViPipe, 0x382b, 0xfa); + ov6211_write_register(ViPipe, 0x382f, 0x04); + ov6211_write_register(ViPipe, 0x3832, 0x00); + ov6211_write_register(ViPipe, 0x3833, 0x05); + ov6211_write_register(ViPipe, 0x3834, 0x00); + ov6211_write_register(ViPipe, 0x3835, 0x05); + ov6211_write_register(ViPipe, 0x3882, 0x04); + ov6211_write_register(ViPipe, 0x3883, 0x00); + ov6211_write_register(ViPipe, 0x38a4, 0x10); + ov6211_write_register(ViPipe, 0x38a5, 0x00); + ov6211_write_register(ViPipe, 0x38b1, 0x03); + ov6211_write_register(ViPipe, 0x3b80, 0x00); + ov6211_write_register(ViPipe, 0x3b81, 0xa5); + ov6211_write_register(ViPipe, 0x3b82, 0x10); + ov6211_write_register(ViPipe, 0x3b83, 0x00); + ov6211_write_register(ViPipe, 0x3b84, 0x08); + ov6211_write_register(ViPipe, 0x3b85, 0x00); + ov6211_write_register(ViPipe, 0x3b86, 0x01); + ov6211_write_register(ViPipe, 0x3b87, 0x00); + ov6211_write_register(ViPipe, 0x3b88, 0x00); + ov6211_write_register(ViPipe, 0x3b89, 0x00); + ov6211_write_register(ViPipe, 0x3b8a, 0x00); + ov6211_write_register(ViPipe, 0x3b8b, 0x05); + ov6211_write_register(ViPipe, 0x3b8c, 0x00); + ov6211_write_register(ViPipe, 0x3b8d, 0x00); + ov6211_write_register(ViPipe, 0x3b8e, 0x00); + ov6211_write_register(ViPipe, 0x3b8f, 0x1a); + ov6211_write_register(ViPipe, 0x3b94, 0x05); + ov6211_write_register(ViPipe, 0x3b95, 0xf2); + ov6211_write_register(ViPipe, 0x3b96, 0xf0); + ov6211_write_register(ViPipe, 0x4004, 0x04); + ov6211_write_register(ViPipe, 0x404e, 0x01); + ov6211_write_register(ViPipe, 0x4801, 0x0f); + ov6211_write_register(ViPipe, 0x4806, 0x0f); + + ov6211_write_register(ViPipe, 0x4818, 0x00); + ov6211_write_register(ViPipe, 0x4819, 0xaa); + ov6211_write_register(ViPipe, 0x482a, 0x08); + + ov6211_write_register(ViPipe, 0x481a, 0x00); + ov6211_write_register(ViPipe, 0x481b, 0x4a); + ov6211_write_register(ViPipe, 0x482b, 0x08); + + ov6211_write_register(ViPipe, 0x4837, 0x43); + ov6211_write_register(ViPipe, 0x5a08, 0x00); + ov6211_write_register(ViPipe, 0x5a01, 0x00); + ov6211_write_register(ViPipe, 0x5a03, 0x00); + ov6211_write_register(ViPipe, 0x5a04, 0x10); + ov6211_write_register(ViPipe, 0x5a05, 0xa0); + ov6211_write_register(ViPipe, 0x5a06, 0x0c); + ov6211_write_register(ViPipe, 0x5a07, 0x78); + + ov6211_default_reg_init(ViPipe); + + ov6211_write_register(ViPipe, 0x0100, 0x01); + + delay_ms(100); + + printf("ViPipe:%d,===OV6211 400P 120fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_ov7251/Makefile b/middleware/v2/component/isp/sensor/cv181x/ov_ov7251/Makefile new file mode 100644 index 000000000..880ea8509 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_ov7251/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_ov7251.a +TARGET_SO = $(MW_LIB)/libsns_ov7251.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_ov7251/ov7251_cmos.c b/middleware/v2/component/isp/sensor/cv181x/ov_ov7251/ov7251_cmos.c new file mode 100644 index 000000000..30a0c7adb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_ov7251/ov7251_cmos.c @@ -0,0 +1,967 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "ov7251_cmos_ex.h" +#include "ov7251_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define OV7251_ID 7251 +#define OV7251_I2C_ADDR_1 0x60 +#define OV7251_I2C_ADDR_2 0x70 +#define OV7251_I2C_ADDR_IS_VALID(addr) ((addr) == OV7251_I2C_ADDR_1 || (addr) == OV7251_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastOv7251[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define OV7251_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastOv7251[dev]) +#define OV7251_SENSOR_SET_CTX(dev, pstCtx) (g_pastOv7251[dev] = pstCtx) +#define OV7251_SENSOR_RESET_CTX(dev) (g_pastOv7251[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunOv7251_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Ov7251_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Ov7251_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeOv7251_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Ov7251 Lines Range*****/ +#define OV7251_FULL_LINES_MAX (0xFFFF) + +/*****Ov7251 Register Address*****/ +#define OV7251_EXP_ADDR 0x3500 +#define OV7251_AGAIN_ADDR 0x350a +#define OV7251_VTS_ADDR 0x380E + +#define OV7251_RES_IS_480P(w, h) ((w) == 640 && (h) == 480) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const OV7251_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astOv7251_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = OV7251_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astOv7251_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astOv7251_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astOv7251_mode[pstSnsState->u8ImgMode].f32MinFps; + + + switch (pstSnsState->u8ImgMode) { + case OV7251_MODE_640X480P120: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > OV7251_FULL_LINES_MAX) ? OV7251_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VTS_0].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_1].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 2 + * max : vts - 20 + * step : 1 + */ + u32MinTime = 2; + u32MaxTime = pstSnsState->au32FL[0] - 20; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_0].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_1].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_2].u32Data = ((u32TmpIntTime & 0x000F) << 4); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +typedef struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} gain_tbl_info_s; + +static struct gain_tbl_info_s AgainInfo[15] = { + { + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x01, + .regGainFineBase = 0x00, + .regGainFineStep = 1, + }, + { + .gainMax = 2944, + .idxBase = 16, + .regGain = 0x02, + .regGainFineBase = 0x00, + .regGainFineStep = 2, + }, + { + .gainMax = 3968, + .idxBase = 24, + .regGain = 0x03, + .regGainFineBase = 0x00, + .regGainFineStep = 2, + }, + { + .gainMax = 4864, + .idxBase = 32, + .regGain = 0x04, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 5888, + .idxBase = 36, + .regGain = 0x05, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 6912, + .idxBase = 40, + .regGain = 0x06, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 7936, + .idxBase = 44, + .regGain = 0x07, + .regGainFineBase = 0x00, + .regGainFineStep = 4, + }, + { + .gainMax = 8704, + .idxBase = 48, + .regGain = 0x08, + .regGainFineBase = 0x08, + .regGainFineStep = 8, + }, + { + .gainMax = 9728, + .idxBase = 49, + .regGain = 0x09, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 10752, + .idxBase = 51, + .regGain = 0x0a, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 11776, + .idxBase = 53, + .regGain = 0x0b, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 12800, + .idxBase = 55, + .regGain = 0x0c, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 13824, + .idxBase = 57, + .regGain = 0x0d, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 14848, + .idxBase = 59, + .regGain = 0x0e, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, + { + .gainMax = 15872, + .idxBase = 61, + .regGain = 0x0f, + .regGainFineBase = 0x00, + .regGainFineStep = 8, + }, +}; + +static CVI_U32 Again_table[] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8704, 9216, 9728, 10240, + 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, 15872 +}; + +static const CVI_U32 again_table_size = ARRAY_SIZE(Again_table); + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[again_table_size - 1]) { + *pu32AgainLin = Again_table[again_table_size - 1]; + *pu32AgainDb = again_table_size - 1; + return CVI_SUCCESS; + } + + for (i = 1; i < again_table_size; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + struct gain_tbl_info_s *info; + int i, tbl_num; + + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN0].u32Data = 0x00; + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN1].u32Data = (info->regGain & 0x0F) << 4; + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN1].u32Data |= (u32Again & 0x0F); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const OV7251_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astOv7251_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = OV7251_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOv7251_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunOv7251_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = ov7251_i2c_addr; + pstI2c_data[i].u32AddrByteNum = ov7251_addr_byte; + pstI2c_data[i].u32DataByteNum = ov7251_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + pstI2c_data[LINEAR_EXP_0].u32RegAddr = OV7251_EXP_ADDR; + pstI2c_data[LINEAR_EXP_1].u32RegAddr = OV7251_EXP_ADDR + 1; + pstI2c_data[LINEAR_EXP_2].u32RegAddr = OV7251_EXP_ADDR + 2; + pstI2c_data[LINEAR_AGAIN0].u32RegAddr = OV7251_AGAIN_ADDR; + pstI2c_data[LINEAR_AGAIN1].u32RegAddr = OV7251_AGAIN_ADDR + 1; + pstI2c_data[LINEAR_VTS_0].u32RegAddr = OV7251_VTS_ADDR; + pstI2c_data[LINEAR_VTS_1].u32RegAddr = OV7251_VTS_ADDR + 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 120) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (OV7251_RES_IS_480P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OV7251_MODE_640X480P120; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeOv7251_MirrorFip[ViPipe] != eSnsMirrorFlip) { + ov7251_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeOv7251_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = OV7251_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOv7251_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astOv7251_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astOv7251_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV7251_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &ov7251_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astOv7251_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astOv7251_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &ov7251_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = ov7251_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = ov7251_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (OV7251_I2C_ADDR_IS_VALID(s32I2cAddr)) + ov7251_i2c_addr = s32I2cAddr; +} + +static CVI_S32 ov7251_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunOv7251_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OV7251_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + OV7251_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OV7251_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + OV7251_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = OV7251_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, OV7251_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, OV7251_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, OV7251_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Ov7251_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Ov7251_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return ov7251_probe(ViPipe); +} + + +ISP_SNS_OBJ_S stSnsOv7251_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = ov7251_standby, + .pfnRestart = ov7251_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = ov7251_write_register, + .pfnReadReg = ov7251_read_register, + .pfnSetBusInfo = ov7251_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_ov7251/ov7251_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/ov_ov7251/ov7251_cmos_ex.h new file mode 100644 index 000000000..339ec679f --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_ov7251/ov7251_cmos_ex.h @@ -0,0 +1,86 @@ +#ifndef __OV7251_CMOS_EX_H_ +#define __OV7251_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum ov7251_linear_regs_e { + LINEAR_EXP_0 = 0, + LINEAR_EXP_1, + LINEAR_EXP_2, + LINEAR_AGAIN0, + LINEAR_AGAIN1, + LINEAR_VTS_0, + LINEAR_VTS_1, + LINEAR_REGS_NUM +}; + +typedef enum _OV7251_MODE_E { + OV7251_MODE_640X480P120 = 0, + OV7251_MODE_LINEAR_NUM, + OV7251_MODE_NUM +} OV7251_MODE_E; + +typedef struct _OV7251_STATE_S { + CVI_U32 u32Sexp_MAX; +} OV7251_STATE_S; + +typedef struct _OV7251_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + CVI_U16 u16L2sOffset; + CVI_U16 u16TopBoundary; + CVI_U16 u16BotBoundary; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U32 u32L2S_MAX; + char name[64]; +} OV7251_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastOv7251[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunOv7251_BusInfo[]; +extern CVI_U16 g_au16Ov7251_GainMode[]; +extern CVI_U16 g_au16Ov7251_L2SMode[VI_MAX_PIPE_NUM]; +extern CVI_U8 ov7251_i2c_addr; +extern const CVI_U32 ov7251_addr_byte; +extern const CVI_U32 ov7251_data_byte; +extern void ov7251_init(VI_PIPE ViPipe); +extern void ov7251_exit(VI_PIPE ViPipe); +extern void ov7251_standby(VI_PIPE ViPipe); +extern void ov7251_restart(VI_PIPE ViPipe); +extern int ov7251_write_register(VI_PIPE ViPipe, int addr, int data); +extern int ov7251_read_register(VI_PIPE ViPipe, int addr); +extern void ov7251_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int ov7251_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OV7251_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_ov7251/ov7251_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/ov_ov7251/ov7251_cmos_param.h new file mode 100644 index 000000000..adf3415d6 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_ov7251/ov7251_cmos_param.h @@ -0,0 +1,122 @@ +#ifndef __OV7251_CMOS_PARAM_H_ +#define __OV7251_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "ov7251_cmos_ex.h" + +static const OV7251_MODE_S g_astOv7251_mode[OV7251_MODE_NUM] = { + [OV7251_MODE_640X480P120] = { + .name = "640X480P120", + .astImg[0] = { + .stSnsSize = { + .u32Width = 640, + .u32Height = 480, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 640, + .u32Height = 480, + }, + .stMaxSize = { + .u32Width = 640, + .u32Height = 480, + }, + }, + .f32MaxFps = 120, + .f32MinFps = 0.79, /* 0x20a * 100 / 0xFFFF */ + .u32HtsDef = 1522, + .u32VtsDef = 538, + .stExp[0] = { + .u16Min = 2, + .u16Max = 538 - 20, + .u16Def = 100, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {64, 64, 64, 64, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1040, 1040, 1040, 1040 +#endif + }, + .stAuto = { + {64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, +#endif + }, + }, +}; + +struct combo_dev_attr_s ov7251_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {1, 0, -1, -1, -1}, + .pn_swap = {1, 1, 0, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OV7251_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/ov_ov7251/ov7251_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/ov_ov7251/ov7251_sensor_ctl.c new file mode 100644 index 000000000..38d3518bb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/ov_ov7251/ov7251_sensor_ctl.c @@ -0,0 +1,318 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "ov7251_cmos_ex.h" + +static void ov7251_linear_480p120_init(VI_PIPE ViPipe); + +CVI_U8 ov7251_i2c_addr = 0x60; /* I2C Address of OV7251 */ +const CVI_U32 ov7251_addr_byte = 2; +const CVI_U32 ov7251_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int ov7251_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunOv7251_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, ov7251_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int ov7251_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int ov7251_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (ov7251_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, ov7251_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, ov7251_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (ov7251_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; + +} + +int ov7251_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (ov7251_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (ov7251_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, ov7251_addr_byte + ov7251_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void ov7251_standby(VI_PIPE ViPipe) +{ + ov7251_write_register(ViPipe, 0x0100, 0x00); /* standby */ +} + +void ov7251_restart(VI_PIPE ViPipe) +{ + ov7251_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + ov7251_write_register(ViPipe, 0x0100, 0x01); /* restart */ +} + +void ov7251_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastOv7251[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastOv7251[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + ov7251_write_register(ViPipe, + g_pastOv7251[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastOv7251[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void ov7251_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 flip, mirror; + + flip = ov7251_read_register(ViPipe, 0x3820); + mirror = ov7251_read_register(ViPipe, 0x3821); + + flip &= ~(0x1 << 2); + mirror &= ~(0x1 << 2); + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + mirror |= 0x1 << 2; + break; + case ISP_SNS_FLIP: + flip |= 0x1 << 2; + break; + case ISP_SNS_MIRROR_FLIP: + flip |= 0x1 << 2; + mirror |= 0x1 << 2; + break; + default: + return; + } + + ov7251_write_register(ViPipe, 0x3820, flip); + ov7251_write_register(ViPipe, 0x3821, mirror); +} + +#define OV7251_CHIP_ID_ADDR_H 0x300A +#define OV7251_CHIP_ID_ADDR_L 0x300B +#define OV7251_CHIP_ID 0x7750 + +int ov7251_probe(VI_PIPE ViPipe) +{ + int nVal, nVal2; + + if (ov7251_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + delay_ms(5); + + nVal = ov7251_read_register(ViPipe, OV7251_CHIP_ID_ADDR_H); + nVal2 = ov7251_read_register(ViPipe, OV7251_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | ((nVal2 & 0xFF) << 0)) != OV7251_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void ov7251_init(VI_PIPE ViPipe) +{ + ov7251_i2c_init(ViPipe); + + ov7251_linear_480p120_init(ViPipe); + + g_pastOv7251[ViPipe]->bInit = CVI_TRUE; +} + +void ov7251_exit(VI_PIPE ViPipe) +{ + ov7251_i2c_exit(ViPipe); +} + +/* 1944P30 and 1944P25 */ +static void ov7251_linear_480p120_init(VI_PIPE ViPipe) +{ + ov7251_write_register(ViPipe, 0x0103, 0x01); + ov7251_write_register(ViPipe, 0x0100, 0x00); + ov7251_write_register(ViPipe, 0x3012, 0xc0); + ov7251_write_register(ViPipe, 0x3013, 0xd2); + ov7251_write_register(ViPipe, 0x3016, 0x10); + ov7251_write_register(ViPipe, 0x3017, 0x00); + ov7251_write_register(ViPipe, 0x3018, 0x00); + ov7251_write_register(ViPipe, 0x301a, 0x00); + ov7251_write_register(ViPipe, 0x301b, 0x00); + ov7251_write_register(ViPipe, 0x301c, 0x00); + ov7251_write_register(ViPipe, 0x3023, 0x05); + ov7251_write_register(ViPipe, 0x3099, 0x32); + ov7251_write_register(ViPipe, 0x30b3, 0x64); + ov7251_write_register(ViPipe, 0x30b4, 0x03); + ov7251_write_register(ViPipe, 0x30b5, 0x05); + ov7251_write_register(ViPipe, 0x3106, 0xda); + ov7251_write_register(ViPipe, 0x3501, 0x1f); + ov7251_write_register(ViPipe, 0x3502, 0x80); + ov7251_write_register(ViPipe, 0x3503, 0x07); + ov7251_write_register(ViPipe, 0x3600, 0x1c); + ov7251_write_register(ViPipe, 0x3602, 0x62); + ov7251_write_register(ViPipe, 0x3620, 0xb7); + ov7251_write_register(ViPipe, 0x3622, 0x04); + ov7251_write_register(ViPipe, 0x3626, 0x21); + ov7251_write_register(ViPipe, 0x3627, 0x30); + ov7251_write_register(ViPipe, 0x3630, 0x44); + ov7251_write_register(ViPipe, 0x3631, 0x35); + ov7251_write_register(ViPipe, 0x3634, 0x60); + ov7251_write_register(ViPipe, 0x3663, 0x70); + ov7251_write_register(ViPipe, 0x3669, 0x1a); + ov7251_write_register(ViPipe, 0x3673, 0x01); + ov7251_write_register(ViPipe, 0x3674, 0xef); + ov7251_write_register(ViPipe, 0x3675, 0x03); + ov7251_write_register(ViPipe, 0x3705, 0xc1); + ov7251_write_register(ViPipe, 0x3757, 0xb3); + ov7251_write_register(ViPipe, 0x37a8, 0x01); + ov7251_write_register(ViPipe, 0x37a9, 0xc0); + ov7251_write_register(ViPipe, 0x380d, 0xa0); + ov7251_write_register(ViPipe, 0x380f, 0x1a); + ov7251_write_register(ViPipe, 0x3811, 0x04); + ov7251_write_register(ViPipe, 0x3813, 0x05); + ov7251_write_register(ViPipe, 0x3820, 0x40); + ov7251_write_register(ViPipe, 0x382f, 0x0e); + ov7251_write_register(ViPipe, 0x3835, 0x0c); + ov7251_write_register(ViPipe, 0x3b80, 0x00); + ov7251_write_register(ViPipe, 0x3c01, 0x63); + ov7251_write_register(ViPipe, 0x3c07, 0x06); + ov7251_write_register(ViPipe, 0x3c0c, 0x01); + ov7251_write_register(ViPipe, 0x3c0d, 0xd0); + ov7251_write_register(ViPipe, 0x3c0e, 0x02); + ov7251_write_register(ViPipe, 0x3c0f, 0x0a); + ov7251_write_register(ViPipe, 0x4001, 0x42); + ov7251_write_register(ViPipe, 0x404e, 0x01); + ov7251_write_register(ViPipe, 0x4501, 0x48); + ov7251_write_register(ViPipe, 0x4601, 0x4e); + ov7251_write_register(ViPipe, 0x4801, 0x0f); + ov7251_write_register(ViPipe, 0x4819, 0xaa); + ov7251_write_register(ViPipe, 0x4823, 0x3e); + ov7251_write_register(ViPipe, 0x4a47, 0x7f); + ov7251_write_register(ViPipe, 0x4a49, 0xf0); + ov7251_write_register(ViPipe, 0x4a4b, 0x30); + ov7251_write_register(ViPipe, 0x5001, 0x80); + + ov7251_default_reg_init(ViPipe); + + ov7251_write_register(ViPipe, 0x0100, 0x01); + + delay_ms(100); + + printf("ViPipe:%d,===OV7251 480P 120fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2020/Makefile b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2020/Makefile new file mode 100644 index 000000000..7ebc9b71c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2020/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_pr2020.a +TARGET_SO = $(MW_LIB)/libsns_pr2020.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2020/pr2020_cmos.c b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2020/pr2020_cmos.c new file mode 100644 index 000000000..727d3d85e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2020/pr2020_cmos.c @@ -0,0 +1,293 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_isp.h" + +#include "pr2020_cmos_ex.h" +#include "pr2020_cmos_param.h" + +/**************************************************************************** + * global variables * + ****************************************************************************/ +ISP_SNS_COMMBUS_U g_aunPr2020_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_STATE_S *g_pastPr2020[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define PR2020_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastPr2020[dev]) +#define PR2020_SENSOR_SET_CTX(dev, pstCtx) (g_pastPr2020[dev] = pstCtx) +#define PR2020_SENSOR_RESET_CTX(dev) (g_pastPr2020[dev] = CVI_NULL) + +#define PR2020_RES_IS_720P(w, h) ((w) <= 1280 && (h) <= 720) +#define PR2020_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) +#define PR2020_ID 2020 + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const PR2020_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + PR2020_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astPr2020_mode[pstSnsState->u8ImgMode]; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + PR2020_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstCfg0 = &pstSnsState->astSyncInfo[0]; + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + PR2020_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + + if (pstSensorImageMode->f32Fps <= 25) { + if (PR2020_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = PR2020_MODE_720P_25; + } else if (PR2020_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = PR2020_MODE_1080P_25; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSensorImageMode->f32Fps <= 30) { + if (PR2020_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = PR2020_MODE_720P_30; + } else if (PR2020_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = PR2020_MODE_1080P_30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + PR2020_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->u8ImgMode = PR2020_MODE_1080P_25; + pstSnsState->enWDRMode = WDR_MODE_NONE; +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + PR2020_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + if (ViPipe == 0) { + memcpy(pstRxAttr, &pr2020_rx_attr, sizeof(*pstRxAttr)); + CVI_TRACE_SNS(CVI_DBG_INFO, "get pr2020_rx_attr\n"); + } else { + memcpy(pstRxAttr, &pr2020_rx1_attr, sizeof(*pstRxAttr)); + CVI_TRACE_SNS(CVI_DBG_INFO, "get pr2020_rx1_attr\n"); + } + + pstRxAttr->img_size.width = g_astPr2020_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astPr2020_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &pr2020_rx_attr; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = pr2020_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = pr2020_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 pr2020_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunPr2020_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + PR2020_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + PR2020_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + PR2020_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + PR2020_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + (void) pstAeLib; + (void) pstAwbLib; + + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = PR2020_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + (void) pstAeLib; + (void) pstAwbLib; + + CVI_S32 s32Ret; + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, PR2020_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsPR2020_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = CVI_NULL, + .pfnRestart = CVI_NULL, + .pfnMirrorFlip = CVI_NULL, + .pfnWriteReg = pr2020_write_register, + .pfnReadReg = pr2020_read_register, + .pfnSetBusInfo = pr2020_set_bus_info, + .pfnSetInit = CVI_NULL, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = CVI_NULL, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2020/pr2020_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2020/pr2020_cmos_ex.h new file mode 100644 index 000000000..7bd2db22a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2020/pr2020_cmos_ex.h @@ -0,0 +1,70 @@ +#ifndef __PR2020_CMOS_EX_H_ +#define __PR2020_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +typedef enum _PR2020_MODE_E { + PR2020_MODE_NONE, + PR2020_MODE_720H_NTSC, + PR2020_MODE_720H_PAL, + PR2020_MODE_720P_25, + PR2020_MODE_720P_30, + PR2020_MODE_720P_50, + PR2020_MODE_720P_60, + PR2020_MODE_1080P_25, + PR2020_MODE_1080P_30, + PR2020_MODE_NUM +} PR2020_MODE_E; + +typedef struct _PR2020_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + char name[64]; +} PR2020_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastPr2020[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunPr2020_BusInfo[]; +extern const CVI_U8 pr2020_i2c_addr; +extern const CVI_U32 pr2020_addr_byte; +extern const CVI_U32 pr2020_data_byte; +extern void pr2020_init(VI_PIPE ViPipe); +extern void pr2020_exit(VI_PIPE ViPipe); +extern void pr2020_standby(VI_PIPE ViPipe); +extern void pr2020_restart(VI_PIPE ViPipe); +extern int pr2020_write_register(VI_PIPE ViPipe, int addr, int data); +extern int pr2020_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __PR2020_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2020/pr2020_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2020/pr2020_cmos_param.h new file mode 100644 index 000000000..309f92603 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2020/pr2020_cmos_param.h @@ -0,0 +1,146 @@ +#ifndef __PR2020_CMOS_PARAM_H_ +#define __PR2020_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "pr2020_cmos_ex.h" + +static const PR2020_MODE_S g_astPr2020_mode[PR2020_MODE_NUM] = { + [PR2020_MODE_720P_25] = { + .name = "720p25", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + }, + [PR2020_MODE_720P_30] = { + .name = "720p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + }, + [PR2020_MODE_1080P_25] = { + .name = "1080p25", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + }, + [PR2020_MODE_1080P_30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + }, +}; + +struct combo_dev_attr_s pr2020_rx_attr = { + .input_mode = INPUT_MODE_BT656_9B, + .mac_clk = RX_MAC_CLK_200M, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_NONE, + }, + .ttl_attr = { + .vi = TTL_VI_SRC_VI1, + .func = { + -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, + -1, -1, -1, -1, + -1, -1, -1, -1, + }, + }, + .devno = 0, +}; + +struct combo_dev_attr_s pr2020_rx1_attr = { + .input_mode = INPUT_MODE_BT656_9B, + .mac_clk = RX_MAC_CLK_200M, + .mclk = { + .cam = 1, + .freq = CAMPLL_FREQ_NONE, + }, + .ttl_attr = { + .vi = TTL_VI_SRC_VI1, + .func = { + -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, + -1, -1, -1, -1, + -1, -1, -1, -1, + }, + }, + .devno = 1, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __PR2020_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2020/pr2020_sensor_ctrl.c b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2020/pr2020_sensor_ctrl.c new file mode 100644 index 000000000..d50158fdd --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2020/pr2020_sensor_ctrl.c @@ -0,0 +1,1908 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "cvi_vi.h" +#include "pr2020_cmos_ex.h" + +const CVI_U8 pr2020_i2c_addr = 0x5C; /* I2C slave address of PR2020*/ +const CVI_U32 pr2020_addr_byte = 1; +const CVI_U32 pr2020_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; +static pthread_t g_pr2020_thid; +static PR2020_MODE_E signal_type = PR2020_MODE_NONE; + +#define PR2020_AUTO_DETECT 1 + +/*gpio*/ +enum CVI_GPIO_NUM_E { +CVI_GPIOD_00 = 404, +CVI_GPIOD_01, CVI_GPIOD_02, CVI_GPIOD_03, CVI_GPIOD_04, CVI_GPIOD_05, +CVI_GPIOD_06, CVI_GPIOD_07, CVI_GPIOD_08, CVI_GPIOD_09, CVI_GPIOD_10, +CVI_GPIOD_11, +CVI_GPIOC_00 = 416, +CVI_GPIOC_01, CVI_GPIOC_02, CVI_GPIOC_03, CVI_GPIOC_04, CVI_GPIOC_05, +CVI_GPIOC_06, CVI_GPIOC_07, CVI_GPIOC_08, CVI_GPIOC_09, CVI_GPIOC_10, +CVI_GPIOC_11, CVI_GPIOC_12, CVI_GPIOC_13, CVI_GPIOC_14, CVI_GPIOC_15, +CVI_GPIOC_16, CVI_GPIOC_17, CVI_GPIOC_18, CVI_GPIOC_19, CVI_GPIOC_20, +CVI_GPIOC_21, CVI_GPIOC_22, CVI_GPIOC_23, CVI_GPIOC_24, CVI_GPIOC_25, +CVI_GPIOC_26, CVI_GPIOC_27, CVI_GPIOC_28, CVI_GPIOC_29, CVI_GPIOC_30, +CVI_GPIOC_31, +CVI_GPIOB_00 = 448, +CVI_GPIOB_01, CVI_GPIOB_02, CVI_GPIOB_03, CVI_GPIOB_04, CVI_GPIOB_05, +CVI_GPIOB_06, CVI_GPIOB_07, CVI_GPIOB_08, CVI_GPIOB_09, CVI_GPIOB_10, +CVI_GPIOB_11, CVI_GPIOB_12, CVI_GPIOB_13, CVI_GPIOB_14, CVI_GPIOB_15, +CVI_GPIOB_16, CVI_GPIOB_17, CVI_GPIOB_18, CVI_GPIOB_19, CVI_GPIOB_20, +CVI_GPIOB_21, CVI_GPIOB_22, CVI_GPIOB_23, CVI_GPIOB_24, CVI_GPIOB_25, +CVI_GPIOB_26, CVI_GPIOB_27, CVI_GPIOB_28, CVI_GPIOB_29, CVI_GPIOB_30, +CVI_GPIOB_31, +CVI_GPIOA_00 = 480, +CVI_GPIOA_01, CVI_GPIOA_02, CVI_GPIOA_03, CVI_GPIOA_04, CVI_GPIOA_05, +CVI_GPIOA_06, CVI_GPIOA_07, CVI_GPIOA_08, CVI_GPIOA_09, CVI_GPIOA_10, +CVI_GPIOA_11, CVI_GPIOA_12, CVI_GPIOA_13, CVI_GPIOA_14, CVI_GPIOA_15, +CVI_GPIOA_16, CVI_GPIOA_17, CVI_GPIOA_18, CVI_GPIOA_19, CVI_GPIOA_20, +CVI_GPIOA_21, CVI_GPIOA_22, CVI_GPIOA_23, CVI_GPIOA_24, CVI_GPIOA_25, +CVI_GPIOA_26, CVI_GPIOA_27, CVI_GPIOA_28, CVI_GPIOA_29, CVI_GPIOA_30, +CVI_GPIOA_31, +}; + +#define CVI_GPIO_MIN CVI_GPIOD_00 +#define CVI_GPIO_MAX CVI_GPIOA_31 + +#define SYSFS_GPIO_DIR "/sys/class/gpio" +#define MAX_BUF 64 + +static int PR2020_GPIO_Export(unsigned int gpio) +{ + int fd, len; + char buf[MAX_BUF]; + + fd = open(SYSFS_GPIO_DIR"/export", O_WRONLY); + if (fd < 0) { + perror("gpio/export"); + return fd; + } + + len = snprintf(buf, sizeof(buf), "%d", gpio); + write(fd, buf, len); + close(fd); + + return 0; +} + +static int PR2020_GPIO_SetDirection(unsigned int gpio, unsigned int out_flag) +{ + int fd; + char buf[MAX_BUF]; + + snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR"/gpio%d/direction", gpio); + if (access(buf, 0) == -1) + PR2020_GPIO_Export(gpio); + + fd = open(buf, O_WRONLY); + if (fd < 0) { + perror("gpio/direction"); + return fd; + } + //printf("mark %d , %s\n",out_flag, buf); + if (out_flag) + write(fd, "out", 4); + else + write(fd, "in", 3); + + close(fd); + return 0; +} + +static int PR2020_GPIO_SetValue(unsigned int gpio, unsigned int value) +{ + int fd; + char buf[MAX_BUF]; + + snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR"/gpio%d/value", gpio); + if (access(buf, 0) == -1) + PR2020_GPIO_Export(gpio); + + PR2020_GPIO_SetDirection(gpio, 1); //output + + fd = open(buf, O_WRONLY); + if (fd < 0) { + perror("gpio/set-value"); + return fd; + } + + if (value) + write(fd, "1", 2); + else + write(fd, "0", 2); + + close(fd); + return 0; +} + +int pr2020_sys_init(VI_PIPE ViPipe) +{ + (void) ViPipe; + +#if 0 + //AHD_PWR_EN + if (PR2020_GPIO_SetValue(CVI_GPIOA_00, 1) != 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "set power down gpio error!\n"); + return CVI_FAILURE; + } +#endif + //PR2K_RST + if (PR2020_GPIO_SetValue(CVI_GPIOB_12, 1) != 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "set reset gpio error!\n"); + return CVI_FAILURE; + } +#if 0 + //BACK_DET + if (PR2020_GPIO_SetValue(CVI_GPIOD_01, 1) != 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "set back detect gpio error!\n"); + return CVI_FAILURE; + } +#endif + return CVI_SUCCESS; +} + +int pr2020_i2c_init(VI_PIPE ViPipe) +{ + int ret; + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + + u8DevNum = g_aunPr2020_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + CVI_TRACE_SNS(CVI_DBG_INFO, "open %s\n", acDevFile); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, pr2020_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int pr2020_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int pr2020_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return 0; + + if (pr2020_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, pr2020_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, pr2020_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (pr2020_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + CVI_TRACE_SNS(CVI_DBG_INFO, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int pr2020_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (pr2020_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + if (pr2020_data_byte == 2) + buf[idx++] = (data >> 8) & 0xff; + + // add data byte 0 + buf[idx++] = data & 0xff; + + ret = write(g_fd[ViPipe], buf, pr2020_addr_byte + pr2020_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + CVI_TRACE_SNS(CVI_DBG_INFO, "i2c w 0x%x 0x%x\n", addr, data); + +#if 0 // read back checing + ret = pr2020_read_register(ViPipe, addr); + if (ret != data) + CVI_TRACE_SNS(CVI_DBG_INFO, "i2c readback-check fail, 0x%x != 0x%x\n", ret, data); +#endif + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void pr2020_fw_init(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe=%d\n", ViPipe); + + pr2020_write_register(ViPipe, 0xFF, 0x00); + pr2020_write_register(ViPipe, 0xD0, 0x30); + pr2020_write_register(ViPipe, 0xD1, 0x08); + pr2020_write_register(ViPipe, 0xD2, 0x21); + pr2020_write_register(ViPipe, 0xD3, 0x00); + pr2020_write_register(ViPipe, 0xD8, 0x37); + pr2020_write_register(ViPipe, 0xD9, 0x08); + + pr2020_write_register(ViPipe, 0xFF, 0x01); + pr2020_write_register(ViPipe, 0x00, 0xE4);//no-video data, 0xe4: black, 0xe5: blue + pr2020_write_register(ViPipe, 0x01, 0x61); + pr2020_write_register(ViPipe, 0x02, 0x00); + pr2020_write_register(ViPipe, 0x03, 0x57); + pr2020_write_register(ViPipe, 0x04, 0x0C); + pr2020_write_register(ViPipe, 0x05, 0x88); + pr2020_write_register(ViPipe, 0x06, 0x04); + pr2020_write_register(ViPipe, 0x07, 0xB2); + pr2020_write_register(ViPipe, 0x08, 0x44); + pr2020_write_register(ViPipe, 0x09, 0x34); + pr2020_write_register(ViPipe, 0x0A, 0x02); + pr2020_write_register(ViPipe, 0x0B, 0x14); + pr2020_write_register(ViPipe, 0x0C, 0x04); + pr2020_write_register(ViPipe, 0x0D, 0x08); + pr2020_write_register(ViPipe, 0x0E, 0x5E); + pr2020_write_register(ViPipe, 0x0F, 0x5E); + pr2020_write_register(ViPipe, 0x10, 0x26); +} + +void pr2020_set_cvbs_ntsc_60(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe=%d\n", ViPipe); + + //Page0 sys + pr2020_write_register(ViPipe, 0xff, 0x00); + pr2020_write_register(ViPipe, 0x10, 0x30); + pr2020_write_register(ViPipe, 0x11, 0x07); + pr2020_write_register(ViPipe, 0x12, 0x00); + pr2020_write_register(ViPipe, 0x13, 0x00); + pr2020_write_register(ViPipe, 0x14, 0x21);//b[1:0); => Select Camera Input. VinP(1), VinN(3), Differ(0). + pr2020_write_register(ViPipe, 0x15, 0x44); + pr2020_write_register(ViPipe, 0x16, 0x0d); + pr2020_write_register(ViPipe, 0x40, 0x00); + pr2020_write_register(ViPipe, 0x47, 0x36); + pr2020_write_register(ViPipe, 0x4e, 0x3f); + pr2020_write_register(ViPipe, 0x80, 0x56); + pr2020_write_register(ViPipe, 0x81, 0x0e); + pr2020_write_register(ViPipe, 0x82, 0x0d); + pr2020_write_register(ViPipe, 0x84, 0x30); + pr2020_write_register(ViPipe, 0x86, 0x20); + pr2020_write_register(ViPipe, 0x87, 0x00); + pr2020_write_register(ViPipe, 0x8a, 0x00); + pr2020_write_register(ViPipe, 0x90, 0x00); + pr2020_write_register(ViPipe, 0x91, 0x00); + pr2020_write_register(ViPipe, 0x92, 0x00); + pr2020_write_register(ViPipe, 0x94, 0xff); + pr2020_write_register(ViPipe, 0x95, 0xff); + pr2020_write_register(ViPipe, 0x96, 0xff); + pr2020_write_register(ViPipe, 0xa0, 0x00); + pr2020_write_register(ViPipe, 0xa1, 0x20); + pr2020_write_register(ViPipe, 0xa4, 0x01); + pr2020_write_register(ViPipe, 0xa5, 0xe3); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0x12); + pr2020_write_register(ViPipe, 0xa8, 0x00); + pr2020_write_register(ViPipe, 0xd0, 0x30); + pr2020_write_register(ViPipe, 0xd1, 0x08); + pr2020_write_register(ViPipe, 0xd2, 0x21); + pr2020_write_register(ViPipe, 0xd3, 0x00); + pr2020_write_register(ViPipe, 0xd8, 0x31); + pr2020_write_register(ViPipe, 0xd9, 0x08); + pr2020_write_register(ViPipe, 0xda, 0x21); + pr2020_write_register(ViPipe, 0xe0, 0x3e); + pr2020_write_register(ViPipe, 0xe1, 0x80); + pr2020_write_register(ViPipe, 0xe2, 0x38); + pr2020_write_register(ViPipe, 0xe3, 0x19); + pr2020_write_register(ViPipe, 0xe4, 0x19); + pr2020_write_register(ViPipe, 0xea, 0x01); + pr2020_write_register(ViPipe, 0xeb, 0xff); + pr2020_write_register(ViPipe, 0xf1, 0x44); + pr2020_write_register(ViPipe, 0xf2, 0x01); + + //Page1 vdec + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x00, 0xe4); + pr2020_write_register(ViPipe, 0x01, 0x61); + pr2020_write_register(ViPipe, 0x02, 0x00); + pr2020_write_register(ViPipe, 0x03, 0x57); + pr2020_write_register(ViPipe, 0x04, 0x0c); + pr2020_write_register(ViPipe, 0x05, 0x88); + pr2020_write_register(ViPipe, 0x06, 0x04); + pr2020_write_register(ViPipe, 0x07, 0xb2); + pr2020_write_register(ViPipe, 0x08, 0x44); + pr2020_write_register(ViPipe, 0x09, 0x34); + pr2020_write_register(ViPipe, 0x0a, 0x02); + pr2020_write_register(ViPipe, 0x0b, 0x14); + pr2020_write_register(ViPipe, 0x0c, 0x04); + pr2020_write_register(ViPipe, 0x0d, 0x08); + pr2020_write_register(ViPipe, 0x0e, 0x5e); + pr2020_write_register(ViPipe, 0x0f, 0x5e); + pr2020_write_register(ViPipe, 0x10, 0x26); + pr2020_write_register(ViPipe, 0x11, 0x00); + pr2020_write_register(ViPipe, 0x12, 0x02); + pr2020_write_register(ViPipe, 0x13, 0x90); + pr2020_write_register(ViPipe, 0x14, 0xd0); + pr2020_write_register(ViPipe, 0x15, 0x10); + pr2020_write_register(ViPipe, 0x16, 0xf0); + pr2020_write_register(ViPipe, 0x17, 0x00); + pr2020_write_register(ViPipe, 0x18, 0x21); + pr2020_write_register(ViPipe, 0x19, 0x4a); + pr2020_write_register(ViPipe, 0x1a, 0x20); + pr2020_write_register(ViPipe, 0x1b, 0x07); + pr2020_write_register(ViPipe, 0x1c, 0x00); + pr2020_write_register(ViPipe, 0x1d, 0x42); + pr2020_write_register(ViPipe, 0x1e, 0x40); + pr2020_write_register(ViPipe, 0x1f, 0xd0); + pr2020_write_register(ViPipe, 0x20, 0x80); + pr2020_write_register(ViPipe, 0x21, 0x70); + pr2020_write_register(ViPipe, 0x22, 0x65); + pr2020_write_register(ViPipe, 0x23, 0x83); + pr2020_write_register(ViPipe, 0x24, 0x80); + pr2020_write_register(ViPipe, 0x25, 0x80); + pr2020_write_register(ViPipe, 0x26, 0x84); + pr2020_write_register(ViPipe, 0x27, 0x80); + pr2020_write_register(ViPipe, 0x28, 0x00); + pr2020_write_register(ViPipe, 0x29, 0x5f); + pr2020_write_register(ViPipe, 0x2a, 0x20); + pr2020_write_register(ViPipe, 0x2b, 0x00); + pr2020_write_register(ViPipe, 0x2c, 0x00); + pr2020_write_register(ViPipe, 0x2d, 0x00); + pr2020_write_register(ViPipe, 0x2e, 0x00); + pr2020_write_register(ViPipe, 0x2f, 0x00); + pr2020_write_register(ViPipe, 0x30, 0x00); + pr2020_write_register(ViPipe, 0x31, 0x00); + pr2020_write_register(ViPipe, 0x32, 0xc0); + pr2020_write_register(ViPipe, 0x33, 0x14); + pr2020_write_register(ViPipe, 0x34, 0x14); + pr2020_write_register(ViPipe, 0x35, 0x80); + pr2020_write_register(ViPipe, 0x36, 0x80); + pr2020_write_register(ViPipe, 0x37, 0xe2); + pr2020_write_register(ViPipe, 0x38, 0x41); + pr2020_write_register(ViPipe, 0x39, 0x00); + pr2020_write_register(ViPipe, 0x3a, 0xac); + pr2020_write_register(ViPipe, 0x3b, 0x04); + pr2020_write_register(ViPipe, 0x3c, 0x01); + pr2020_write_register(ViPipe, 0x3d, 0x21); + pr2020_write_register(ViPipe, 0x3e, 0x06); + pr2020_write_register(ViPipe, 0x3f, 0xd5); + pr2020_write_register(ViPipe, 0x40, 0x05); + pr2020_write_register(ViPipe, 0x41, 0x55); + pr2020_write_register(ViPipe, 0x42, 0x01); + pr2020_write_register(ViPipe, 0x43, 0x30); + pr2020_write_register(ViPipe, 0x44, 0x6a); + pr2020_write_register(ViPipe, 0x45, 0x00); + pr2020_write_register(ViPipe, 0x46, 0x06); + pr2020_write_register(ViPipe, 0x47, 0x2b); + pr2020_write_register(ViPipe, 0x48, 0xb9); + pr2020_write_register(ViPipe, 0x49, 0x00); + pr2020_write_register(ViPipe, 0x4a, 0x7b); + pr2020_write_register(ViPipe, 0x4b, 0x60); + pr2020_write_register(ViPipe, 0x4c, 0x00); + pr2020_write_register(ViPipe, 0x4d, 0x47); + pr2020_write_register(ViPipe, 0x4e, 0x02); + pr2020_write_register(ViPipe, 0x4f, 0x20); + pr2020_write_register(ViPipe, 0x50, 0x01); + pr2020_write_register(ViPipe, 0x51, 0x28); + pr2020_write_register(ViPipe, 0x52, 0x40); + pr2020_write_register(ViPipe, 0x53, 0x0c); + pr2020_write_register(ViPipe, 0x54, 0x0f); + pr2020_write_register(ViPipe, 0x55, 0x8d); + pr2020_write_register(ViPipe, 0x70, 0x06); + pr2020_write_register(ViPipe, 0x71, 0x08); + pr2020_write_register(ViPipe, 0x72, 0x0a); + pr2020_write_register(ViPipe, 0x73, 0x0c); + pr2020_write_register(ViPipe, 0x74, 0x0e); + pr2020_write_register(ViPipe, 0x75, 0x10); + pr2020_write_register(ViPipe, 0x76, 0x12); + pr2020_write_register(ViPipe, 0x77, 0x14); + pr2020_write_register(ViPipe, 0x78, 0x06); + pr2020_write_register(ViPipe, 0x79, 0x08); + pr2020_write_register(ViPipe, 0x7a, 0x0a); + pr2020_write_register(ViPipe, 0x7b, 0x0c); + pr2020_write_register(ViPipe, 0x7c, 0x0e); + pr2020_write_register(ViPipe, 0x7d, 0x10); + pr2020_write_register(ViPipe, 0x7e, 0x12); + pr2020_write_register(ViPipe, 0x7f, 0x14); + pr2020_write_register(ViPipe, 0x80, 0x00); + pr2020_write_register(ViPipe, 0x81, 0x09); + pr2020_write_register(ViPipe, 0x82, 0x00); + pr2020_write_register(ViPipe, 0x83, 0x07); + pr2020_write_register(ViPipe, 0x84, 0x00); + pr2020_write_register(ViPipe, 0x85, 0x17); + pr2020_write_register(ViPipe, 0x86, 0x03); + pr2020_write_register(ViPipe, 0x87, 0xe5); + pr2020_write_register(ViPipe, 0x88, 0x04); + pr2020_write_register(ViPipe, 0x89, 0x48); + pr2020_write_register(ViPipe, 0x8a, 0x04); + pr2020_write_register(ViPipe, 0x8b, 0x48); + pr2020_write_register(ViPipe, 0x8c, 0x05); + pr2020_write_register(ViPipe, 0x8d, 0xf0); + pr2020_write_register(ViPipe, 0x8e, 0x05); + pr2020_write_register(ViPipe, 0x8f, 0x47); + pr2020_write_register(ViPipe, 0x90, 0x03); + pr2020_write_register(ViPipe, 0x91, 0x13); + pr2020_write_register(ViPipe, 0x92, 0x73); + pr2020_write_register(ViPipe, 0x93, 0xe8); + pr2020_write_register(ViPipe, 0x94, 0x0f); + pr2020_write_register(ViPipe, 0x95, 0x5e); + pr2020_write_register(ViPipe, 0x96, 0x03); + pr2020_write_register(ViPipe, 0x97, 0xd0); + pr2020_write_register(ViPipe, 0x98, 0x17); + pr2020_write_register(ViPipe, 0x99, 0x34); + pr2020_write_register(ViPipe, 0x9a, 0x13); + pr2020_write_register(ViPipe, 0x9b, 0x56); + pr2020_write_register(ViPipe, 0x9c, 0x0b); + pr2020_write_register(ViPipe, 0x9d, 0x9a); + pr2020_write_register(ViPipe, 0x9e, 0x09); + pr2020_write_register(ViPipe, 0x9f, 0xab); + pr2020_write_register(ViPipe, 0xa0, 0x01); + pr2020_write_register(ViPipe, 0xa1, 0x74); + pr2020_write_register(ViPipe, 0xa2, 0x01); + pr2020_write_register(ViPipe, 0xa3, 0x6b); + pr2020_write_register(ViPipe, 0xa4, 0x00); + pr2020_write_register(ViPipe, 0xa5, 0xba); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0xa3); + pr2020_write_register(ViPipe, 0xa8, 0x01); + pr2020_write_register(ViPipe, 0xa9, 0x39); + pr2020_write_register(ViPipe, 0xaa, 0x01); + pr2020_write_register(ViPipe, 0xab, 0x39); + pr2020_write_register(ViPipe, 0xac, 0x00); + pr2020_write_register(ViPipe, 0xad, 0xc1); + pr2020_write_register(ViPipe, 0xae, 0x00); + pr2020_write_register(ViPipe, 0xaf, 0xc1); + pr2020_write_register(ViPipe, 0xb0, 0x04); + pr2020_write_register(ViPipe, 0xb1, 0xd4); + pr2020_write_register(ViPipe, 0xb2, 0x07); + pr2020_write_register(ViPipe, 0xb3, 0xda); + pr2020_write_register(ViPipe, 0xb4, 0x00); + pr2020_write_register(ViPipe, 0xb5, 0x17); + pr2020_write_register(ViPipe, 0xb6, 0x08); + pr2020_write_register(ViPipe, 0xb7, 0xe8); + pr2020_write_register(ViPipe, 0xb8, 0xb0); + pr2020_write_register(ViPipe, 0xb9, 0xce); + pr2020_write_register(ViPipe, 0xba, 0x90); + pr2020_write_register(ViPipe, 0xbb, 0x10); + pr2020_write_register(ViPipe, 0xbc, 0x00); + pr2020_write_register(ViPipe, 0xbd, 0x04); + pr2020_write_register(ViPipe, 0xbe, 0x02); + pr2020_write_register(ViPipe, 0xbf, 0xd0); + pr2020_write_register(ViPipe, 0xc0, 0x00); + pr2020_write_register(ViPipe, 0xc1, 0x10); + pr2020_write_register(ViPipe, 0xc2, 0x00); + pr2020_write_register(ViPipe, 0xc3, 0xf0); + + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0e); + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0f); +} + +void pr2020_set_cvbs_pal_50(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe=%d\n", ViPipe); + + //Page0 sys + pr2020_write_register(ViPipe, 0xff, 0x00); + pr2020_write_register(ViPipe, 0x10, 0x21); + pr2020_write_register(ViPipe, 0x11, 0x07); + pr2020_write_register(ViPipe, 0x12, 0x00); + pr2020_write_register(ViPipe, 0x13, 0x00); + pr2020_write_register(ViPipe, 0x14, 0x21);//b[1:0); => Select Camera Input. VinP(1), VinN(3), Differ(0). + pr2020_write_register(ViPipe, 0x15, 0x44); + pr2020_write_register(ViPipe, 0x16, 0x0d); + pr2020_write_register(ViPipe, 0x40, 0x00); + pr2020_write_register(ViPipe, 0x47, 0x36); + pr2020_write_register(ViPipe, 0x4e, 0x3f); + pr2020_write_register(ViPipe, 0x80, 0x56); + pr2020_write_register(ViPipe, 0x81, 0x0e); + pr2020_write_register(ViPipe, 0x82, 0x0d); + pr2020_write_register(ViPipe, 0x84, 0x30); + pr2020_write_register(ViPipe, 0x86, 0x20); + pr2020_write_register(ViPipe, 0x87, 0x00); + pr2020_write_register(ViPipe, 0x8a, 0x00); + pr2020_write_register(ViPipe, 0x90, 0x00); + pr2020_write_register(ViPipe, 0x91, 0x00); + pr2020_write_register(ViPipe, 0x92, 0x00); + pr2020_write_register(ViPipe, 0x94, 0xff); + pr2020_write_register(ViPipe, 0x95, 0xff); + pr2020_write_register(ViPipe, 0x96, 0xff); + pr2020_write_register(ViPipe, 0xa0, 0x00); + pr2020_write_register(ViPipe, 0xa1, 0x20); + pr2020_write_register(ViPipe, 0xa4, 0x01); + pr2020_write_register(ViPipe, 0xa5, 0xe3); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0x12); + pr2020_write_register(ViPipe, 0xa8, 0x00); + pr2020_write_register(ViPipe, 0xd0, 0x30); + pr2020_write_register(ViPipe, 0xd1, 0x08); + pr2020_write_register(ViPipe, 0xd2, 0x21); + pr2020_write_register(ViPipe, 0xd3, 0x00); + pr2020_write_register(ViPipe, 0xd8, 0x31); + pr2020_write_register(ViPipe, 0xd9, 0x08); + pr2020_write_register(ViPipe, 0xda, 0x21); + pr2020_write_register(ViPipe, 0xe0, 0x3e); + pr2020_write_register(ViPipe, 0xe1, 0x80); + pr2020_write_register(ViPipe, 0xe2, 0x38); + pr2020_write_register(ViPipe, 0xe3, 0x19); + pr2020_write_register(ViPipe, 0xe4, 0x19); + pr2020_write_register(ViPipe, 0xea, 0x01); + pr2020_write_register(ViPipe, 0xeb, 0xff); + pr2020_write_register(ViPipe, 0xf1, 0x44); + pr2020_write_register(ViPipe, 0xf2, 0x01); + + //Page1 vdec + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x00, 0xe4); + pr2020_write_register(ViPipe, 0x01, 0x61); + pr2020_write_register(ViPipe, 0x02, 0x00); + pr2020_write_register(ViPipe, 0x03, 0x57); + pr2020_write_register(ViPipe, 0x04, 0x0c); + pr2020_write_register(ViPipe, 0x05, 0x88); + pr2020_write_register(ViPipe, 0x06, 0x04); + pr2020_write_register(ViPipe, 0x07, 0xb2); + pr2020_write_register(ViPipe, 0x08, 0x44); + pr2020_write_register(ViPipe, 0x09, 0x34); + pr2020_write_register(ViPipe, 0x0a, 0x02); + pr2020_write_register(ViPipe, 0x0b, 0x14); + pr2020_write_register(ViPipe, 0x0c, 0x04); + pr2020_write_register(ViPipe, 0x0d, 0x08); + pr2020_write_register(ViPipe, 0x0e, 0x5e); + pr2020_write_register(ViPipe, 0x0f, 0x5e); + pr2020_write_register(ViPipe, 0x10, 0x26); + pr2020_write_register(ViPipe, 0x11, 0x00); + pr2020_write_register(ViPipe, 0x12, 0x22); + pr2020_write_register(ViPipe, 0x13, 0xe0); + pr2020_write_register(ViPipe, 0x14, 0xd0); + pr2020_write_register(ViPipe, 0x15, 0x16); + pr2020_write_register(ViPipe, 0x16, 0x20); + pr2020_write_register(ViPipe, 0x17, 0x00); + pr2020_write_register(ViPipe, 0x18, 0x21); + pr2020_write_register(ViPipe, 0x19, 0x4a); + pr2020_write_register(ViPipe, 0x1a, 0x20); + pr2020_write_register(ViPipe, 0x1b, 0x06); + pr2020_write_register(ViPipe, 0x1c, 0x31); + pr2020_write_register(ViPipe, 0x1d, 0x42); + pr2020_write_register(ViPipe, 0x1e, 0x50); + pr2020_write_register(ViPipe, 0x1f, 0xd0); + pr2020_write_register(ViPipe, 0x20, 0x80); + pr2020_write_register(ViPipe, 0x21, 0x75); + pr2020_write_register(ViPipe, 0x22, 0x65); + pr2020_write_register(ViPipe, 0x23, 0x83); + pr2020_write_register(ViPipe, 0x24, 0x80); + pr2020_write_register(ViPipe, 0x25, 0x80); + pr2020_write_register(ViPipe, 0x26, 0x84); + pr2020_write_register(ViPipe, 0x27, 0x80); + pr2020_write_register(ViPipe, 0x28, 0x00); + pr2020_write_register(ViPipe, 0x29, 0x5f); + pr2020_write_register(ViPipe, 0x2a, 0x20); + pr2020_write_register(ViPipe, 0x2b, 0x00); + pr2020_write_register(ViPipe, 0x2c, 0x00); + pr2020_write_register(ViPipe, 0x2d, 0x00); + pr2020_write_register(ViPipe, 0x2e, 0x00); + pr2020_write_register(ViPipe, 0x2f, 0x00); + pr2020_write_register(ViPipe, 0x30, 0x00); + pr2020_write_register(ViPipe, 0x31, 0x00); + pr2020_write_register(ViPipe, 0x32, 0xc0); + pr2020_write_register(ViPipe, 0x33, 0x20); + pr2020_write_register(ViPipe, 0x34, 0x20); + pr2020_write_register(ViPipe, 0x35, 0x10); + pr2020_write_register(ViPipe, 0x36, 0x10); + pr2020_write_register(ViPipe, 0x37, 0xc4); + pr2020_write_register(ViPipe, 0x38, 0x42); + pr2020_write_register(ViPipe, 0x39, 0x00); + pr2020_write_register(ViPipe, 0x3a, 0xac); + pr2020_write_register(ViPipe, 0x3b, 0x04); + pr2020_write_register(ViPipe, 0x3c, 0x01); + pr2020_write_register(ViPipe, 0x3d, 0x21); + pr2020_write_register(ViPipe, 0x3e, 0x06); + pr2020_write_register(ViPipe, 0x3f, 0xd5); + pr2020_write_register(ViPipe, 0x40, 0x85); + pr2020_write_register(ViPipe, 0x41, 0x55); + pr2020_write_register(ViPipe, 0x42, 0x01); + pr2020_write_register(ViPipe, 0x43, 0x31); + pr2020_write_register(ViPipe, 0x44, 0x6a); + pr2020_write_register(ViPipe, 0x45, 0x00); + pr2020_write_register(ViPipe, 0x46, 0x07); + pr2020_write_register(ViPipe, 0x47, 0xa4); + pr2020_write_register(ViPipe, 0x48, 0xa5); + pr2020_write_register(ViPipe, 0x49, 0x00); + pr2020_write_register(ViPipe, 0x4a, 0x7b); + pr2020_write_register(ViPipe, 0x4b, 0x60); + pr2020_write_register(ViPipe, 0x4c, 0x00); + pr2020_write_register(ViPipe, 0x4d, 0x47); + pr2020_write_register(ViPipe, 0x4e, 0x02); + pr2020_write_register(ViPipe, 0x4f, 0x20); + pr2020_write_register(ViPipe, 0x50, 0x01); + pr2020_write_register(ViPipe, 0x51, 0x28); + pr2020_write_register(ViPipe, 0x52, 0x40); + pr2020_write_register(ViPipe, 0x53, 0x0c); + pr2020_write_register(ViPipe, 0x54, 0x0f); + pr2020_write_register(ViPipe, 0x55, 0x8d); + pr2020_write_register(ViPipe, 0x70, 0x06); + pr2020_write_register(ViPipe, 0x71, 0x08); + pr2020_write_register(ViPipe, 0x72, 0x0a); + pr2020_write_register(ViPipe, 0x73, 0x0c); + pr2020_write_register(ViPipe, 0x74, 0x0e); + pr2020_write_register(ViPipe, 0x75, 0x10); + pr2020_write_register(ViPipe, 0x76, 0x12); + pr2020_write_register(ViPipe, 0x77, 0x14); + pr2020_write_register(ViPipe, 0x78, 0x06); + pr2020_write_register(ViPipe, 0x79, 0x08); + pr2020_write_register(ViPipe, 0x7a, 0x0a); + pr2020_write_register(ViPipe, 0x7b, 0x0c); + pr2020_write_register(ViPipe, 0x7c, 0x0e); + pr2020_write_register(ViPipe, 0x7d, 0x10); + pr2020_write_register(ViPipe, 0x7e, 0x12); + pr2020_write_register(ViPipe, 0x7f, 0x14); + pr2020_write_register(ViPipe, 0x80, 0x00); + pr2020_write_register(ViPipe, 0x81, 0x09); + pr2020_write_register(ViPipe, 0x82, 0x00); + pr2020_write_register(ViPipe, 0x83, 0x07); + pr2020_write_register(ViPipe, 0x84, 0x00); + pr2020_write_register(ViPipe, 0x85, 0x17); + pr2020_write_register(ViPipe, 0x86, 0x03); + pr2020_write_register(ViPipe, 0x87, 0xe5); + pr2020_write_register(ViPipe, 0x88, 0x05); + pr2020_write_register(ViPipe, 0x89, 0x24); + pr2020_write_register(ViPipe, 0x8a, 0x05); + pr2020_write_register(ViPipe, 0x8b, 0x24); + pr2020_write_register(ViPipe, 0x8c, 0x05); + pr2020_write_register(ViPipe, 0x8d, 0xf0); + pr2020_write_register(ViPipe, 0x8e, 0x05); + pr2020_write_register(ViPipe, 0x8f, 0x47); + pr2020_write_register(ViPipe, 0x90, 0x02); + pr2020_write_register(ViPipe, 0x91, 0xb4); + pr2020_write_register(ViPipe, 0x92, 0x73); + pr2020_write_register(ViPipe, 0x93, 0xe8); + pr2020_write_register(ViPipe, 0x94, 0x0f); + pr2020_write_register(ViPipe, 0x95, 0x5e); + pr2020_write_register(ViPipe, 0x96, 0x03); + pr2020_write_register(ViPipe, 0x97, 0xd0); + pr2020_write_register(ViPipe, 0x98, 0x17); + pr2020_write_register(ViPipe, 0x99, 0x34); + pr2020_write_register(ViPipe, 0x9a, 0x13); + pr2020_write_register(ViPipe, 0x9b, 0x56); + pr2020_write_register(ViPipe, 0x9c, 0x0b); + pr2020_write_register(ViPipe, 0x9d, 0x9a); + pr2020_write_register(ViPipe, 0x9e, 0x09); + pr2020_write_register(ViPipe, 0x9f, 0xab); + pr2020_write_register(ViPipe, 0xa0, 0x01); + pr2020_write_register(ViPipe, 0xa1, 0x74); + pr2020_write_register(ViPipe, 0xa2, 0x01); + pr2020_write_register(ViPipe, 0xa3, 0x6b); + pr2020_write_register(ViPipe, 0xa4, 0x00); + pr2020_write_register(ViPipe, 0xa5, 0xba); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0xa3); + pr2020_write_register(ViPipe, 0xa8, 0x01); + pr2020_write_register(ViPipe, 0xa9, 0x39); + pr2020_write_register(ViPipe, 0xaa, 0x01); + pr2020_write_register(ViPipe, 0xab, 0x39); + pr2020_write_register(ViPipe, 0xac, 0x00); + pr2020_write_register(ViPipe, 0xad, 0xc1); + pr2020_write_register(ViPipe, 0xae, 0x00); + pr2020_write_register(ViPipe, 0xaf, 0xc1); + pr2020_write_register(ViPipe, 0xb0, 0x05); + pr2020_write_register(ViPipe, 0xb1, 0xcc); + pr2020_write_register(ViPipe, 0xb2, 0x09); + pr2020_write_register(ViPipe, 0xb3, 0x6d); + pr2020_write_register(ViPipe, 0xb4, 0x00); + pr2020_write_register(ViPipe, 0xb5, 0x17); + pr2020_write_register(ViPipe, 0xb6, 0x08); + pr2020_write_register(ViPipe, 0xb7, 0xe8); + pr2020_write_register(ViPipe, 0xb8, 0xb0); + pr2020_write_register(ViPipe, 0xb9, 0xce); + pr2020_write_register(ViPipe, 0xba, 0x90); + pr2020_write_register(ViPipe, 0xbb, 0x10); + pr2020_write_register(ViPipe, 0xbc, 0x00); + pr2020_write_register(ViPipe, 0xbd, 0x04); + pr2020_write_register(ViPipe, 0xbe, 0x02); + pr2020_write_register(ViPipe, 0xbf, 0xd0); + pr2020_write_register(ViPipe, 0xc0, 0x00); + pr2020_write_register(ViPipe, 0xc1, 0x16); + pr2020_write_register(ViPipe, 0xc2, 0x01); + pr2020_write_register(ViPipe, 0xc3, 0x20); + + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0e); + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0f); +} + +void pr2020_set_720p_25(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe=%d\n", ViPipe); + + //Page0 sys + pr2020_write_register(ViPipe, 0xff, 0x00); + pr2020_write_register(ViPipe, 0x10, 0x82); + pr2020_write_register(ViPipe, 0x11, 0x07); + pr2020_write_register(ViPipe, 0x12, 0x00); + pr2020_write_register(ViPipe, 0x13, 0x00); + pr2020_write_register(ViPipe, 0x14, 0x21);//b[1:0); => Select Camera Input. VinP(1), VinN(3), Differ(0). + pr2020_write_register(ViPipe, 0x15, 0x44); + pr2020_write_register(ViPipe, 0x16, 0x0d); + pr2020_write_register(ViPipe, 0x40, 0x00); + pr2020_write_register(ViPipe, 0x47, 0x3a); + pr2020_write_register(ViPipe, 0x4e, 0x3f); + pr2020_write_register(ViPipe, 0x80, 0x56); + pr2020_write_register(ViPipe, 0x81, 0x0e); + pr2020_write_register(ViPipe, 0x82, 0x0d); + pr2020_write_register(ViPipe, 0x84, 0x30); + pr2020_write_register(ViPipe, 0x86, 0x20); + pr2020_write_register(ViPipe, 0x87, 0x00); + pr2020_write_register(ViPipe, 0x8a, 0x00); + pr2020_write_register(ViPipe, 0x90, 0x00); + pr2020_write_register(ViPipe, 0x91, 0x00); + pr2020_write_register(ViPipe, 0x92, 0x00); + pr2020_write_register(ViPipe, 0x94, 0xff); + pr2020_write_register(ViPipe, 0x95, 0xff); + pr2020_write_register(ViPipe, 0x96, 0xff); + pr2020_write_register(ViPipe, 0xa0, 0x00); + pr2020_write_register(ViPipe, 0xa1, 0x20); + pr2020_write_register(ViPipe, 0xa4, 0x01); + pr2020_write_register(ViPipe, 0xa5, 0xe3); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0x12); + pr2020_write_register(ViPipe, 0xa8, 0x00); + pr2020_write_register(ViPipe, 0xd0, 0x30); + pr2020_write_register(ViPipe, 0xd1, 0x08); + pr2020_write_register(ViPipe, 0xd2, 0x21); + pr2020_write_register(ViPipe, 0xd3, 0x00); + pr2020_write_register(ViPipe, 0xd8, 0x31); + pr2020_write_register(ViPipe, 0xd9, 0x08); + pr2020_write_register(ViPipe, 0xda, 0x21); + pr2020_write_register(ViPipe, 0xe0, 0x39); + pr2020_write_register(ViPipe, 0xe1, 0x90); + pr2020_write_register(ViPipe, 0xe2, 0x38); + pr2020_write_register(ViPipe, 0xe3, 0x19); + pr2020_write_register(ViPipe, 0xe4, 0x19); + pr2020_write_register(ViPipe, 0xea, 0x01); + pr2020_write_register(ViPipe, 0xeb, 0xff); + pr2020_write_register(ViPipe, 0xf1, 0x44); + pr2020_write_register(ViPipe, 0xf2, 0x01); + + //Page1 vdec + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x00, 0xe4); + pr2020_write_register(ViPipe, 0x01, 0x61); + pr2020_write_register(ViPipe, 0x02, 0x00); + pr2020_write_register(ViPipe, 0x03, 0x57); + pr2020_write_register(ViPipe, 0x04, 0x0c); + pr2020_write_register(ViPipe, 0x05, 0x88); + pr2020_write_register(ViPipe, 0x06, 0x04); + pr2020_write_register(ViPipe, 0x07, 0xb2); + pr2020_write_register(ViPipe, 0x08, 0x44); + pr2020_write_register(ViPipe, 0x09, 0x34); + pr2020_write_register(ViPipe, 0x0a, 0x02); + pr2020_write_register(ViPipe, 0x0b, 0x14); + pr2020_write_register(ViPipe, 0x0c, 0x04); + pr2020_write_register(ViPipe, 0x0d, 0x08); + pr2020_write_register(ViPipe, 0x0e, 0x5e); + pr2020_write_register(ViPipe, 0x0f, 0x5e); + pr2020_write_register(ViPipe, 0x10, 0x26); + pr2020_write_register(ViPipe, 0x11, 0x01); + pr2020_write_register(ViPipe, 0x12, 0x45); + pr2020_write_register(ViPipe, 0x13, 0x0c); + pr2020_write_register(ViPipe, 0x14, 0x00); + pr2020_write_register(ViPipe, 0x15, 0x1b); + pr2020_write_register(ViPipe, 0x16, 0xd0); + pr2020_write_register(ViPipe, 0x17, 0x00); + pr2020_write_register(ViPipe, 0x18, 0x41); + pr2020_write_register(ViPipe, 0x19, 0x46); + pr2020_write_register(ViPipe, 0x1a, 0x22); + pr2020_write_register(ViPipe, 0x1b, 0x05); + pr2020_write_register(ViPipe, 0x1c, 0xea); + pr2020_write_register(ViPipe, 0x1d, 0x45); + pr2020_write_register(ViPipe, 0x1e, 0x4c); + pr2020_write_register(ViPipe, 0x1f, 0x00); + pr2020_write_register(ViPipe, 0x20, 0x80); + pr2020_write_register(ViPipe, 0x21, 0x80); + pr2020_write_register(ViPipe, 0x22, 0x90); + pr2020_write_register(ViPipe, 0x23, 0x80); + pr2020_write_register(ViPipe, 0x24, 0x80); + pr2020_write_register(ViPipe, 0x25, 0x80); + pr2020_write_register(ViPipe, 0x26, 0x84); + pr2020_write_register(ViPipe, 0x27, 0x82); + pr2020_write_register(ViPipe, 0x28, 0x00); + pr2020_write_register(ViPipe, 0x29, 0x7d); + pr2020_write_register(ViPipe, 0x2a, 0x00); + pr2020_write_register(ViPipe, 0x2b, 0x00); + pr2020_write_register(ViPipe, 0x2c, 0x00); + pr2020_write_register(ViPipe, 0x2d, 0x00); + pr2020_write_register(ViPipe, 0x2e, 0x00); + pr2020_write_register(ViPipe, 0x2f, 0x00); + pr2020_write_register(ViPipe, 0x30, 0x00); + pr2020_write_register(ViPipe, 0x31, 0x00); + pr2020_write_register(ViPipe, 0x32, 0xc0); + pr2020_write_register(ViPipe, 0x33, 0x14); + pr2020_write_register(ViPipe, 0x34, 0x14); + pr2020_write_register(ViPipe, 0x35, 0x80); + pr2020_write_register(ViPipe, 0x36, 0x80); + pr2020_write_register(ViPipe, 0x37, 0xaa); + pr2020_write_register(ViPipe, 0x38, 0x48); + pr2020_write_register(ViPipe, 0x39, 0x08); + pr2020_write_register(ViPipe, 0x3a, 0x27); + pr2020_write_register(ViPipe, 0x3b, 0x02); + pr2020_write_register(ViPipe, 0x3c, 0x01); + pr2020_write_register(ViPipe, 0x3d, 0x23); + pr2020_write_register(ViPipe, 0x3e, 0x02); + pr2020_write_register(ViPipe, 0x3f, 0xc4); + pr2020_write_register(ViPipe, 0x40, 0x05); + pr2020_write_register(ViPipe, 0x41, 0x55); + pr2020_write_register(ViPipe, 0x42, 0x01); + pr2020_write_register(ViPipe, 0x43, 0x33); + pr2020_write_register(ViPipe, 0x44, 0x6a); + pr2020_write_register(ViPipe, 0x45, 0x00); + pr2020_write_register(ViPipe, 0x46, 0x09); + pr2020_write_register(ViPipe, 0x47, 0xe2); + pr2020_write_register(ViPipe, 0x48, 0x01); + pr2020_write_register(ViPipe, 0x49, 0x00); + pr2020_write_register(ViPipe, 0x4a, 0x7b); + pr2020_write_register(ViPipe, 0x4b, 0x60); + pr2020_write_register(ViPipe, 0x4c, 0x00); + pr2020_write_register(ViPipe, 0x4d, 0x4a); + pr2020_write_register(ViPipe, 0x4e, 0x00); + pr2020_write_register(ViPipe, 0x4f, 0x20); + pr2020_write_register(ViPipe, 0x50, 0x01); + pr2020_write_register(ViPipe, 0x51, 0x28); + pr2020_write_register(ViPipe, 0x52, 0x40); + pr2020_write_register(ViPipe, 0x53, 0x0c); + pr2020_write_register(ViPipe, 0x54, 0x0f); + pr2020_write_register(ViPipe, 0x55, 0x8d); + pr2020_write_register(ViPipe, 0x70, 0x06); + pr2020_write_register(ViPipe, 0x71, 0x08); + pr2020_write_register(ViPipe, 0x72, 0x0a); + pr2020_write_register(ViPipe, 0x73, 0x0c); + pr2020_write_register(ViPipe, 0x74, 0x0e); + pr2020_write_register(ViPipe, 0x75, 0x10); + pr2020_write_register(ViPipe, 0x76, 0x12); + pr2020_write_register(ViPipe, 0x77, 0x14); + pr2020_write_register(ViPipe, 0x78, 0x06); + pr2020_write_register(ViPipe, 0x79, 0x08); + pr2020_write_register(ViPipe, 0x7a, 0x0a); + pr2020_write_register(ViPipe, 0x7b, 0x0c); + pr2020_write_register(ViPipe, 0x7c, 0x0e); + pr2020_write_register(ViPipe, 0x7d, 0x10); + pr2020_write_register(ViPipe, 0x7e, 0x12); + pr2020_write_register(ViPipe, 0x7f, 0x14); + pr2020_write_register(ViPipe, 0x80, 0x00); + pr2020_write_register(ViPipe, 0x81, 0x09); + pr2020_write_register(ViPipe, 0x82, 0x00); + pr2020_write_register(ViPipe, 0x83, 0x07); + pr2020_write_register(ViPipe, 0x84, 0x00); + pr2020_write_register(ViPipe, 0x85, 0x17); + pr2020_write_register(ViPipe, 0x86, 0x03); + pr2020_write_register(ViPipe, 0x87, 0xe5); + pr2020_write_register(ViPipe, 0x88, 0x0a); + pr2020_write_register(ViPipe, 0x89, 0x48); + pr2020_write_register(ViPipe, 0x8a, 0x0a); + pr2020_write_register(ViPipe, 0x8b, 0x48); + pr2020_write_register(ViPipe, 0x8c, 0x0b); + pr2020_write_register(ViPipe, 0x8d, 0xe0); + pr2020_write_register(ViPipe, 0x8e, 0x05); + pr2020_write_register(ViPipe, 0x8f, 0x47); + pr2020_write_register(ViPipe, 0x90, 0x05); + pr2020_write_register(ViPipe, 0x91, 0x69); + pr2020_write_register(ViPipe, 0x92, 0x73); + pr2020_write_register(ViPipe, 0x93, 0xe8); + pr2020_write_register(ViPipe, 0x94, 0x0f); + pr2020_write_register(ViPipe, 0x95, 0x5e); + pr2020_write_register(ViPipe, 0x96, 0x07); + pr2020_write_register(ViPipe, 0x97, 0x90); + pr2020_write_register(ViPipe, 0x98, 0x17); + pr2020_write_register(ViPipe, 0x99, 0x34); + pr2020_write_register(ViPipe, 0x9a, 0x13); + pr2020_write_register(ViPipe, 0x9b, 0x56); + pr2020_write_register(ViPipe, 0x9c, 0x0b); + pr2020_write_register(ViPipe, 0x9d, 0x9a); + pr2020_write_register(ViPipe, 0x9e, 0x09); + pr2020_write_register(ViPipe, 0x9f, 0xab); + pr2020_write_register(ViPipe, 0xa0, 0x01); + pr2020_write_register(ViPipe, 0xa1, 0x74); + pr2020_write_register(ViPipe, 0xa2, 0x01); + pr2020_write_register(ViPipe, 0xa3, 0x6b); + pr2020_write_register(ViPipe, 0xa4, 0x00); + pr2020_write_register(ViPipe, 0xa5, 0xba); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0xa3); + pr2020_write_register(ViPipe, 0xa8, 0x01); + pr2020_write_register(ViPipe, 0xa9, 0x39); + pr2020_write_register(ViPipe, 0xaa, 0x01); + pr2020_write_register(ViPipe, 0xab, 0x39); + pr2020_write_register(ViPipe, 0xac, 0x00); + pr2020_write_register(ViPipe, 0xad, 0xc1); + pr2020_write_register(ViPipe, 0xae, 0x00); + pr2020_write_register(ViPipe, 0xaf, 0xc1); + pr2020_write_register(ViPipe, 0xb0, 0x0b); + pr2020_write_register(ViPipe, 0xb1, 0x99); + pr2020_write_register(ViPipe, 0xb2, 0x12); + pr2020_write_register(ViPipe, 0xb3, 0xca); + pr2020_write_register(ViPipe, 0xb4, 0x00); + pr2020_write_register(ViPipe, 0xb5, 0x17); + pr2020_write_register(ViPipe, 0xb6, 0x08); + pr2020_write_register(ViPipe, 0xb7, 0xe8); + pr2020_write_register(ViPipe, 0xb8, 0xb0); + pr2020_write_register(ViPipe, 0xb9, 0xce); + pr2020_write_register(ViPipe, 0xba, 0x90); + pr2020_write_register(ViPipe, 0xbb, 0x00); + pr2020_write_register(ViPipe, 0xbc, 0x00); + pr2020_write_register(ViPipe, 0xbd, 0x04); + pr2020_write_register(ViPipe, 0xbe, 0x05); + pr2020_write_register(ViPipe, 0xbf, 0x00); + pr2020_write_register(ViPipe, 0xc0, 0x00); + pr2020_write_register(ViPipe, 0xc1, 0x12); + pr2020_write_register(ViPipe, 0xc2, 0x02); + pr2020_write_register(ViPipe, 0xc3, 0xd0); + + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0e); + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0f); +} + +void pr2020_set_720p_30(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe=%d\n", ViPipe); + + //Page0 sys + pr2020_write_register(ViPipe, 0xff, 0x00); + pr2020_write_register(ViPipe, 0x10, 0x92); + pr2020_write_register(ViPipe, 0x11, 0x07); + pr2020_write_register(ViPipe, 0x12, 0x00); + pr2020_write_register(ViPipe, 0x13, 0x00); + pr2020_write_register(ViPipe, 0x14, 0x21);//b[1:0); => Select Camera Input. VinP(1), VinN(3), Differ(0). + pr2020_write_register(ViPipe, 0x15, 0x44); + pr2020_write_register(ViPipe, 0x16, 0x0d); + pr2020_write_register(ViPipe, 0x40, 0x00); + pr2020_write_register(ViPipe, 0x47, 0x3a); + pr2020_write_register(ViPipe, 0x4e, 0x3f); + pr2020_write_register(ViPipe, 0x80, 0x56); + pr2020_write_register(ViPipe, 0x81, 0x0e); + pr2020_write_register(ViPipe, 0x82, 0x0d); + pr2020_write_register(ViPipe, 0x84, 0x30); + pr2020_write_register(ViPipe, 0x86, 0x20); + pr2020_write_register(ViPipe, 0x87, 0x00); + pr2020_write_register(ViPipe, 0x8a, 0x00); + pr2020_write_register(ViPipe, 0x90, 0x00); + pr2020_write_register(ViPipe, 0x91, 0x00); + pr2020_write_register(ViPipe, 0x92, 0x00); + pr2020_write_register(ViPipe, 0x94, 0xff); + pr2020_write_register(ViPipe, 0x95, 0xff); + pr2020_write_register(ViPipe, 0x96, 0xff); + pr2020_write_register(ViPipe, 0xa0, 0x00); + pr2020_write_register(ViPipe, 0xa1, 0x20); + pr2020_write_register(ViPipe, 0xa4, 0x01); + pr2020_write_register(ViPipe, 0xa5, 0xe3); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0x12); + pr2020_write_register(ViPipe, 0xa8, 0x00); + pr2020_write_register(ViPipe, 0xd0, 0x30); + pr2020_write_register(ViPipe, 0xd1, 0x08); + pr2020_write_register(ViPipe, 0xd2, 0x21); + pr2020_write_register(ViPipe, 0xd3, 0x00); + pr2020_write_register(ViPipe, 0xd8, 0x31); + pr2020_write_register(ViPipe, 0xd9, 0x08); + pr2020_write_register(ViPipe, 0xda, 0x21); + pr2020_write_register(ViPipe, 0xe0, 0x39); + pr2020_write_register(ViPipe, 0xe1, 0x90); + pr2020_write_register(ViPipe, 0xe2, 0x38); + pr2020_write_register(ViPipe, 0xe3, 0x19); + pr2020_write_register(ViPipe, 0xe4, 0x19); + pr2020_write_register(ViPipe, 0xea, 0x01); + pr2020_write_register(ViPipe, 0xeb, 0xff); + pr2020_write_register(ViPipe, 0xf1, 0x44); + pr2020_write_register(ViPipe, 0xf2, 0x01); + + //Page1 vdec + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x00, 0xe4); + pr2020_write_register(ViPipe, 0x01, 0x61); + pr2020_write_register(ViPipe, 0x02, 0x00); + pr2020_write_register(ViPipe, 0x03, 0x57); + pr2020_write_register(ViPipe, 0x04, 0x0c); + pr2020_write_register(ViPipe, 0x05, 0x88); + pr2020_write_register(ViPipe, 0x06, 0x04); + pr2020_write_register(ViPipe, 0x07, 0xb2); + pr2020_write_register(ViPipe, 0x08, 0x44); + pr2020_write_register(ViPipe, 0x09, 0x34); + pr2020_write_register(ViPipe, 0x0a, 0x02); + pr2020_write_register(ViPipe, 0x0b, 0x14); + pr2020_write_register(ViPipe, 0x0c, 0x04); + pr2020_write_register(ViPipe, 0x0d, 0x08); + pr2020_write_register(ViPipe, 0x0e, 0x5e); + pr2020_write_register(ViPipe, 0x0f, 0x5e); + pr2020_write_register(ViPipe, 0x10, 0x26); + pr2020_write_register(ViPipe, 0x11, 0x00); + pr2020_write_register(ViPipe, 0x12, 0x45); + pr2020_write_register(ViPipe, 0x13, 0xfc); + pr2020_write_register(ViPipe, 0x14, 0x00); + pr2020_write_register(ViPipe, 0x15, 0x18); + pr2020_write_register(ViPipe, 0x16, 0xd0); + pr2020_write_register(ViPipe, 0x17, 0x00); + pr2020_write_register(ViPipe, 0x18, 0x41); + pr2020_write_register(ViPipe, 0x19, 0x46); + pr2020_write_register(ViPipe, 0x1a, 0x22); + pr2020_write_register(ViPipe, 0x1b, 0x05); + pr2020_write_register(ViPipe, 0x1c, 0xea); + pr2020_write_register(ViPipe, 0x1d, 0x45); + pr2020_write_register(ViPipe, 0x1e, 0x40); + pr2020_write_register(ViPipe, 0x1f, 0x00); + pr2020_write_register(ViPipe, 0x20, 0x80); + pr2020_write_register(ViPipe, 0x21, 0x80); + pr2020_write_register(ViPipe, 0x22, 0x90); + pr2020_write_register(ViPipe, 0x23, 0x80); + pr2020_write_register(ViPipe, 0x24, 0x80); + pr2020_write_register(ViPipe, 0x25, 0x80); + pr2020_write_register(ViPipe, 0x26, 0x84); + pr2020_write_register(ViPipe, 0x27, 0x82); + pr2020_write_register(ViPipe, 0x28, 0x00); + pr2020_write_register(ViPipe, 0x29, 0x7b); + pr2020_write_register(ViPipe, 0x2a, 0xa6); + pr2020_write_register(ViPipe, 0x2b, 0x00); + pr2020_write_register(ViPipe, 0x2c, 0x00); + pr2020_write_register(ViPipe, 0x2d, 0x00); + pr2020_write_register(ViPipe, 0x2e, 0x00); + pr2020_write_register(ViPipe, 0x2f, 0x00); + pr2020_write_register(ViPipe, 0x30, 0x00); + pr2020_write_register(ViPipe, 0x31, 0x00); + pr2020_write_register(ViPipe, 0x32, 0xc0); + pr2020_write_register(ViPipe, 0x33, 0x14); + pr2020_write_register(ViPipe, 0x34, 0x14); + pr2020_write_register(ViPipe, 0x35, 0x80); + pr2020_write_register(ViPipe, 0x36, 0x80); + pr2020_write_register(ViPipe, 0x37, 0xaa); + pr2020_write_register(ViPipe, 0x38, 0x48); + pr2020_write_register(ViPipe, 0x39, 0x08); + pr2020_write_register(ViPipe, 0x3a, 0x27); + pr2020_write_register(ViPipe, 0x3b, 0x02); + pr2020_write_register(ViPipe, 0x3c, 0x01); + pr2020_write_register(ViPipe, 0x3d, 0x23); + pr2020_write_register(ViPipe, 0x3e, 0x02); + pr2020_write_register(ViPipe, 0x3f, 0xc4); + pr2020_write_register(ViPipe, 0x40, 0x05); + pr2020_write_register(ViPipe, 0x41, 0x55); + pr2020_write_register(ViPipe, 0x42, 0x01); + pr2020_write_register(ViPipe, 0x43, 0x33); + pr2020_write_register(ViPipe, 0x44, 0x6a); + pr2020_write_register(ViPipe, 0x45, 0x00); + pr2020_write_register(ViPipe, 0x46, 0x09); + pr2020_write_register(ViPipe, 0x47, 0xdc); + pr2020_write_register(ViPipe, 0x48, 0xa0); + pr2020_write_register(ViPipe, 0x49, 0x00); + pr2020_write_register(ViPipe, 0x4a, 0x7b); + pr2020_write_register(ViPipe, 0x4b, 0x60); + pr2020_write_register(ViPipe, 0x4c, 0x00); + pr2020_write_register(ViPipe, 0x4d, 0x4a); + pr2020_write_register(ViPipe, 0x4e, 0x00); + pr2020_write_register(ViPipe, 0x4f, 0x20); + pr2020_write_register(ViPipe, 0x50, 0x01); + pr2020_write_register(ViPipe, 0x51, 0x28); + pr2020_write_register(ViPipe, 0x52, 0x40); + pr2020_write_register(ViPipe, 0x53, 0x0c); + pr2020_write_register(ViPipe, 0x54, 0x0f); + pr2020_write_register(ViPipe, 0x55, 0x8d); + pr2020_write_register(ViPipe, 0x70, 0x06); + pr2020_write_register(ViPipe, 0x71, 0x08); + pr2020_write_register(ViPipe, 0x72, 0x0a); + pr2020_write_register(ViPipe, 0x73, 0x0c); + pr2020_write_register(ViPipe, 0x74, 0x0e); + pr2020_write_register(ViPipe, 0x75, 0x10); + pr2020_write_register(ViPipe, 0x76, 0x12); + pr2020_write_register(ViPipe, 0x77, 0x14); + pr2020_write_register(ViPipe, 0x78, 0x06); + pr2020_write_register(ViPipe, 0x79, 0x08); + pr2020_write_register(ViPipe, 0x7a, 0x0a); + pr2020_write_register(ViPipe, 0x7b, 0x0c); + pr2020_write_register(ViPipe, 0x7c, 0x0e); + pr2020_write_register(ViPipe, 0x7d, 0x10); + pr2020_write_register(ViPipe, 0x7e, 0x12); + pr2020_write_register(ViPipe, 0x7f, 0x14); + pr2020_write_register(ViPipe, 0x80, 0x00); + pr2020_write_register(ViPipe, 0x81, 0x09); + pr2020_write_register(ViPipe, 0x82, 0x00); + pr2020_write_register(ViPipe, 0x83, 0x07); + pr2020_write_register(ViPipe, 0x84, 0x00); + pr2020_write_register(ViPipe, 0x85, 0x17); + pr2020_write_register(ViPipe, 0x86, 0x03); + pr2020_write_register(ViPipe, 0x87, 0xe5); + pr2020_write_register(ViPipe, 0x88, 0x08); + pr2020_write_register(ViPipe, 0x89, 0x91); + pr2020_write_register(ViPipe, 0x8a, 0x08); + pr2020_write_register(ViPipe, 0x8b, 0x91); + pr2020_write_register(ViPipe, 0x8c, 0x0b); + pr2020_write_register(ViPipe, 0x8d, 0xe0); + pr2020_write_register(ViPipe, 0x8e, 0x05); + pr2020_write_register(ViPipe, 0x8f, 0x47); + pr2020_write_register(ViPipe, 0x90, 0x05); + pr2020_write_register(ViPipe, 0x91, 0xa0); + pr2020_write_register(ViPipe, 0x92, 0x73); + pr2020_write_register(ViPipe, 0x93, 0xe8); + pr2020_write_register(ViPipe, 0x94, 0x0f); + pr2020_write_register(ViPipe, 0x95, 0x5e); + pr2020_write_register(ViPipe, 0x96, 0x07); + pr2020_write_register(ViPipe, 0x97, 0x90); + pr2020_write_register(ViPipe, 0x98, 0x17); + pr2020_write_register(ViPipe, 0x99, 0x34); + pr2020_write_register(ViPipe, 0x9a, 0x13); + pr2020_write_register(ViPipe, 0x9b, 0x56); + pr2020_write_register(ViPipe, 0x9c, 0x0b); + pr2020_write_register(ViPipe, 0x9d, 0x9a); + pr2020_write_register(ViPipe, 0x9e, 0x09); + pr2020_write_register(ViPipe, 0x9f, 0xab); + pr2020_write_register(ViPipe, 0xa0, 0x01); + pr2020_write_register(ViPipe, 0xa1, 0x74); + pr2020_write_register(ViPipe, 0xa2, 0x01); + pr2020_write_register(ViPipe, 0xa3, 0x6b); + pr2020_write_register(ViPipe, 0xa4, 0x00); + pr2020_write_register(ViPipe, 0xa5, 0xba); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0xa3); + pr2020_write_register(ViPipe, 0xa8, 0x01); + pr2020_write_register(ViPipe, 0xa9, 0x39); + pr2020_write_register(ViPipe, 0xaa, 0x01); + pr2020_write_register(ViPipe, 0xab, 0x39); + pr2020_write_register(ViPipe, 0xac, 0x00); + pr2020_write_register(ViPipe, 0xad, 0xc1); + pr2020_write_register(ViPipe, 0xae, 0x00); + pr2020_write_register(ViPipe, 0xaf, 0xc1); + pr2020_write_register(ViPipe, 0xb0, 0x09); + pr2020_write_register(ViPipe, 0xb1, 0xaa); + pr2020_write_register(ViPipe, 0xb2, 0x0f); + pr2020_write_register(ViPipe, 0xb3, 0xae); + pr2020_write_register(ViPipe, 0xb4, 0x00); + pr2020_write_register(ViPipe, 0xb5, 0x17); + pr2020_write_register(ViPipe, 0xb6, 0x08); + pr2020_write_register(ViPipe, 0xb7, 0xe8); + pr2020_write_register(ViPipe, 0xb8, 0xb0); + pr2020_write_register(ViPipe, 0xb9, 0xce); + pr2020_write_register(ViPipe, 0xba, 0x90); + pr2020_write_register(ViPipe, 0xbb, 0x00); + pr2020_write_register(ViPipe, 0xbc, 0x00); + pr2020_write_register(ViPipe, 0xbd, 0x04); + pr2020_write_register(ViPipe, 0xbe, 0x05); + pr2020_write_register(ViPipe, 0xbf, 0x00); + pr2020_write_register(ViPipe, 0xc0, 0x00); + pr2020_write_register(ViPipe, 0xc1, 0x18); + pr2020_write_register(ViPipe, 0xc2, 0x02); + pr2020_write_register(ViPipe, 0xc3, 0xd0); + + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0e); + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0f); +} + +void pr2020_set_1080p_25(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe=%d\n", ViPipe); + + //Page0 sys + pr2020_write_register(ViPipe, 0xff, 0x00); + pr2020_write_register(ViPipe, 0x10, 0x83); + pr2020_write_register(ViPipe, 0x11, 0x07); + pr2020_write_register(ViPipe, 0x12, 0x00); + pr2020_write_register(ViPipe, 0x13, 0x00); + pr2020_write_register(ViPipe, 0x14, 0x21);//b[1:0} => Select Camera Input. VinP(1), VinN(3), Differ(0). + pr2020_write_register(ViPipe, 0x15, 0x44); + pr2020_write_register(ViPipe, 0x16, 0x0d); + pr2020_write_register(ViPipe, 0x40, 0x00); + pr2020_write_register(ViPipe, 0x47, 0x3a); + pr2020_write_register(ViPipe, 0x4e, 0x3f); + pr2020_write_register(ViPipe, 0x80, 0x56); + pr2020_write_register(ViPipe, 0x81, 0x0e); + pr2020_write_register(ViPipe, 0x82, 0x0d); + pr2020_write_register(ViPipe, 0x84, 0x30); + pr2020_write_register(ViPipe, 0x86, 0x20); + pr2020_write_register(ViPipe, 0x87, 0x00); + pr2020_write_register(ViPipe, 0x8a, 0x00); + pr2020_write_register(ViPipe, 0x90, 0x00); + pr2020_write_register(ViPipe, 0x91, 0x00); + pr2020_write_register(ViPipe, 0x92, 0x00); + pr2020_write_register(ViPipe, 0x94, 0xff); + pr2020_write_register(ViPipe, 0x95, 0xff); + pr2020_write_register(ViPipe, 0x96, 0xff); + pr2020_write_register(ViPipe, 0xa0, 0x00); + pr2020_write_register(ViPipe, 0xa1, 0x20); + pr2020_write_register(ViPipe, 0xa4, 0x01); + pr2020_write_register(ViPipe, 0xa5, 0xe3); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0x12); + pr2020_write_register(ViPipe, 0xa8, 0x00); + pr2020_write_register(ViPipe, 0xd0, 0x30); + pr2020_write_register(ViPipe, 0xd1, 0x08); + pr2020_write_register(ViPipe, 0xd2, 0x21); + pr2020_write_register(ViPipe, 0xd3, 0x00); + pr2020_write_register(ViPipe, 0xd8, 0x30); + pr2020_write_register(ViPipe, 0xd9, 0x08); + pr2020_write_register(ViPipe, 0xda, 0x21); + pr2020_write_register(ViPipe, 0xe0, 0x35); + pr2020_write_register(ViPipe, 0xe1, 0x80);//[6] 0:cb-y-cr-y 1:y-cb-y-cr + pr2020_write_register(ViPipe, 0xe2, 0x18); + pr2020_write_register(ViPipe, 0xe3, 0x00); + pr2020_write_register(ViPipe, 0xe4, 0x00); + pr2020_write_register(ViPipe, 0xea, 0x01); + pr2020_write_register(ViPipe, 0xeb, 0xff); + pr2020_write_register(ViPipe, 0xf1, 0x44); + pr2020_write_register(ViPipe, 0xf2, 0x01); + + //Page1 vdec + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x00, 0xe4); + pr2020_write_register(ViPipe, 0x01, 0x61); + pr2020_write_register(ViPipe, 0x02, 0x00); + pr2020_write_register(ViPipe, 0x03, 0x57); + pr2020_write_register(ViPipe, 0x04, 0x0c); + pr2020_write_register(ViPipe, 0x05, 0x88); + pr2020_write_register(ViPipe, 0x06, 0x04); + pr2020_write_register(ViPipe, 0x07, 0xb2); + pr2020_write_register(ViPipe, 0x08, 0x44); + pr2020_write_register(ViPipe, 0x09, 0x34); + pr2020_write_register(ViPipe, 0x0a, 0x02); + pr2020_write_register(ViPipe, 0x0b, 0x14); + pr2020_write_register(ViPipe, 0x0c, 0x04); + pr2020_write_register(ViPipe, 0x0d, 0x08); + pr2020_write_register(ViPipe, 0x0e, 0x5e); + pr2020_write_register(ViPipe, 0x0f, 0x5e); + pr2020_write_register(ViPipe, 0x10, 0x26); + pr2020_write_register(ViPipe, 0x11, 0x00); + pr2020_write_register(ViPipe, 0x12, 0x87); + pr2020_write_register(ViPipe, 0x13, 0x24); + pr2020_write_register(ViPipe, 0x14, 0x80); + pr2020_write_register(ViPipe, 0x15, 0x2a); + pr2020_write_register(ViPipe, 0x16, 0x38); + pr2020_write_register(ViPipe, 0x17, 0x00); + pr2020_write_register(ViPipe, 0x18, 0x80); + pr2020_write_register(ViPipe, 0x19, 0x48); + pr2020_write_register(ViPipe, 0x1a, 0x6c); + pr2020_write_register(ViPipe, 0x1b, 0x05); + pr2020_write_register(ViPipe, 0x1c, 0x61); + pr2020_write_register(ViPipe, 0x1d, 0x07); + pr2020_write_register(ViPipe, 0x1e, 0x7e); + pr2020_write_register(ViPipe, 0x1f, 0x80); + pr2020_write_register(ViPipe, 0x20, 0x80); + pr2020_write_register(ViPipe, 0x21, 0x80); + pr2020_write_register(ViPipe, 0x22, 0x90); + pr2020_write_register(ViPipe, 0x23, 0x80); + pr2020_write_register(ViPipe, 0x24, 0x80); + pr2020_write_register(ViPipe, 0x25, 0x80); + pr2020_write_register(ViPipe, 0x26, 0x84); + pr2020_write_register(ViPipe, 0x27, 0x82); + pr2020_write_register(ViPipe, 0x28, 0x00); + pr2020_write_register(ViPipe, 0x29, 0xff); + pr2020_write_register(ViPipe, 0x2a, 0xff); + pr2020_write_register(ViPipe, 0x2b, 0x00); + pr2020_write_register(ViPipe, 0x2c, 0x00); + pr2020_write_register(ViPipe, 0x2d, 0x00); + pr2020_write_register(ViPipe, 0x2e, 0x00); + pr2020_write_register(ViPipe, 0x2f, 0x00); + pr2020_write_register(ViPipe, 0x30, 0x00); + pr2020_write_register(ViPipe, 0x31, 0x00); + pr2020_write_register(ViPipe, 0x32, 0xc0); + pr2020_write_register(ViPipe, 0x33, 0x14); + pr2020_write_register(ViPipe, 0x34, 0x14); + pr2020_write_register(ViPipe, 0x35, 0x80); + pr2020_write_register(ViPipe, 0x36, 0x80); + pr2020_write_register(ViPipe, 0x37, 0xad); + pr2020_write_register(ViPipe, 0x38, 0x4b); + pr2020_write_register(ViPipe, 0x39, 0x08); + pr2020_write_register(ViPipe, 0x3a, 0x21); + pr2020_write_register(ViPipe, 0x3b, 0x02); + pr2020_write_register(ViPipe, 0x3c, 0x01); + pr2020_write_register(ViPipe, 0x3d, 0x23); + pr2020_write_register(ViPipe, 0x3e, 0x05); + pr2020_write_register(ViPipe, 0x3f, 0xc8); + pr2020_write_register(ViPipe, 0x40, 0x05); + pr2020_write_register(ViPipe, 0x41, 0x55); + pr2020_write_register(ViPipe, 0x42, 0x01); + pr2020_write_register(ViPipe, 0x43, 0x38); + pr2020_write_register(ViPipe, 0x44, 0x6a); + pr2020_write_register(ViPipe, 0x45, 0x00); + pr2020_write_register(ViPipe, 0x46, 0x14); + pr2020_write_register(ViPipe, 0x47, 0xb0); + pr2020_write_register(ViPipe, 0x48, 0xdf); + pr2020_write_register(ViPipe, 0x49, 0x00); + pr2020_write_register(ViPipe, 0x4a, 0x7b); + pr2020_write_register(ViPipe, 0x4b, 0x60); + pr2020_write_register(ViPipe, 0x4c, 0x00); + pr2020_write_register(ViPipe, 0x4d, 0x26); + pr2020_write_register(ViPipe, 0x4e, 0x00); + pr2020_write_register(ViPipe, 0x4f, 0x20);//RK:0x24 + pr2020_write_register(ViPipe, 0x50, 0x01); + pr2020_write_register(ViPipe, 0x51, 0x28); + pr2020_write_register(ViPipe, 0x52, 0x40); + pr2020_write_register(ViPipe, 0x53, 0x0c); + pr2020_write_register(ViPipe, 0x54, 0x0f); + pr2020_write_register(ViPipe, 0x55, 0x8d); + pr2020_write_register(ViPipe, 0x70, 0x06); + pr2020_write_register(ViPipe, 0x71, 0x08); + pr2020_write_register(ViPipe, 0x72, 0x0a); + pr2020_write_register(ViPipe, 0x73, 0x0c); + pr2020_write_register(ViPipe, 0x74, 0x0e); + pr2020_write_register(ViPipe, 0x75, 0x10); + pr2020_write_register(ViPipe, 0x76, 0x12); + pr2020_write_register(ViPipe, 0x77, 0x14); + pr2020_write_register(ViPipe, 0x78, 0x06); + pr2020_write_register(ViPipe, 0x79, 0x08); + pr2020_write_register(ViPipe, 0x7a, 0x0a); + pr2020_write_register(ViPipe, 0x7b, 0x0c); + pr2020_write_register(ViPipe, 0x7c, 0x0e); + pr2020_write_register(ViPipe, 0x7d, 0x10); + pr2020_write_register(ViPipe, 0x7e, 0x12); + pr2020_write_register(ViPipe, 0x7f, 0x14); + pr2020_write_register(ViPipe, 0x80, 0x00); + pr2020_write_register(ViPipe, 0x81, 0x09); + pr2020_write_register(ViPipe, 0x82, 0x00); + pr2020_write_register(ViPipe, 0x83, 0x07); + pr2020_write_register(ViPipe, 0x84, 0x00); + pr2020_write_register(ViPipe, 0x85, 0x17); + pr2020_write_register(ViPipe, 0x86, 0x03); + pr2020_write_register(ViPipe, 0x87, 0xe5); + pr2020_write_register(ViPipe, 0x88, 0x05); + pr2020_write_register(ViPipe, 0x89, 0x24); + pr2020_write_register(ViPipe, 0x8a, 0x05); + pr2020_write_register(ViPipe, 0x8b, 0x24); + pr2020_write_register(ViPipe, 0x8c, 0x08); + pr2020_write_register(ViPipe, 0x8d, 0xe8); + pr2020_write_register(ViPipe, 0x8e, 0x05); + pr2020_write_register(ViPipe, 0x8f, 0x47); + pr2020_write_register(ViPipe, 0x90, 0x02); + pr2020_write_register(ViPipe, 0x91, 0xb4); + pr2020_write_register(ViPipe, 0x92, 0x73); + pr2020_write_register(ViPipe, 0x93, 0xe8); + pr2020_write_register(ViPipe, 0x94, 0x0f); + pr2020_write_register(ViPipe, 0x95, 0x5e); + pr2020_write_register(ViPipe, 0x96, 0x03); + pr2020_write_register(ViPipe, 0x97, 0xd0); + pr2020_write_register(ViPipe, 0x98, 0x17); + pr2020_write_register(ViPipe, 0x99, 0x34); + pr2020_write_register(ViPipe, 0x9a, 0x13); + pr2020_write_register(ViPipe, 0x9b, 0x56); + pr2020_write_register(ViPipe, 0x9c, 0x0b); + pr2020_write_register(ViPipe, 0x9d, 0x9a); + pr2020_write_register(ViPipe, 0x9e, 0x09); + pr2020_write_register(ViPipe, 0x9f, 0xab); + pr2020_write_register(ViPipe, 0xa0, 0x01); + pr2020_write_register(ViPipe, 0xa1, 0x74); + pr2020_write_register(ViPipe, 0xa2, 0x01); + pr2020_write_register(ViPipe, 0xa3, 0x6b); + pr2020_write_register(ViPipe, 0xa4, 0x00); + pr2020_write_register(ViPipe, 0xa5, 0xba); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0xa3); + pr2020_write_register(ViPipe, 0xa8, 0x01); + pr2020_write_register(ViPipe, 0xa9, 0x39); + pr2020_write_register(ViPipe, 0xaa, 0x01); + pr2020_write_register(ViPipe, 0xab, 0x39); + pr2020_write_register(ViPipe, 0xac, 0x00); + pr2020_write_register(ViPipe, 0xad, 0xc1); + pr2020_write_register(ViPipe, 0xae, 0x00); + pr2020_write_register(ViPipe, 0xaf, 0xc1); + pr2020_write_register(ViPipe, 0xb0, 0x05); + pr2020_write_register(ViPipe, 0xb1, 0xcc); + pr2020_write_register(ViPipe, 0xb2, 0x09); + pr2020_write_register(ViPipe, 0xb3, 0x6d); + pr2020_write_register(ViPipe, 0xb4, 0x00); + pr2020_write_register(ViPipe, 0xb5, 0x17); + pr2020_write_register(ViPipe, 0xb6, 0x08); + pr2020_write_register(ViPipe, 0xb7, 0xe8); + pr2020_write_register(ViPipe, 0xb8, 0xb0); + pr2020_write_register(ViPipe, 0xb9, 0xce); + pr2020_write_register(ViPipe, 0xba, 0x90); + pr2020_write_register(ViPipe, 0xbb, 0x00); + pr2020_write_register(ViPipe, 0xbc, 0x00); + pr2020_write_register(ViPipe, 0xbd, 0x04); + pr2020_write_register(ViPipe, 0xbe, 0x07); + pr2020_write_register(ViPipe, 0xbf, 0x80); + pr2020_write_register(ViPipe, 0xc0, 0x00); + pr2020_write_register(ViPipe, 0xc1, 0x20); + pr2020_write_register(ViPipe, 0xc2, 0x04); + pr2020_write_register(ViPipe, 0xc3, 0x38); + + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0e); + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0f); +} + +void pr2020_set_1080p_30(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe=%d\n", ViPipe); + + //Page0 sys + pr2020_write_register(ViPipe, 0xff, 0x00); + pr2020_write_register(ViPipe, 0x10, 0x93); + pr2020_write_register(ViPipe, 0x11, 0x07); + pr2020_write_register(ViPipe, 0x12, 0x00); + pr2020_write_register(ViPipe, 0x13, 0x00); + pr2020_write_register(ViPipe, 0x14, 0x21);//b[1:0} => Select Camera Input. VinP(1), VinN(3), Differ(0). + pr2020_write_register(ViPipe, 0x15, 0x44); + pr2020_write_register(ViPipe, 0x16, 0x0d); + pr2020_write_register(ViPipe, 0x40, 0x00); + pr2020_write_register(ViPipe, 0x47, 0x3a); + pr2020_write_register(ViPipe, 0x4e, 0x3f); + pr2020_write_register(ViPipe, 0x80, 0x56); + pr2020_write_register(ViPipe, 0x81, 0x0e); + pr2020_write_register(ViPipe, 0x82, 0x0d); + pr2020_write_register(ViPipe, 0x84, 0x30); + pr2020_write_register(ViPipe, 0x86, 0x20); + pr2020_write_register(ViPipe, 0x87, 0x00); + pr2020_write_register(ViPipe, 0x8a, 0x00); + pr2020_write_register(ViPipe, 0x90, 0x00); + pr2020_write_register(ViPipe, 0x91, 0x00); + pr2020_write_register(ViPipe, 0x92, 0x00); + pr2020_write_register(ViPipe, 0x94, 0xff); + pr2020_write_register(ViPipe, 0x95, 0xff); + pr2020_write_register(ViPipe, 0x96, 0xff); + pr2020_write_register(ViPipe, 0xa0, 0x00); + pr2020_write_register(ViPipe, 0xa1, 0x20); + pr2020_write_register(ViPipe, 0xa4, 0x01); + pr2020_write_register(ViPipe, 0xa5, 0xe3); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0x12); + pr2020_write_register(ViPipe, 0xa8, 0x00); + pr2020_write_register(ViPipe, 0xd0, 0x30); + pr2020_write_register(ViPipe, 0xd1, 0x08); + pr2020_write_register(ViPipe, 0xd2, 0x21); + pr2020_write_register(ViPipe, 0xd3, 0x00); + pr2020_write_register(ViPipe, 0xd8, 0x30); + pr2020_write_register(ViPipe, 0xd9, 0x08); + pr2020_write_register(ViPipe, 0xda, 0x21); + pr2020_write_register(ViPipe, 0xe0, 0x35); + pr2020_write_register(ViPipe, 0xe1, 0x80); + pr2020_write_register(ViPipe, 0xe2, 0x18); + pr2020_write_register(ViPipe, 0xe3, 0x00); + pr2020_write_register(ViPipe, 0xe4, 0x00); + pr2020_write_register(ViPipe, 0xea, 0x01); + pr2020_write_register(ViPipe, 0xeb, 0xff); + pr2020_write_register(ViPipe, 0xf1, 0x44); + pr2020_write_register(ViPipe, 0xf2, 0x01); + + //Page1 vdec + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x00, 0xe4); + pr2020_write_register(ViPipe, 0x01, 0x61); + pr2020_write_register(ViPipe, 0x02, 0x00); + pr2020_write_register(ViPipe, 0x03, 0x57); + pr2020_write_register(ViPipe, 0x04, 0x0c); + pr2020_write_register(ViPipe, 0x05, 0x88); + pr2020_write_register(ViPipe, 0x06, 0x04); + pr2020_write_register(ViPipe, 0x07, 0xb2); + pr2020_write_register(ViPipe, 0x08, 0x44); + pr2020_write_register(ViPipe, 0x09, 0x34); + pr2020_write_register(ViPipe, 0x0a, 0x02); + pr2020_write_register(ViPipe, 0x0b, 0x14); + pr2020_write_register(ViPipe, 0x0c, 0x04); + pr2020_write_register(ViPipe, 0x0d, 0x08); + pr2020_write_register(ViPipe, 0x0e, 0x5e); + pr2020_write_register(ViPipe, 0x0f, 0x5e); + pr2020_write_register(ViPipe, 0x10, 0x26); + pr2020_write_register(ViPipe, 0x11, 0x00); + pr2020_write_register(ViPipe, 0x12, 0x87); + pr2020_write_register(ViPipe, 0x13, 0x2c); + pr2020_write_register(ViPipe, 0x14, 0x80); + pr2020_write_register(ViPipe, 0x15, 0x28); + pr2020_write_register(ViPipe, 0x16, 0x38); + pr2020_write_register(ViPipe, 0x17, 0x00); + pr2020_write_register(ViPipe, 0x18, 0x80); + pr2020_write_register(ViPipe, 0x19, 0x48); + pr2020_write_register(ViPipe, 0x1a, 0x6c); + pr2020_write_register(ViPipe, 0x1b, 0x05); + pr2020_write_register(ViPipe, 0x1c, 0x61); + pr2020_write_register(ViPipe, 0x1d, 0x07); + pr2020_write_register(ViPipe, 0x1e, 0x7e); + pr2020_write_register(ViPipe, 0x1f, 0x80); + pr2020_write_register(ViPipe, 0x20, 0x80); + pr2020_write_register(ViPipe, 0x21, 0x80); + pr2020_write_register(ViPipe, 0x22, 0x90); + pr2020_write_register(ViPipe, 0x23, 0x80); + pr2020_write_register(ViPipe, 0x24, 0x80); + pr2020_write_register(ViPipe, 0x25, 0x80); + pr2020_write_register(ViPipe, 0x26, 0x84); + pr2020_write_register(ViPipe, 0x27, 0x82); + pr2020_write_register(ViPipe, 0x28, 0x00); + pr2020_write_register(ViPipe, 0x29, 0xff); + pr2020_write_register(ViPipe, 0x2a, 0xff); + pr2020_write_register(ViPipe, 0x2b, 0x00); + pr2020_write_register(ViPipe, 0x2c, 0x00); + pr2020_write_register(ViPipe, 0x2d, 0x00); + pr2020_write_register(ViPipe, 0x2e, 0x00); + pr2020_write_register(ViPipe, 0x2f, 0x00); + pr2020_write_register(ViPipe, 0x30, 0x00); + pr2020_write_register(ViPipe, 0x31, 0x00); + pr2020_write_register(ViPipe, 0x32, 0xc0); + pr2020_write_register(ViPipe, 0x33, 0x14); + pr2020_write_register(ViPipe, 0x34, 0x14); + pr2020_write_register(ViPipe, 0x35, 0x80); + pr2020_write_register(ViPipe, 0x36, 0x80); + pr2020_write_register(ViPipe, 0x37, 0xad); + pr2020_write_register(ViPipe, 0x38, 0x4b); + pr2020_write_register(ViPipe, 0x39, 0x08); + pr2020_write_register(ViPipe, 0x3a, 0x21); + pr2020_write_register(ViPipe, 0x3b, 0x02); + pr2020_write_register(ViPipe, 0x3c, 0x01); + pr2020_write_register(ViPipe, 0x3d, 0x23); + pr2020_write_register(ViPipe, 0x3e, 0x05); + pr2020_write_register(ViPipe, 0x3f, 0xc8); + pr2020_write_register(ViPipe, 0x40, 0x05); + pr2020_write_register(ViPipe, 0x41, 0x55); + pr2020_write_register(ViPipe, 0x42, 0x01); + pr2020_write_register(ViPipe, 0x43, 0x38); + pr2020_write_register(ViPipe, 0x44, 0x6a); + pr2020_write_register(ViPipe, 0x45, 0x00); + pr2020_write_register(ViPipe, 0x46, 0x14); + pr2020_write_register(ViPipe, 0x47, 0xb2); + pr2020_write_register(ViPipe, 0x48, 0xbc); + pr2020_write_register(ViPipe, 0x49, 0x00); + pr2020_write_register(ViPipe, 0x4a, 0x7b); + pr2020_write_register(ViPipe, 0x4b, 0x60); + pr2020_write_register(ViPipe, 0x4c, 0x00); + pr2020_write_register(ViPipe, 0x4d, 0x26); + pr2020_write_register(ViPipe, 0x4e, 0x00); + pr2020_write_register(ViPipe, 0x4f, 0x20);//RK:0x24 + pr2020_write_register(ViPipe, 0x50, 0x01); + pr2020_write_register(ViPipe, 0x51, 0x28); + pr2020_write_register(ViPipe, 0x52, 0x40); + pr2020_write_register(ViPipe, 0x53, 0x0c); + pr2020_write_register(ViPipe, 0x54, 0x0f); + pr2020_write_register(ViPipe, 0x55, 0x8d); + pr2020_write_register(ViPipe, 0x70, 0x06); + pr2020_write_register(ViPipe, 0x71, 0x08); + pr2020_write_register(ViPipe, 0x72, 0x0a); + pr2020_write_register(ViPipe, 0x73, 0x0c); + pr2020_write_register(ViPipe, 0x74, 0x0e); + pr2020_write_register(ViPipe, 0x75, 0x10); + pr2020_write_register(ViPipe, 0x76, 0x12); + pr2020_write_register(ViPipe, 0x77, 0x14); + pr2020_write_register(ViPipe, 0x78, 0x06); + pr2020_write_register(ViPipe, 0x79, 0x08); + pr2020_write_register(ViPipe, 0x7a, 0x0a); + pr2020_write_register(ViPipe, 0x7b, 0x0c); + pr2020_write_register(ViPipe, 0x7c, 0x0e); + pr2020_write_register(ViPipe, 0x7d, 0x10); + pr2020_write_register(ViPipe, 0x7e, 0x12); + pr2020_write_register(ViPipe, 0x7f, 0x14); + pr2020_write_register(ViPipe, 0x80, 0x00); + pr2020_write_register(ViPipe, 0x81, 0x09); + pr2020_write_register(ViPipe, 0x82, 0x00); + pr2020_write_register(ViPipe, 0x83, 0x07); + pr2020_write_register(ViPipe, 0x84, 0x00); + pr2020_write_register(ViPipe, 0x85, 0x17); + pr2020_write_register(ViPipe, 0x86, 0x03); + pr2020_write_register(ViPipe, 0x87, 0xe5); + pr2020_write_register(ViPipe, 0x88, 0x04); + pr2020_write_register(ViPipe, 0x89, 0x48); + pr2020_write_register(ViPipe, 0x8a, 0x04); + pr2020_write_register(ViPipe, 0x8b, 0x48); + pr2020_write_register(ViPipe, 0x8c, 0x08); + pr2020_write_register(ViPipe, 0x8d, 0xe8); + pr2020_write_register(ViPipe, 0x8e, 0x05); + pr2020_write_register(ViPipe, 0x8f, 0x47); + pr2020_write_register(ViPipe, 0x90, 0x03); + pr2020_write_register(ViPipe, 0x91, 0x13); + pr2020_write_register(ViPipe, 0x92, 0x73); + pr2020_write_register(ViPipe, 0x93, 0xe8); + pr2020_write_register(ViPipe, 0x94, 0x0f); + pr2020_write_register(ViPipe, 0x95, 0x5e); + pr2020_write_register(ViPipe, 0x96, 0x03); + pr2020_write_register(ViPipe, 0x97, 0xd0); + pr2020_write_register(ViPipe, 0x98, 0x17); + pr2020_write_register(ViPipe, 0x99, 0x34); + pr2020_write_register(ViPipe, 0x9a, 0x13); + pr2020_write_register(ViPipe, 0x9b, 0x56); + pr2020_write_register(ViPipe, 0x9c, 0x0b); + pr2020_write_register(ViPipe, 0x9d, 0x9a); + pr2020_write_register(ViPipe, 0x9e, 0x09); + pr2020_write_register(ViPipe, 0x9f, 0xab); + pr2020_write_register(ViPipe, 0xa0, 0x01); + pr2020_write_register(ViPipe, 0xa1, 0x74); + pr2020_write_register(ViPipe, 0xa2, 0x01); + pr2020_write_register(ViPipe, 0xa3, 0x6b); + pr2020_write_register(ViPipe, 0xa4, 0x00); + pr2020_write_register(ViPipe, 0xa5, 0xba); + pr2020_write_register(ViPipe, 0xa6, 0x00); + pr2020_write_register(ViPipe, 0xa7, 0xa3); + pr2020_write_register(ViPipe, 0xa8, 0x01); + pr2020_write_register(ViPipe, 0xa9, 0x39); + pr2020_write_register(ViPipe, 0xaa, 0x01); + pr2020_write_register(ViPipe, 0xab, 0x39); + pr2020_write_register(ViPipe, 0xac, 0x00); + pr2020_write_register(ViPipe, 0xad, 0xc1); + pr2020_write_register(ViPipe, 0xae, 0x00); + pr2020_write_register(ViPipe, 0xaf, 0xc1); + pr2020_write_register(ViPipe, 0xb0, 0x04); + pr2020_write_register(ViPipe, 0xb1, 0xd4); + pr2020_write_register(ViPipe, 0xb2, 0x07); + pr2020_write_register(ViPipe, 0xb3, 0xda); + pr2020_write_register(ViPipe, 0xb4, 0x00); + pr2020_write_register(ViPipe, 0xb5, 0x17); + pr2020_write_register(ViPipe, 0xb6, 0x08); + pr2020_write_register(ViPipe, 0xb7, 0xe8); + pr2020_write_register(ViPipe, 0xb8, 0xb0); + pr2020_write_register(ViPipe, 0xb9, 0xce); + pr2020_write_register(ViPipe, 0xba, 0x90); + pr2020_write_register(ViPipe, 0xbb, 0x00); + pr2020_write_register(ViPipe, 0xbc, 0x00); + pr2020_write_register(ViPipe, 0xbd, 0x04); + pr2020_write_register(ViPipe, 0xbe, 0x07); + pr2020_write_register(ViPipe, 0xbf, 0x80); + pr2020_write_register(ViPipe, 0xc0, 0x00); + pr2020_write_register(ViPipe, 0xc1, 0x20); + pr2020_write_register(ViPipe, 0xc2, 0x04); + pr2020_write_register(ViPipe, 0xc3, 0x38); + + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0e); + pr2020_write_register(ViPipe, 0xff, 0x01); + pr2020_write_register(ViPipe, 0x54, 0x0f); +} + +#if (PR2020_AUTO_DETECT) +void pr2000_chip_init(VI_PIPE ViPipe) +{ + CVI_U8 lockstatus = 0; + CVI_U8 detvideo = 0; + CVI_U8 temp = 0; + + lockstatus = pr2020_read_register(ViPipe, 0x01); + detvideo = pr2020_read_register(ViPipe, 0x00); + temp = pr2020_read_register(ViPipe, 0x10); + CVI_TRACE_SNS(CVI_DBG_INFO, "detvideo = 0x%2x, lockstatus = 0x%2x, signal_type = %d, temp = 0x%2x!!!\n", + detvideo, lockstatus, signal_type, temp); + if (((lockstatus & 0x18) == 0x18) && ((detvideo & 0x08) == 0x08)) { //camera plug in + //for test start + if ((detvideo & 0x03) == 0x00) { //NTSC + if (signal_type != PR2020_MODE_720H_NTSC) {//shold set reg again + pr2020_write_register(ViPipe, 0xff, 0x00); + temp = pr2020_read_register(ViPipe, 0x11); + if (temp != 0x00) + pr2020_write_register(ViPipe, 0x11, 0x00); + delay_ms(200); + pr2020_set_cvbs_ntsc_60(ViPipe); + signal_type = PR2020_MODE_720H_NTSC; + CVI_TRACE_SNS(CVI_DBG_INFO, "pr2020 download NTSC reg!\n"); + } + } else if ((detvideo & 0x03) == 0x01) { //PAL + if (signal_type != PR2020_MODE_720H_PAL) {//shold set reg again + pr2020_write_register(ViPipe, 0xff, 0x00); + temp = pr2020_read_register(ViPipe, 0x11); + if (temp != 0x00) + pr2020_write_register(ViPipe, 0x11, 0x00); + delay_ms(200); + pr2020_set_cvbs_pal_50(ViPipe); + signal_type = PR2020_MODE_720H_PAL; + CVI_TRACE_SNS(CVI_DBG_INFO, "pr2020 download PAL reg!\n"); + } + } else if ((detvideo & 0x03) == 0x02) { //720p + if ((detvideo & 0x30) == 0x00) { //25fps + if (signal_type != PR2020_MODE_720P_25) { //shold set reg again + pr2020_write_register(ViPipe, 0xff, 0x00); + temp = pr2020_read_register(ViPipe, 0x11); + if (temp != 0x00) + pr2020_write_register(ViPipe, 0x11, 0x00); + delay_ms(200); + pr2020_set_720p_25(ViPipe); + signal_type = PR2020_MODE_720P_25; + CVI_TRACE_SNS(CVI_DBG_INFO, "pr2020 download 720P 25fps reg!\n"); + } + } else if ((detvideo & 0x30) == 0x10) { //30fps + if (signal_type != PR2020_MODE_720P_30) { //shold set reg again + pr2020_write_register(ViPipe, 0xff, 0x00); + temp = pr2020_read_register(ViPipe, 0x11); + if (temp != 0x00) + pr2020_write_register(ViPipe, 0x11, 0x00); + delay_ms(200); + pr2020_set_720p_30(ViPipe); + signal_type = PR2020_MODE_720P_30; + CVI_TRACE_SNS(CVI_DBG_INFO, "pr2020 download 720P 30fps reg!\n"); + } + } else if ((detvideo & 0x30) == 0x20) { //50fps + signal_type = PR2020_MODE_NONE; + CVI_TRACE_SNS(CVI_DBG_INFO, "detect video fmt is 720P 50fps\n"); + } else if ((detvideo & 0x30) == 0x30) { //60fps + signal_type = PR2020_MODE_NONE; + CVI_TRACE_SNS(CVI_DBG_INFO, "detect video fmt is 720P 60fps\n"); + } + } else if ((detvideo & 0x03) == 0x03) { //1080p + if ((detvideo & 0x30) == 0x00) { //25fps + if (signal_type != PR2020_MODE_1080P_25) { //shold set reg again + pr2020_write_register(ViPipe, 0xff, 0x00); + temp = pr2020_read_register(ViPipe, 0x11); + if (temp != 0x00) + pr2020_write_register(ViPipe, 0x11, 0x00); + delay_ms(200); + pr2020_set_1080p_25(ViPipe); + signal_type = PR2020_MODE_1080P_25; + CVI_TRACE_SNS(CVI_DBG_INFO, "pr2020 download full hd 1080p 25fps reg!\n"); + } + } else if ((detvideo & 0x30) == 0x10) { //30fps + if (signal_type != PR2020_MODE_1080P_30) { //shold set reg again + pr2020_write_register(ViPipe, 0xff, 0x00); + temp = pr2020_read_register(ViPipe, 0x11); + if (temp != 0x00) + pr2020_write_register(ViPipe, 0x11, 0x00); + delay_ms(200); + pr2020_set_1080p_30(ViPipe); + signal_type = PR2020_MODE_1080P_30; + CVI_TRACE_SNS(CVI_DBG_INFO, "pr2020 download full hd 1080p 30fps reg!\n"); + } + } + } else { + CVI_TRACE_SNS(CVI_DBG_INFO, "detect nothing!!!\n"); + signal_type = PR2020_MODE_NONE; + } + pr2020_write_register(ViPipe, 0xff, 0x00); +#if 0 + //for test end + //read camera plug and signal state + //mdelay(100); + CVI_TRACE_SNS(CVI_DBG_INFO, "pr2020 read reg 0x%2x, 0x%2x, 0x%2x, 0x%2x, 0x%2x\n", + pr2020_read_register(ViPipe, 0xff), + pr2020_read_register(ViPipe, 0x00), + pr2020_read_register(ViPipe, 0x01), + pr2020_read_register(ViPipe, 0x10), + pr2020_read_register(ViPipe, 0x11)); + +#endif + } else { + pr2020_write_register(ViPipe, 0xff, 0x00); + pr2020_write_register(ViPipe, 0x11, 0x00); + signal_type = PR2020_MODE_NONE; + CVI_TRACE_SNS(CVI_DBG_INFO, "pr2020 has no signal!\n"); + } +} + +static void *pr2020_device_auto_detect(void *arg) +{ + VI_PIPE ViPipe = *(CVI_U8 *)arg; + PR2020_MODE_E signal_type_old = signal_type; + + free(arg); + while (1) { + delay_ms(500); //500ms + pr2000_chip_init(ViPipe); //do it day and night + if (signal_type_old != signal_type) { + signal_type_old = signal_type; + CVI_VI_Trig_AHD(ViPipe, 1); + } + } + return NULL; +} +#endif + +void pr2020_init(VI_PIPE ViPipe) +{ + if (pr2020_sys_init(ViPipe) != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "PR2020 sys init fail\n"); + return; + } + + delay_ms(20); + + if (pr2020_i2c_init(ViPipe) != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "PR2020 i2c init fail\n"); + return; + } + + // check sensor chip id + pr2020_write_register(ViPipe, 0xff, 0x00); + if (((pr2020_read_register(ViPipe, 0xfc) << 8) | (pr2020_read_register(ViPipe, 0xfd))) != 0x2000) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read PR2020 chip id fail\n"); + return; + } + + CVI_TRACE_SNS(CVI_DBG_INFO, "Loading Pixelplus PR2020 sensor\n"); + + pr2020_write_register(ViPipe, 0xff, 0x00);//reset + pr2020_write_register(ViPipe, 0x11, 0x00); + + pr2020_fw_init(ViPipe); + + signal_type = g_pastPr2020[ViPipe]->u8ImgMode; + if (signal_type == PR2020_MODE_720P_25) { + pr2020_set_720p_25(ViPipe); + } else if (signal_type == PR2020_MODE_720P_30) { + pr2020_set_720p_30(ViPipe); + } else if (signal_type == PR2020_MODE_1080P_25) { + pr2020_set_1080p_25(ViPipe); + } else if (signal_type == PR2020_MODE_1080P_30) { + pr2020_set_1080p_30(ViPipe); + } + CVI_TRACE_SNS(CVI_DBG_INFO, "signal_type=%d\n", signal_type); + // wait for signal to stabilize + delay_ms(800); + pr2020_write_register(ViPipe, 0xff, 0x00);//page0 +#if PR2020_AUTO_DETECT + CVI_U8 *arg = malloc(sizeof(*arg)); + + *arg = ViPipe; + if (pthread_create(&g_pr2020_thid, NULL, pr2020_device_auto_detect, arg) != 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "PR2020 auto detect function fail!\n"); + } +#endif +} + +void pr2020_exit(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "Exit Pixelplus PR2020 Sensor\n"); + + if (g_pr2020_thid) + pthread_kill(g_pr2020_thid, SIGQUIT); + + pr2020_i2c_exit(ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2100/Makefile b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2100/Makefile new file mode 100644 index 000000000..4b21c77e0 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2100/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_pr2100.a +TARGET_SO = $(MW_LIB)/libsns_pr2100.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2100/pr2100_cmos.c b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2100/pr2100_cmos.c new file mode 100644 index 000000000..f2dcfe8ea --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2100/pr2100_cmos.c @@ -0,0 +1,314 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_isp.h" + +#include "pr2100_cmos_ex.h" +#include "pr2100_cmos_param.h" + +/**************************************************************************** + * global variables * + ****************************************************************************/ +ISP_SNS_COMMBUS_U g_aunPr2100_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_STATE_S *g_pastPr2100[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define PR2100_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastPr2100[dev]) +#define PR2100_SENSOR_SET_CTX(dev, pstCtx) (g_pastPr2100[dev] = pstCtx) +#define PR2100_SENSOR_RESET_CTX(dev) (g_pastPr2100[dev] = CVI_NULL) + +#define PR2100_RES_IS_2M(w, h) ((w) <= 1920 && (h) <= 1080) +#define PR2100_ID 2100 + +CVI_U16 g_au16Pr2100_BdgMuxMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const PR2100_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + PR2100_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astPr2100_mode[pstSnsState->u8ImgMode]; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + PR2100_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstCfg0 = &pstSnsState->astSyncInfo[0]; + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + PR2100_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + + if (pstSensorImageMode->f32Fps <= 30) { + if (PR2100_RES_IS_2M(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + switch (g_au16Pr2100_BdgMuxMode[ViPipe]) { + case SNS_BDG_MUX_NONE: + u8SensorImageMode = PR2100_MODE_1080P; + break; + case SNS_BDG_MUX_2: + u8SensorImageMode = PR2100_MODE_1080P_2CH; + break; + case SNS_BDG_MUX_3: + case SNS_BDG_MUX_4: + u8SensorImageMode = PR2100_MODE_1080P_4CH; + break; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + PR2100_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->u8ImgMode = PR2100_MODE_1080P; + pstSnsState->enWDRMode = WDR_MODE_NONE; +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + PR2100_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &pr2100_multi_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astPr2100_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astPr2100_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + + if (pstSnsState->u8ImgMode == PR2100_MODE_1080P) { + pstRxAttr->mac_clk = RX_MAC_CLK_400M; + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + pstRxAttr->mipi_attr.demux.demux_en = 0; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &pr2100_multi_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = pr2100_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = pr2100_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 pr2100_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunPr2100_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + PR2100_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + PR2100_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + PR2100_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + PR2100_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + (void) pstAeLib; + (void) pstAwbLib; + + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = PR2100_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + (void) pstAeLib; + (void) pstAwbLib; + + CVI_S32 s32Ret; + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, PR2100_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + g_au16Pr2100_BdgMuxMode[ViPipe] = pstInitAttr->enSnsBdgMuxMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsPR2100_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = CVI_NULL, + .pfnRestart = CVI_NULL, + .pfnMirrorFlip = CVI_NULL, + .pfnWriteReg = pr2100_write_register, + .pfnReadReg = pr2100_read_register, + .pfnSetBusInfo = pr2100_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = CVI_NULL, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2100/pr2100_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2100/pr2100_cmos_ex.h new file mode 100644 index 000000000..3bb5e7495 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2100/pr2100_cmos_ex.h @@ -0,0 +1,65 @@ +#ifndef __PR2100_CMOS_EX_H_ +#define __PR2100_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +typedef enum _PR2100_MODE_E { + PR2100_MODE_NONE, + PR2100_MODE_1080P, + PR2100_MODE_1080P_2CH, + PR2100_MODE_1080P_4CH, + PR2100_MODE_NUM +} PR2100_MODE_E; + +typedef struct _PR2100_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + char name[64]; +} PR2100_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastPr2100[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunPr2100_BusInfo[]; +extern const CVI_U8 pr2100_i2c_addr; +extern const CVI_U32 pr2100_addr_byte; +extern const CVI_U32 pr2100_data_byte; +extern void pr2100_init(VI_PIPE ViPipe); +extern void pr2100_exit(VI_PIPE ViPipe); +extern void pr2100_standby(VI_PIPE ViPipe); +extern void pr2100_restart(VI_PIPE ViPipe); +extern int pr2100_write_register(VI_PIPE ViPipe, int addr, int data); +extern int pr2100_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __PR2100_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2100/pr2100_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2100/pr2100_cmos_param.h new file mode 100644 index 000000000..c0413d8ad --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2100/pr2100_cmos_param.h @@ -0,0 +1,109 @@ +#ifndef __PR2100_CMOS_PARAM_H_ +#define __PR2100_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "pr2100_cmos_ex.h" + +static const PR2100_MODE_S g_astPr2100_mode[PR2100_MODE_NUM] = { + [PR2100_MODE_1080P] = { + .name = "1080p25", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + }, + [PR2100_MODE_1080P_2CH] = { + .name = "1080p25_2ch", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + }, + [PR2100_MODE_1080P_4CH] = { + .name = "1080p25_4ch", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + }, +}; + +struct combo_dev_attr_s pr2100_multi_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_600M, + .mipi_attr = { + .raw_data_type = YUV422_8BIT, + .lane_id = {0, 1, 2, 3, 4}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + .demux = { + .demux_en = 1, + .vc_mapping = {0, 1, 2, 3}, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_NONE, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __PR2100_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2100/pr2100_sensor_ctrl.c b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2100/pr2100_sensor_ctrl.c new file mode 100644 index 000000000..77c52ab7c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/pixelplus_pr2100/pr2100_sensor_ctrl.c @@ -0,0 +1,2431 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include +#include "cvi_sns_ctrl.h" +#include "pr2100_cmos_ex.h" +#include +#include + +static void pr2100_set_1080p(VI_PIPE ViPipe); +static void pr2100_set_1080p_2ch(VI_PIPE ViPipe); +static void pr2100_set_1080p_4ch(VI_PIPE ViPipe); + +const CVI_U8 pr2100_master_i2c_addr = 0x5C; /* I2C slave address of PR2100 master chip*/ +const CVI_U8 pr2100_slave_i2c_addr = 0x5F; /* I2C slave address of PR2100 slave chip*/ +const CVI_U32 pr2100_addr_byte = 1; +const CVI_U32 pr2100_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; +static VI_PIPE slave_pipe = (VI_MAX_PIPE_NUM - 1); + +#define PR2100_TEST_PATTERN 0 +#define PR2100_SLAVE_TEST_PATTERN 0 + +#if (PR2100_TEST_PATTERN) +//1920x1080 offset 0x0 0x1FA400 0x278D00 +// 0 : White eb 80 80 +// 1 : Yellow d2 10 92 +// 2 : Cyan aa a6 10 +// 3 : Green 91 36 22 +// 4 : Magenta 6a ca de +// 5 : Red 51 5a f0 +// 6 : Blue +// 7 : Black +// 8 : Color Bar +// 9 : Ramp +// 10 : Inverse Color Bar +// 11 : Combination Pattern +#define output_pattern_ch0 (0x8 | 0x80) // color bar +#define output_pattern_ch1 (0x8 | 0xA0) // reverse color bar +#define output_pattern_ch2 (0x8 | 0x80) // color bar +#define output_pattern_ch3 (0x8 | 0xA0) // reverse color bar +#else +#define output_pattern_ch0 (0x00) +#define output_pattern_ch1 (0x00) +#define output_pattern_ch2 (0x00) +#define output_pattern_ch3 (0x00) +#endif + +/*gpio*/ +enum CVI_GPIO_NUM_E { +CVI_GPIOD_00 = 404, +CVI_GPIOD_01, CVI_GPIOD_02, CVI_GPIOD_03, CVI_GPIOD_04, CVI_GPIOD_05, +CVI_GPIOD_06, CVI_GPIOD_07, CVI_GPIOD_08, CVI_GPIOD_09, CVI_GPIOD_10, +CVI_GPIOD_11, +CVI_GPIOC_00 = 416, +CVI_GPIOC_01, CVI_GPIOC_02, CVI_GPIOC_03, CVI_GPIOC_04, CVI_GPIOC_05, +CVI_GPIOC_06, CVI_GPIOC_07, CVI_GPIOC_08, CVI_GPIOC_09, CVI_GPIOC_10, +CVI_GPIOC_11, CVI_GPIOC_12, CVI_GPIOC_13, CVI_GPIOC_14, CVI_GPIOC_15, +CVI_GPIOC_16, CVI_GPIOC_17, CVI_GPIOC_18, CVI_GPIOC_19, CVI_GPIOC_20, +CVI_GPIOC_21, CVI_GPIOC_22, CVI_GPIOC_23, CVI_GPIOC_24, CVI_GPIOC_25, +CVI_GPIOC_26, CVI_GPIOC_27, CVI_GPIOC_28, CVI_GPIOC_29, CVI_GPIOC_30, +CVI_GPIOC_31, +CVI_GPIOB_00 = 448, +CVI_GPIOB_01, CVI_GPIOB_02, CVI_GPIOB_03, CVI_GPIOB_04, CVI_GPIOB_05, +CVI_GPIOB_06, CVI_GPIOB_07, CVI_GPIOB_08, CVI_GPIOB_09, CVI_GPIOB_10, +CVI_GPIOB_11, CVI_GPIOB_12, CVI_GPIOB_13, CVI_GPIOB_14, CVI_GPIOB_15, +CVI_GPIOB_16, CVI_GPIOB_17, CVI_GPIOB_18, CVI_GPIOB_19, CVI_GPIOB_20, +CVI_GPIOB_21, CVI_GPIOB_22, CVI_GPIOB_23, CVI_GPIOB_24, CVI_GPIOB_25, +CVI_GPIOB_26, CVI_GPIOB_27, CVI_GPIOB_28, CVI_GPIOB_29, CVI_GPIOB_30, +CVI_GPIOB_31, +CVI_GPIOA_00 = 480, +CVI_GPIOA_01, CVI_GPIOA_02, CVI_GPIOA_03, CVI_GPIOA_04, CVI_GPIOA_05, +CVI_GPIOA_06, CVI_GPIOA_07, CVI_GPIOA_08, CVI_GPIOA_09, CVI_GPIOA_10, +CVI_GPIOA_11, CVI_GPIOA_12, CVI_GPIOA_13, CVI_GPIOA_14, CVI_GPIOA_15, +CVI_GPIOA_16, CVI_GPIOA_17, CVI_GPIOA_18, CVI_GPIOA_19, CVI_GPIOA_20, +CVI_GPIOA_21, CVI_GPIOA_22, CVI_GPIOA_23, CVI_GPIOA_24, CVI_GPIOA_25, +CVI_GPIOA_26, CVI_GPIOA_27, CVI_GPIOA_28, CVI_GPIOA_29, CVI_GPIOA_30, +CVI_GPIOA_31, +}; + +#define CVI_GPIO_MIN CVI_GPIOD_00 +#define CVI_GPIO_MAX CVI_GPIOA_31 + +#define SYSFS_GPIO_DIR "/sys/class/gpio" +#define MAX_BUF 64 + +static int PR2100_GPIO_Export(unsigned int gpio) +{ + int fd, len; + char buf[MAX_BUF]; + + fd = open(SYSFS_GPIO_DIR"/export", O_WRONLY); + if (fd < 0) { + perror("gpio/export"); + return fd; + } + + len = snprintf(buf, sizeof(buf), "%d", gpio); + write(fd, buf, len); + close(fd); + + return 0; +} + +static int PR2100_GPIO_SetDirection(unsigned int gpio, unsigned int out_flag) +{ + int fd; + char buf[MAX_BUF]; + + snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR"/gpio%d/direction", gpio); + if (access(buf, 0) == -1) + PR2100_GPIO_Export(gpio); + + fd = open(buf, O_WRONLY); + if (fd < 0) { + perror("gpio/direction"); + return fd; + } + //printf("mark %d , %s\n",out_flag, buf); + if (out_flag) + write(fd, "out", 4); + else + write(fd, "in", 3); + + close(fd); + return 0; +} + +static int PR2100_GPIO_SetValue(unsigned int gpio, unsigned int value) +{ + int fd; + char buf[MAX_BUF]; + + snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR"/gpio%d/value", gpio); + if (access(buf, 0) == -1) + PR2100_GPIO_Export(gpio); + + PR2100_GPIO_SetDirection(gpio, 1); //output + + fd = open(buf, O_WRONLY); + if (fd < 0) { + perror("gpio/set-value"); + return fd; + } + + if (value) + write(fd, "1", 2); + else + write(fd, "0", 2); + + close(fd); + return 0; +} + +int pr2100_sys_init(VI_PIPE ViPipe) +{ + (void) ViPipe; + + //CAM_PEN + if (PR2100_GPIO_SetValue(CVI_GPIOA_06, 1) != 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "set power down gpio error!\n"); + return CVI_FAILURE; + } +#if 0 + //SENSOR0_RSTN + if (PR2100_GPIO_SetValue(CVI_GPIOD_07, 1) != 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "set reset gpio error!\n"); + return CVI_FAILURE; + } + + //BACK_DET + if (PR2100_GPIO_SetValue(CVI_GPIOD_01, 1) != 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "set back detect gpio error!\n"); + return CVI_FAILURE; + } +#endif + return CVI_SUCCESS; +} + +int pr2100_i2c_init(VI_PIPE ViPipe, CVI_U8 i2c_addr) +{ + int ret; + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + + u8DevNum = g_aunPr2100_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + CVI_TRACE_SNS(CVI_DBG_INFO, "open %s\n", acDevFile); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int pr2100_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int pr2100_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return 0; + + if (pr2100_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, pr2100_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, pr2100_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (pr2100_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + CVI_TRACE_SNS(CVI_DBG_INFO, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int pr2100_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (pr2100_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + if (pr2100_data_byte == 2) + buf[idx++] = (data >> 8) & 0xff; + + // add data byte 0 + buf[idx++] = data & 0xff; + + ret = write(g_fd[ViPipe], buf, pr2100_addr_byte + pr2100_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + CVI_TRACE_SNS(CVI_DBG_INFO, "i2c w 0x%x 0x%x\n", addr, data); + +#if 0 // read back checing + ret = pr2100_read_register(ViPipe, addr); + if (ret != data) + CVI_TRACE_SNS(CVI_DBG_INFO, "i2c readback-check fail, 0x%x != 0x%x\n", ret, data); +#endif + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void pr2100_init(VI_PIPE ViPipe) +{ + CVI_U8 u8ImgMode; + + u8ImgMode = g_pastPr2100[ViPipe]->u8ImgMode; + if (ViPipe) // only init ch0 + return; + + if (pr2100_sys_init(ViPipe) != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "PR2100 sys init fail\n"); + return; + } + + delay_ms(20); + + if (pr2100_i2c_init(ViPipe, pr2100_master_i2c_addr) != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "PR2100 master i2c init fail\n"); + return; + } + + // check sensor chip id + pr2100_write_register(ViPipe, 0xff, 0x00); + if (((pr2100_read_register(ViPipe, 0xfc) << 8) | + (pr2100_read_register(ViPipe, 0xfd))) != 0x2100) { + CVI_TRACE_SNS(CVI_DBG_ERR, "PR2100 master chip id check fail\n"); + return; + } + + CVI_TRACE_SNS(CVI_DBG_INFO, "Loading Pixelplus PR2100 sensor\n"); + + switch (u8ImgMode) { + case PR2100_MODE_1080P: + pr2100_set_1080p(ViPipe); + break; + case PR2100_MODE_1080P_2CH: + pr2100_set_1080p_2ch(ViPipe); + break; + case PR2100_MODE_1080P_4CH: + g_aunPr2100_BusInfo[slave_pipe].s8I2cDev = g_aunPr2100_BusInfo[ViPipe].s8I2cDev; + if (pr2100_i2c_init(slave_pipe, pr2100_slave_i2c_addr) != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "PR2100 slave i2c init fail\n"); + break; + } + pr2100_write_register(slave_pipe, 0xff, 0x00); + if (((pr2100_read_register(slave_pipe, 0xfc) << 8) | + (pr2100_read_register(slave_pipe, 0xfd))) != 0x2100) { + CVI_TRACE_SNS(CVI_DBG_ERR, "PR2100 slave chip id check fail\n"); + break; + } + pr2100_set_1080p_4ch(ViPipe); + break; + default: + break; + } + + // wait for signal to stabilize + delay_ms(800); + pr2100_write_register(ViPipe, 0xff, 0x00);//page0 +} + +void pr2100_exit(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "Exit Pixelplus PR2100 Sensor\n"); + + pr2100_i2c_exit(ViPipe); + + if (g_pastPr2100[ViPipe]->u8ImgMode == PR2100_MODE_1080P_4CH) + pr2100_i2c_exit(slave_pipe); +} + +static void pr2100_set_1080p(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "1CH ViPipe=%d\n", ViPipe); + pr2100_write_register(ViPipe, 0xff, 0x00);//Page0 + pr2100_write_register(ViPipe, 0xc0, 0x21); + pr2100_write_register(ViPipe, 0xc1, 0x21); + pr2100_write_register(ViPipe, 0xc2, 0x21); + pr2100_write_register(ViPipe, 0xc3, 0x21); + pr2100_write_register(ViPipe, 0xc4, 0x21); + pr2100_write_register(ViPipe, 0xc5, 0x21); + pr2100_write_register(ViPipe, 0xc6, 0x21); + pr2100_write_register(ViPipe, 0xc7, 0x21); + pr2100_write_register(ViPipe, 0xc8, 0x21); + pr2100_write_register(ViPipe, 0xc9, 0x01); + pr2100_write_register(ViPipe, 0xca, 0x01); + pr2100_write_register(ViPipe, 0xcb, 0x01); + pr2100_write_register(ViPipe, 0xd0, 0x06); + pr2100_write_register(ViPipe, 0xd1, 0x23); + pr2100_write_register(ViPipe, 0xd2, 0x21); + pr2100_write_register(ViPipe, 0xd3, 0x44); + pr2100_write_register(ViPipe, 0xd4, 0x06); + pr2100_write_register(ViPipe, 0xd5, 0x23); + pr2100_write_register(ViPipe, 0xd6, 0x21); + pr2100_write_register(ViPipe, 0xd7, 0x44); + pr2100_write_register(ViPipe, 0xd8, 0x06); + pr2100_write_register(ViPipe, 0xd9, 0x22); + pr2100_write_register(ViPipe, 0xda, 0x2c); + pr2100_write_register(ViPipe, 0x11, 0x0f); + pr2100_write_register(ViPipe, 0x12, 0x00); + pr2100_write_register(ViPipe, 0x13, 0x00); + pr2100_write_register(ViPipe, 0x14, 0x21); + pr2100_write_register(ViPipe, 0x15, 0x44); + pr2100_write_register(ViPipe, 0x16, 0x0d); + pr2100_write_register(ViPipe, 0x31, 0x0f); + pr2100_write_register(ViPipe, 0x32, 0x00); + pr2100_write_register(ViPipe, 0x33, 0x00); + pr2100_write_register(ViPipe, 0x34, 0x21); + pr2100_write_register(ViPipe, 0x35, 0x44); + pr2100_write_register(ViPipe, 0x36, 0x0d); + pr2100_write_register(ViPipe, 0xf3, 0x06); + pr2100_write_register(ViPipe, 0xf4, 0x66); + pr2100_write_register(ViPipe, 0xff, 0x01);//Page1 + pr2100_write_register(ViPipe, 0x00, 0xe4); + pr2100_write_register(ViPipe, 0x01, 0x61); + pr2100_write_register(ViPipe, 0x02, 0x00); + pr2100_write_register(ViPipe, 0x03, 0x56); + pr2100_write_register(ViPipe, 0x04, 0x0c); + pr2100_write_register(ViPipe, 0x05, 0x88); + pr2100_write_register(ViPipe, 0x06, 0x04); + pr2100_write_register(ViPipe, 0x07, 0xb2); + pr2100_write_register(ViPipe, 0x08, 0x44); + pr2100_write_register(ViPipe, 0x09, 0x34); + pr2100_write_register(ViPipe, 0x0a, 0x02); + pr2100_write_register(ViPipe, 0x0b, 0x14); + pr2100_write_register(ViPipe, 0x0c, 0x04); + pr2100_write_register(ViPipe, 0x0d, 0x08); + pr2100_write_register(ViPipe, 0x0e, 0x5e); + pr2100_write_register(ViPipe, 0x0f, 0x5e); + pr2100_write_register(ViPipe, 0x2c, 0x00); + pr2100_write_register(ViPipe, 0x2d, 0x00); + pr2100_write_register(ViPipe, 0x2e, 0x00); + pr2100_write_register(ViPipe, 0x2f, 0x00); + pr2100_write_register(ViPipe, 0x30, 0x00); + pr2100_write_register(ViPipe, 0x31, 0x00); + pr2100_write_register(ViPipe, 0x32, 0xc0); + pr2100_write_register(ViPipe, 0x3b, 0x02); + pr2100_write_register(ViPipe, 0x3c, 0x01); + pr2100_write_register(ViPipe, 0x4f, 0x00); + pr2100_write_register(ViPipe, 0x51, 0x28); + pr2100_write_register(ViPipe, 0x52, 0x40); + pr2100_write_register(ViPipe, 0x53, 0x0c); + pr2100_write_register(ViPipe, 0x54, 0x0f); + pr2100_write_register(ViPipe, 0x55, 0x8d); + pr2100_write_register(ViPipe, 0x70, 0x06); + pr2100_write_register(ViPipe, 0x71, 0x08); + pr2100_write_register(ViPipe, 0x72, 0x0a); + pr2100_write_register(ViPipe, 0x73, 0x0c); + pr2100_write_register(ViPipe, 0x74, 0x0e); + pr2100_write_register(ViPipe, 0x75, 0x10); + pr2100_write_register(ViPipe, 0x76, 0x12); + pr2100_write_register(ViPipe, 0x77, 0x14); + pr2100_write_register(ViPipe, 0x78, 0x06); + pr2100_write_register(ViPipe, 0x79, 0x08); + pr2100_write_register(ViPipe, 0x7a, 0x0a); + pr2100_write_register(ViPipe, 0x7b, 0x0c); + pr2100_write_register(ViPipe, 0x7c, 0x0e); + pr2100_write_register(ViPipe, 0x7d, 0x10); + pr2100_write_register(ViPipe, 0x7e, 0x12); + pr2100_write_register(ViPipe, 0x7f, 0x14); + pr2100_write_register(ViPipe, 0xff, 0x02);//Page2 + pr2100_write_register(ViPipe, 0x00, 0xe4); + pr2100_write_register(ViPipe, 0x01, 0x61); + pr2100_write_register(ViPipe, 0x02, 0x00); + pr2100_write_register(ViPipe, 0x03, 0x56); + pr2100_write_register(ViPipe, 0x04, 0x0c); + pr2100_write_register(ViPipe, 0x05, 0x88); + pr2100_write_register(ViPipe, 0x06, 0x04); + pr2100_write_register(ViPipe, 0x07, 0xb2); + pr2100_write_register(ViPipe, 0x08, 0x44); + pr2100_write_register(ViPipe, 0x09, 0x34); + pr2100_write_register(ViPipe, 0x0a, 0x02); + pr2100_write_register(ViPipe, 0x0b, 0x14); + pr2100_write_register(ViPipe, 0x0c, 0x04); + pr2100_write_register(ViPipe, 0x0d, 0x08); + pr2100_write_register(ViPipe, 0x0e, 0x5e); + pr2100_write_register(ViPipe, 0x0f, 0x5e); + pr2100_write_register(ViPipe, 0x2c, 0x00); + pr2100_write_register(ViPipe, 0x2d, 0x00); + pr2100_write_register(ViPipe, 0x2e, 0x00); + pr2100_write_register(ViPipe, 0x2f, 0x00); + pr2100_write_register(ViPipe, 0x30, 0x00); + pr2100_write_register(ViPipe, 0x31, 0x00); + pr2100_write_register(ViPipe, 0x32, 0xc0); + pr2100_write_register(ViPipe, 0x3b, 0x02); + pr2100_write_register(ViPipe, 0x3c, 0x01); + pr2100_write_register(ViPipe, 0x4f, 0x00); + pr2100_write_register(ViPipe, 0x51, 0x28); + pr2100_write_register(ViPipe, 0x52, 0x40); + pr2100_write_register(ViPipe, 0x53, 0x0c); + pr2100_write_register(ViPipe, 0x54, 0x0f); + pr2100_write_register(ViPipe, 0x55, 0x8d); + pr2100_write_register(ViPipe, 0x70, 0x06); + pr2100_write_register(ViPipe, 0x71, 0x08); + pr2100_write_register(ViPipe, 0x72, 0x0a); + pr2100_write_register(ViPipe, 0x73, 0x0c); + pr2100_write_register(ViPipe, 0x74, 0x0e); + pr2100_write_register(ViPipe, 0x75, 0x10); + pr2100_write_register(ViPipe, 0x76, 0x12); + pr2100_write_register(ViPipe, 0x77, 0x14); + pr2100_write_register(ViPipe, 0x78, 0x06); + pr2100_write_register(ViPipe, 0x79, 0x08); + pr2100_write_register(ViPipe, 0x7a, 0x0a); + pr2100_write_register(ViPipe, 0x7b, 0x0c); + pr2100_write_register(ViPipe, 0x7c, 0x0e); + pr2100_write_register(ViPipe, 0x7d, 0x10); + pr2100_write_register(ViPipe, 0x7e, 0x12); + pr2100_write_register(ViPipe, 0x7f, 0x14); + pr2100_write_register(ViPipe, 0xff, 0x00);//Page0 + pr2100_write_register(ViPipe, 0x14, 0x21); + pr2100_write_register(ViPipe, 0xff, 0x06);//Page6 + pr2100_write_register(ViPipe, 0x04, 0x50); + pr2100_write_register(ViPipe, 0xff, 0x00);//Page0 + pr2100_write_register(ViPipe, 0xeb, 0x01); + pr2100_write_register(ViPipe, 0xf0, 0x03); + pr2100_write_register(ViPipe, 0xf1, 0xff); + pr2100_write_register(ViPipe, 0xea, 0x00); + // pr2100_write_register(ViPipe, 0xe3, 0x04);//Cb-Y-Cr-Y + pr2100_write_register(ViPipe, 0xe3, 0xc4);//Y-Cb-Y-Cr + pr2100_write_register(ViPipe, 0xff, 0x01);//Page1 + pr2100_write_register(ViPipe, 0x50, 0x21); + pr2100_write_register(ViPipe, 0x4f, 0x00); + pr2100_write_register(ViPipe, 0x50, 0x21); + pr2100_write_register(ViPipe, 0x4f, 0x20); + pr2100_write_register(ViPipe, 0xff, 0x02);//Page2 + pr2100_write_register(ViPipe, 0x50, 0x21); + pr2100_write_register(ViPipe, 0x4f, 0x00); + pr2100_write_register(ViPipe, 0x50, 0x21); + pr2100_write_register(ViPipe, 0x4f, 0x20); + pr2100_write_register(ViPipe, 0xff, 0x01);//Page1 + pr2100_write_register(ViPipe, 0xd1, 0x10); + pr2100_write_register(ViPipe, 0xff, 0x00);//Page0 + pr2100_write_register(ViPipe, 0xe8, 0x00); + pr2100_write_register(ViPipe, 0xe9, 0x10); + pr2100_write_register(ViPipe, 0xff, 0x01);//Page1 + pr2100_write_register(ViPipe, 0xcd, 0x08); + pr2100_write_register(ViPipe, 0x4f, 0x2c); + pr2100_write_register(ViPipe, 0xff, 0x02);//Page2 + pr2100_write_register(ViPipe, 0xd1, 0x10); + pr2100_write_register(ViPipe, 0xff, 0x00);//Page0 + pr2100_write_register(ViPipe, 0xe9, 0x00); + pr2100_write_register(ViPipe, 0xe9, 0x00); + pr2100_write_register(ViPipe, 0xff, 0x02);//Page2 + pr2100_write_register(ViPipe, 0xcd, 0x08); + pr2100_write_register(ViPipe, 0x4f, 0x2c); + pr2100_write_register(ViPipe, 0xff, 0x00);//Page0 + pr2100_write_register(ViPipe, 0xe4, 0x20); + pr2100_write_register(ViPipe, 0xe5, 0x64); + pr2100_write_register(ViPipe, 0xe6, 0x20); + pr2100_write_register(ViPipe, 0xe7, 0x64); + pr2100_write_register(ViPipe, 0xe2, 0x00); + pr2100_write_register(ViPipe, 0xff, 0x06);//Page6 + pr2100_write_register(ViPipe, 0x04, 0x10); + pr2100_write_register(ViPipe, 0x05, 0x04); + pr2100_write_register(ViPipe, 0x06, 0x00); + pr2100_write_register(ViPipe, 0x07, 0x00); + pr2100_write_register(ViPipe, 0x08, 0xc9); + pr2100_write_register(ViPipe, 0x36, 0x0f); + pr2100_write_register(ViPipe, 0x37, 0x00); + pr2100_write_register(ViPipe, 0x38, 0x0f); + pr2100_write_register(ViPipe, 0x39, 0x00); + pr2100_write_register(ViPipe, 0x3a, 0x0f); + pr2100_write_register(ViPipe, 0x3b, 0x00); + pr2100_write_register(ViPipe, 0x3c, 0x0f); + pr2100_write_register(ViPipe, 0x3d, 0x00); + pr2100_write_register(ViPipe, 0x46, 0x1e); + pr2100_write_register(ViPipe, 0x47, 0x5e); + pr2100_write_register(ViPipe, 0x48, 0x9e); + pr2100_write_register(ViPipe, 0x49, 0xde); + pr2100_write_register(ViPipe, 0x1c, 0x09); + pr2100_write_register(ViPipe, 0x1d, 0x08); + pr2100_write_register(ViPipe, 0x1e, 0x09); + pr2100_write_register(ViPipe, 0x1f, 0x11); + pr2100_write_register(ViPipe, 0x20, 0x0c); + pr2100_write_register(ViPipe, 0x21, 0x28); + pr2100_write_register(ViPipe, 0x22, 0x0b); + pr2100_write_register(ViPipe, 0x23, 0x01); + pr2100_write_register(ViPipe, 0x24, 0x12); + pr2100_write_register(ViPipe, 0x25, 0x82); + pr2100_write_register(ViPipe, 0x26, 0x11); + pr2100_write_register(ViPipe, 0x27, 0x11); + pr2100_write_register(ViPipe, 0x04, 0x50); + pr2100_write_register(ViPipe, 0xff, 0x05);//Page5 + pr2100_write_register(ViPipe, 0x09, 0x00); + pr2100_write_register(ViPipe, 0x0a, 0x03); + pr2100_write_register(ViPipe, 0x0e, 0x80); + pr2100_write_register(ViPipe, 0x0f, 0x10); + pr2100_write_register(ViPipe, 0x11, 0x80); + pr2100_write_register(ViPipe, 0x12, 0x6e); + pr2100_write_register(ViPipe, 0x13, 0x00); + pr2100_write_register(ViPipe, 0x14, 0x6e); + pr2100_write_register(ViPipe, 0x15, 0x00); + pr2100_write_register(ViPipe, 0x16, 0x00); + pr2100_write_register(ViPipe, 0x17, 0x00); + pr2100_write_register(ViPipe, 0x18, 0x00); + pr2100_write_register(ViPipe, 0x19, 0x00); + pr2100_write_register(ViPipe, 0x1a, 0x00); + pr2100_write_register(ViPipe, 0x1b, 0x00); + pr2100_write_register(ViPipe, 0x1c, 0x00); + pr2100_write_register(ViPipe, 0x1d, 0x00); + pr2100_write_register(ViPipe, 0x1e, 0x00); + pr2100_write_register(ViPipe, 0x20, 0x88); + pr2100_write_register(ViPipe, 0x21, 0x07); + pr2100_write_register(ViPipe, 0x22, 0x80); + pr2100_write_register(ViPipe, 0x23, 0x04); + pr2100_write_register(ViPipe, 0x24, 0x38); + pr2100_write_register(ViPipe, 0x25, 0x0f); + pr2100_write_register(ViPipe, 0x26, 0x00); + pr2100_write_register(ViPipe, 0x27, 0x0f); + pr2100_write_register(ViPipe, 0x28, 0x00); + pr2100_write_register(ViPipe, 0x29, 0x0b); + pr2100_write_register(ViPipe, 0x2a, 0x40); + pr2100_write_register(ViPipe, 0x30, 0x18); + pr2100_write_register(ViPipe, 0x31, 0x07); + pr2100_write_register(ViPipe, 0x32, 0x80); + pr2100_write_register(ViPipe, 0x33, 0x04); + pr2100_write_register(ViPipe, 0x34, 0x38); + pr2100_write_register(ViPipe, 0x35, 0x0f); + pr2100_write_register(ViPipe, 0x36, 0x00); + pr2100_write_register(ViPipe, 0x37, 0x0f); + pr2100_write_register(ViPipe, 0x38, 0x00); + pr2100_write_register(ViPipe, 0x39, 0x07); + pr2100_write_register(ViPipe, 0x3a, 0x80); + pr2100_write_register(ViPipe, 0x40, 0x28); + pr2100_write_register(ViPipe, 0x41, 0x07); + pr2100_write_register(ViPipe, 0x42, 0x80); + pr2100_write_register(ViPipe, 0x43, 0x04); + pr2100_write_register(ViPipe, 0x44, 0x38); + pr2100_write_register(ViPipe, 0x45, 0x0f); + pr2100_write_register(ViPipe, 0x46, 0x00); + pr2100_write_register(ViPipe, 0x47, 0x0f); + pr2100_write_register(ViPipe, 0x48, 0x00); + pr2100_write_register(ViPipe, 0x49, 0x03); + pr2100_write_register(ViPipe, 0x4a, 0xc0); + pr2100_write_register(ViPipe, 0x50, 0x38); + pr2100_write_register(ViPipe, 0x51, 0x07); + pr2100_write_register(ViPipe, 0x52, 0x80); + pr2100_write_register(ViPipe, 0x53, 0x04); + pr2100_write_register(ViPipe, 0x54, 0x38); + pr2100_write_register(ViPipe, 0x55, 0x0f); + pr2100_write_register(ViPipe, 0x56, 0x00); + pr2100_write_register(ViPipe, 0x57, 0x0f); + pr2100_write_register(ViPipe, 0x58, 0x00); + pr2100_write_register(ViPipe, 0x59, 0x00); + pr2100_write_register(ViPipe, 0x5a, 0x00); + pr2100_write_register(ViPipe, 0x60, 0x05); + pr2100_write_register(ViPipe, 0x61, 0x28); + pr2100_write_register(ViPipe, 0x62, 0x05); + pr2100_write_register(ViPipe, 0x63, 0x28); + pr2100_write_register(ViPipe, 0x64, 0x05); + pr2100_write_register(ViPipe, 0x65, 0x28); + pr2100_write_register(ViPipe, 0x66, 0x05); + pr2100_write_register(ViPipe, 0x67, 0x28); + pr2100_write_register(ViPipe, 0x68, 0xff); + pr2100_write_register(ViPipe, 0x69, 0xff); + pr2100_write_register(ViPipe, 0x6a, 0xff); + pr2100_write_register(ViPipe, 0x6b, 0xff); + pr2100_write_register(ViPipe, 0x6c, 0xff); + pr2100_write_register(ViPipe, 0x6d, 0xff); + pr2100_write_register(ViPipe, 0x6e, 0xff); + pr2100_write_register(ViPipe, 0x6f, 0xff); + pr2100_write_register(ViPipe, 0x10, 0xb3); + pr2100_write_register(ViPipe, 0xff, 0x00);//Page0 + pr2100_write_register(ViPipe, 0x80, 0x80); + pr2100_write_register(ViPipe, 0x81, 0x0e); + pr2100_write_register(ViPipe, 0x82, 0x0d); + pr2100_write_register(ViPipe, 0x84, 0xf0); + pr2100_write_register(ViPipe, 0x8a, 0x00); + pr2100_write_register(ViPipe, 0x90, 0x00); + pr2100_write_register(ViPipe, 0x91, 0x00); + pr2100_write_register(ViPipe, 0x94, 0xff); + pr2100_write_register(ViPipe, 0x95, 0xff); + pr2100_write_register(ViPipe, 0xa0, 0x33); + pr2100_write_register(ViPipe, 0xb0, 0x33); + pr2100_write_register(ViPipe, 0xff, 0x01);//Page1 + pr2100_write_register(ViPipe, 0x80, 0x00); + pr2100_write_register(ViPipe, 0x81, 0x09); + pr2100_write_register(ViPipe, 0x82, 0x00); + pr2100_write_register(ViPipe, 0x83, 0x07); + pr2100_write_register(ViPipe, 0x84, 0x00); + pr2100_write_register(ViPipe, 0x85, 0x17); + pr2100_write_register(ViPipe, 0x86, 0x03); + pr2100_write_register(ViPipe, 0x87, 0xe5); + pr2100_write_register(ViPipe, 0x88, 0x05); + pr2100_write_register(ViPipe, 0x89, 0x24); + pr2100_write_register(ViPipe, 0x8a, 0x05); + pr2100_write_register(ViPipe, 0x8b, 0x24); + pr2100_write_register(ViPipe, 0x8c, 0x08); + pr2100_write_register(ViPipe, 0x8d, 0xe8); + pr2100_write_register(ViPipe, 0x8e, 0x05); + pr2100_write_register(ViPipe, 0x8f, 0x47); + pr2100_write_register(ViPipe, 0x90, 0x02); + pr2100_write_register(ViPipe, 0x91, 0xb4); + pr2100_write_register(ViPipe, 0x92, 0x73); + pr2100_write_register(ViPipe, 0x93, 0xe8); + pr2100_write_register(ViPipe, 0x94, 0x0f); + pr2100_write_register(ViPipe, 0x95, 0x5e); + pr2100_write_register(ViPipe, 0x96, 0x03); + pr2100_write_register(ViPipe, 0x97, 0xd0); + pr2100_write_register(ViPipe, 0x98, 0x17); + pr2100_write_register(ViPipe, 0x99, 0x34); + pr2100_write_register(ViPipe, 0x9a, 0x13); + pr2100_write_register(ViPipe, 0x9b, 0x56); + pr2100_write_register(ViPipe, 0x9c, 0x0b); + pr2100_write_register(ViPipe, 0x9d, 0x9a); + pr2100_write_register(ViPipe, 0x9e, 0x09); + pr2100_write_register(ViPipe, 0x9f, 0xab); + pr2100_write_register(ViPipe, 0xa0, 0x01); + pr2100_write_register(ViPipe, 0xa1, 0x74); + pr2100_write_register(ViPipe, 0xa2, 0x01); + pr2100_write_register(ViPipe, 0xa3, 0x6b); + pr2100_write_register(ViPipe, 0xa4, 0x00); + pr2100_write_register(ViPipe, 0xa5, 0xba); + pr2100_write_register(ViPipe, 0xa6, 0x00); + pr2100_write_register(ViPipe, 0xa7, 0xa3); + pr2100_write_register(ViPipe, 0xa8, 0x01); + pr2100_write_register(ViPipe, 0xa9, 0x39); + pr2100_write_register(ViPipe, 0xaa, 0x01); + pr2100_write_register(ViPipe, 0xab, 0x39); + pr2100_write_register(ViPipe, 0xac, 0x00); + pr2100_write_register(ViPipe, 0xad, 0xc1); + pr2100_write_register(ViPipe, 0xae, 0x00); + pr2100_write_register(ViPipe, 0xaf, 0xc1); + pr2100_write_register(ViPipe, 0xb0, 0x05); + pr2100_write_register(ViPipe, 0xb1, 0xcc); + pr2100_write_register(ViPipe, 0xb2, 0x09); + pr2100_write_register(ViPipe, 0xb3, 0x6d); + pr2100_write_register(ViPipe, 0xb4, 0x00); + pr2100_write_register(ViPipe, 0xb5, 0x17); + pr2100_write_register(ViPipe, 0xb6, 0x08); + pr2100_write_register(ViPipe, 0xb7, 0xe8); + pr2100_write_register(ViPipe, 0xb8, 0xb0); + pr2100_write_register(ViPipe, 0xb9, 0xce); + pr2100_write_register(ViPipe, 0xba, 0x90); + pr2100_write_register(ViPipe, 0xbb, 0x00); + pr2100_write_register(ViPipe, 0xbc, 0x00); + pr2100_write_register(ViPipe, 0xbd, 0x04); + pr2100_write_register(ViPipe, 0xbe, 0x07); + pr2100_write_register(ViPipe, 0xbf, 0x80); + pr2100_write_register(ViPipe, 0xc0, 0x00); + pr2100_write_register(ViPipe, 0xc1, 0x00); + pr2100_write_register(ViPipe, 0xc2, 0x44); + pr2100_write_register(ViPipe, 0xc3, 0x38); + pr2100_write_register(ViPipe, 0xc4, output_pattern_ch0); + pr2100_write_register(ViPipe, 0xc9, 0x00); + pr2100_write_register(ViPipe, 0xca, 0x02); + pr2100_write_register(ViPipe, 0xcb, 0x07); + pr2100_write_register(ViPipe, 0xcc, 0x80); + pr2100_write_register(ViPipe, 0xce, 0x20); + pr2100_write_register(ViPipe, 0xcf, 0x04); + pr2100_write_register(ViPipe, 0xd0, 0x38); + pr2100_write_register(ViPipe, 0xd1, 0x00); + pr2100_write_register(ViPipe, 0xd2, 0x00); + pr2100_write_register(ViPipe, 0xd3, 0x00); + pr2100_write_register(ViPipe, 0xff, 0x00);//Page0 + pr2100_write_register(ViPipe, 0x10, 0x83); + pr2100_write_register(ViPipe, 0x12, 0x00); + pr2100_write_register(ViPipe, 0xe0, 0x05); + pr2100_write_register(ViPipe, 0xff, 0x01);//Page1 + pr2100_write_register(ViPipe, 0x10, 0x26); + pr2100_write_register(ViPipe, 0x11, 0x00); + pr2100_write_register(ViPipe, 0x12, 0x87); + pr2100_write_register(ViPipe, 0x13, 0x24); + pr2100_write_register(ViPipe, 0x14, 0x80); + pr2100_write_register(ViPipe, 0x15, 0x2a); + pr2100_write_register(ViPipe, 0x16, 0x38); + pr2100_write_register(ViPipe, 0x17, 0x00); + pr2100_write_register(ViPipe, 0x18, 0x80); + pr2100_write_register(ViPipe, 0x19, 0x48); + pr2100_write_register(ViPipe, 0x1a, 0x6c); + pr2100_write_register(ViPipe, 0x1b, 0x05); + pr2100_write_register(ViPipe, 0x1c, 0x61); + pr2100_write_register(ViPipe, 0x1d, 0x07); + pr2100_write_register(ViPipe, 0x1e, 0x7e); + pr2100_write_register(ViPipe, 0x1f, 0x80); + pr2100_write_register(ViPipe, 0x20, 0x80); + pr2100_write_register(ViPipe, 0x21, 0x80); + pr2100_write_register(ViPipe, 0x22, 0x90); + pr2100_write_register(ViPipe, 0x23, 0x80); + pr2100_write_register(ViPipe, 0x24, 0x80); + pr2100_write_register(ViPipe, 0x25, 0x80); + pr2100_write_register(ViPipe, 0x26, 0x84); + pr2100_write_register(ViPipe, 0x27, 0x82); + pr2100_write_register(ViPipe, 0x28, 0x00); + pr2100_write_register(ViPipe, 0x29, 0xff); + pr2100_write_register(ViPipe, 0x2a, 0xff); + pr2100_write_register(ViPipe, 0x2b, 0x00); + pr2100_write_register(ViPipe, 0x2c, 0x00); + pr2100_write_register(ViPipe, 0x2e, 0x00); + pr2100_write_register(ViPipe, 0x33, 0x14); + pr2100_write_register(ViPipe, 0x34, 0x14); + pr2100_write_register(ViPipe, 0x35, 0x80); + pr2100_write_register(ViPipe, 0x36, 0x80); + pr2100_write_register(ViPipe, 0x37, 0xad); + pr2100_write_register(ViPipe, 0x38, 0x4b); + pr2100_write_register(ViPipe, 0x39, 0x08); + pr2100_write_register(ViPipe, 0x3a, 0x21); + pr2100_write_register(ViPipe, 0x3b, 0x02); + pr2100_write_register(ViPipe, 0x3d, 0x23); + pr2100_write_register(ViPipe, 0x3e, 0x05); + pr2100_write_register(ViPipe, 0x3f, 0xc8); + pr2100_write_register(ViPipe, 0x40, 0x05); + pr2100_write_register(ViPipe, 0x41, 0x55); + pr2100_write_register(ViPipe, 0x42, 0x01); + pr2100_write_register(ViPipe, 0x43, 0x38); + pr2100_write_register(ViPipe, 0x44, 0x6a); + pr2100_write_register(ViPipe, 0x45, 0x00); + pr2100_write_register(ViPipe, 0x46, 0x14); + pr2100_write_register(ViPipe, 0x47, 0xb0); + pr2100_write_register(ViPipe, 0x48, 0xdf); + pr2100_write_register(ViPipe, 0x49, 0x00); + pr2100_write_register(ViPipe, 0x4a, 0x7b); + pr2100_write_register(ViPipe, 0x4b, 0x60); + pr2100_write_register(ViPipe, 0x4c, 0x00); + pr2100_write_register(ViPipe, 0x4d, 0x26); + pr2100_write_register(ViPipe, 0x4e, 0x00); + pr2100_write_register(ViPipe, 0x50, 0x21); + pr2100_write_register(ViPipe, 0x54, 0x0e); + pr2100_write_register(ViPipe, 0x54, 0x0f); +} + +static void pr2100_set_1080p_2ch(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "2CH ViPipe=%d\n", ViPipe); + + pr2100_write_register(ViPipe, 0xFF, 0x00); + pr2100_write_register(ViPipe, 0x10, 0x83); //MAN_IFMT0 + pr2100_write_register(ViPipe, 0x11, 0x0f); //MAN_EQ_DC_GN0 + pr2100_write_register(ViPipe, 0x12, 0x00); //MAN_EQ_AC_GN0 + pr2100_write_register(ViPipe, 0x13, 0x00); //VADC_EQ_BAND0 + pr2100_write_register(ViPipe, 0x14, 0x21); //VADC_CTRL0_0 + pr2100_write_register(ViPipe, 0x15, 0x44); //VADC_CTRL1_0 + pr2100_write_register(ViPipe, 0x16, 0x0d); //VADC_CTRL2_0 + pr2100_write_register(ViPipe, 0x30, 0x83); //MAN_IFMT1 + pr2100_write_register(ViPipe, 0x31, 0x0f); //MAN_EQ_DC_GN1 + pr2100_write_register(ViPipe, 0x32, 0x00); //MAN_EQ_AC_GN1 + pr2100_write_register(ViPipe, 0x33, 0x00); //VADC_EQ_BAND1 + pr2100_write_register(ViPipe, 0x34, 0x21); //VADC_CTRL0_1 + pr2100_write_register(ViPipe, 0x35, 0x44); //VADC_CTRL1_1 + pr2100_write_register(ViPipe, 0x36, 0x0d); //VADC_CTRL2_1 + pr2100_write_register(ViPipe, 0x80, 0x80); //IRQ_CTRL + pr2100_write_register(ViPipe, 0x81, 0x0e); //IRQ_SYNC_PERIOD + pr2100_write_register(ViPipe, 0x82, 0x0d); //WAKE0_PERIOD + pr2100_write_register(ViPipe, 0x84, 0xf0); //IRQ_NOVID_MD + pr2100_write_register(ViPipe, 0x8a, 0x00); //WAKE1_PERIOD + pr2100_write_register(ViPipe, 0x90, 0x00); //IRQENA_WAKE + pr2100_write_register(ViPipe, 0x91, 0x00); //IRQENA_GPIO + pr2100_write_register(ViPipe, 0x94, 0xff); //IRQCLR_WAKE + pr2100_write_register(ViPipe, 0x95, 0xff); //IRQCLR_GPIO + pr2100_write_register(ViPipe, 0xa0, 0x33); //IRQENA_VFD0 + pr2100_write_register(ViPipe, 0xb0, 0x33); //IRQENA_VFD1 + pr2100_write_register(ViPipe, 0xc0, 0x21); //MPP_CTRL0 + pr2100_write_register(ViPipe, 0xc1, 0x21); //MPP_CTRL1 + pr2100_write_register(ViPipe, 0xc2, 0x21); //MPP_CTRL2 + pr2100_write_register(ViPipe, 0xc3, 0x21); //MPP_CTRL3 + pr2100_write_register(ViPipe, 0xc4, 0x21); //MPP_CTRL4 + pr2100_write_register(ViPipe, 0xc5, 0x21); //MPP_CTRL5 + pr2100_write_register(ViPipe, 0xc6, 0x21); //MPP_CTRL6 + pr2100_write_register(ViPipe, 0xc7, 0x21); //MPP_CTRL7 + pr2100_write_register(ViPipe, 0xc8, 0x21); //MPP_CTRL8 + pr2100_write_register(ViPipe, 0xc9, 0x01); //MPP_CTRL9 + pr2100_write_register(ViPipe, 0xca, 0x01); //MPP_CTRLA + pr2100_write_register(ViPipe, 0xcb, 0x01); //MPP_CTRLB + pr2100_write_register(ViPipe, 0xd0, 0x06); //PLL0_CON0 + pr2100_write_register(ViPipe, 0xd1, 0x23); //PLL0_CON1 + pr2100_write_register(ViPipe, 0xd2, 0x21); //PLL0_CON2 + pr2100_write_register(ViPipe, 0xd3, 0x44); //PLL0_CON3 + pr2100_write_register(ViPipe, 0xd4, 0x06); //PLL1_CON0 + pr2100_write_register(ViPipe, 0xd5, 0x23); //PLL1_CON1 + pr2100_write_register(ViPipe, 0xd6, 0x21); //PLL1_CON2 + pr2100_write_register(ViPipe, 0xd7, 0x44); //PLL1_CON3 + pr2100_write_register(ViPipe, 0xd8, 0x06); //PLL2_CON0 + pr2100_write_register(ViPipe, 0xd9, 0x22); //PLL2_CON1 + pr2100_write_register(ViPipe, 0xda, 0x2c); //PLL2_CON2 + pr2100_write_register(ViPipe, 0xe0, 0x05); //LATCH_EN_CON0 + pr2100_write_register(ViPipe, 0xe1, 0x05); //LATCH_EN_CON1 + pr2100_write_register(ViPipe, 0xe2, 0x00); //OUT_FMT + pr2100_write_register(ViPipe, 0xe3, 0xc4); //CHID_NUM, Y-Cb-Y-Cr + pr2100_write_register(ViPipe, 0xe4, 0x20); //CH_SEL0 + pr2100_write_register(ViPipe, 0xe5, 0x64); //CH_SEL1 + pr2100_write_register(ViPipe, 0xe6, 0x20); //CH_SEL2 + pr2100_write_register(ViPipe, 0xe7, 0x64); //CH_SEL3 + pr2100_write_register(ViPipe, 0xe8, 0x00); //VDCKP_PHASE + pr2100_write_register(ViPipe, 0xe9, 0x00); //VDCKN_PHASE + pr2100_write_register(ViPipe, 0xea, 0x00); //CLK_PWDN + pr2100_write_register(ViPipe, 0xeb, 0x01); //MIPI_DATA_EN + pr2100_write_register(ViPipe, 0xf0, 0x03); //PAR_OE_M + pr2100_write_register(ViPipe, 0xf1, 0xff); //PAR_OE_L + pr2100_write_register(ViPipe, 0xf3, 0x06); //PAD_MPP_CTL + pr2100_write_register(ViPipe, 0xf4, 0x66); //PAD_VD_CTL + + pr2100_write_register(ViPipe, 0xFF, 0x01); + pr2100_write_register(ViPipe, 0x00, 0xe4); //VID_CON0 + pr2100_write_register(ViPipe, 0x01, 0x61); //GAINFIT0 + pr2100_write_register(ViPipe, 0x02, 0x00); //PEDFIT0 + pr2100_write_register(ViPipe, 0x03, 0x56); //CLAMP_CON0 + pr2100_write_register(ViPipe, 0x04, 0x0c); //HPLL_CON0_0 + pr2100_write_register(ViPipe, 0x05, 0x88); //HPLL_CON1_0 + pr2100_write_register(ViPipe, 0x06, 0x04); //HPLL_CON2_0 + pr2100_write_register(ViPipe, 0x07, 0xb2); //HPLL_CON3_0 + pr2100_write_register(ViPipe, 0x08, 0x44); //HPLL_CON4_0 + pr2100_write_register(ViPipe, 0x09, 0x34); //HPLL_CON5_0 + pr2100_write_register(ViPipe, 0x0a, 0x02); //HPLL_CON6_0 + pr2100_write_register(ViPipe, 0x0b, 0x14); //STD_POS0_0 + pr2100_write_register(ViPipe, 0x0c, 0x04); //STD_POS1_0 + pr2100_write_register(ViPipe, 0x0d, 0x08); //STD_POS2_0 + pr2100_write_register(ViPipe, 0x0e, 0x5e); //STD_SLICE0_0 + pr2100_write_register(ViPipe, 0x0f, 0x5e); //STD_SLICE1_0 + pr2100_write_register(ViPipe, 0x10, 0x26); //STD_SLICE2_0 + pr2100_write_register(ViPipe, 0x11, 0x00); //HDELAY_MSB0 + pr2100_write_register(ViPipe, 0x12, 0x87); //HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0x13, 0x24); //HDELAY_LSB0 + pr2100_write_register(ViPipe, 0x14, 0x80); //HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x15, 0x2a); //VDELAY0 + pr2100_write_register(ViPipe, 0x16, 0x38); //VACTIVE0 + pr2100_write_register(ViPipe, 0x17, 0x00); //CBG_DELAY_MSB0 + pr2100_write_register(ViPipe, 0x18, 0x80); //CBG_ACTIVE_MSB0 + pr2100_write_register(ViPipe, 0x19, 0x48); //CBG_DELAY_LSB0 + pr2100_write_register(ViPipe, 0x1a, 0x6c); //CBG_ACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x1b, 0x05); //VSMASK_INV_STRT0 + pr2100_write_register(ViPipe, 0x1c, 0x61); //VSMASK_INV_END0 + pr2100_write_register(ViPipe, 0x1d, 0x07); //CBP_DELAY_MSB0 + pr2100_write_register(ViPipe, 0x1e, 0x7e); //CBP_DELAY_LSB0 + pr2100_write_register(ViPipe, 0x1f, 0x80); //HSCL_ACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x20, 0x80); //CONT0 + pr2100_write_register(ViPipe, 0x21, 0x80); //BRGT0 + pr2100_write_register(ViPipe, 0x22, 0x90); //SAT0 + pr2100_write_register(ViPipe, 0x23, 0x80); //HUE0 + pr2100_write_register(ViPipe, 0x24, 0x80); //CB_GAIN0 + pr2100_write_register(ViPipe, 0x25, 0x80); //CR_GAIN0 + pr2100_write_register(ViPipe, 0x26, 0x84); //CB_OFF0 + pr2100_write_register(ViPipe, 0x27, 0x82); //CR_OFF0 + pr2100_write_register(ViPipe, 0x28, 0x00); //Y_OUT_GAIN0 + pr2100_write_register(ViPipe, 0x29, 0xff); //DOWN_HSCL_MSB0 + pr2100_write_register(ViPipe, 0x2a, 0xff); //DOWN_HSCL_LSB0 + pr2100_write_register(ViPipe, 0x2b, 0x00); //MAN_HSCL_ADD0_0 + pr2100_write_register(ViPipe, 0x2c, 0x00); //MAN_HSCL_ADD1_0 + pr2100_write_register(ViPipe, 0x2d, 0x00); //MAN_HSCL_ADD2_0 + pr2100_write_register(ViPipe, 0x2e, 0x00); //MAN_OUTFMT_ADD0_0 + pr2100_write_register(ViPipe, 0x2f, 0x00); //MAN_OUTFMT_ADD1_0 + pr2100_write_register(ViPipe, 0x30, 0x00); //MAN_OUTFMT_ADD2_0 + pr2100_write_register(ViPipe, 0x31, 0x00); //MAN_COMB_MD0 + pr2100_write_register(ViPipe, 0x32, 0xc0); //COMB_CRL_MD0 + pr2100_write_register(ViPipe, 0x33, 0x14); //COMB_CVBS_CRL0_0 + pr2100_write_register(ViPipe, 0x34, 0x14); //COMB_CVBS_CRL1_0 + pr2100_write_register(ViPipe, 0x35, 0x80); //COMB_CVBS_CRL2_0 + pr2100_write_register(ViPipe, 0x36, 0x80); //COMB_CVBS_CRL3_0 + pr2100_write_register(ViPipe, 0x37, 0xad); //HD_Y_NOTCH_MD0 + pr2100_write_register(ViPipe, 0x38, 0x4b); //HD_COMB_FLT_MD0 + pr2100_write_register(ViPipe, 0x39, 0x08); //Y_DYN_PEAK_GN0 + pr2100_write_register(ViPipe, 0x3a, 0x21); //HD_Y_LPF_MD0 + pr2100_write_register(ViPipe, 0x3b, 0x02); //Y_HPF_CORE_MIN0 + pr2100_write_register(ViPipe, 0x3c, 0x01); //Y_HPF_CORE_STEP0 + pr2100_write_register(ViPipe, 0x3d, 0x23); //CORE_CON0 + pr2100_write_register(ViPipe, 0x3e, 0x05); //MAN_CLPF_MD0 + pr2100_write_register(ViPipe, 0x3f, 0xc8); //HD_CTI_CON0 + pr2100_write_register(ViPipe, 0x40, 0x05); //C_LOOP_CON0_0 + pr2100_write_register(ViPipe, 0x41, 0x55); //C_LOOP_CON1_0 + pr2100_write_register(ViPipe, 0x42, 0x01); //C_LOOP_CON2_0 + pr2100_write_register(ViPipe, 0x43, 0x38); //C_LOOP_CON3_0 + pr2100_write_register(ViPipe, 0x44, 0x6a); //C_HUE_CVI0_0 + pr2100_write_register(ViPipe, 0x45, 0x00); //C_HUE_CVI1_0 + pr2100_write_register(ViPipe, 0x46, 0x14); //C_PHASE_REF0_0 + pr2100_write_register(ViPipe, 0x47, 0xb0); //C_PHASE_REF1_0 + pr2100_write_register(ViPipe, 0x48, 0xdf); //C_PHASE_REF2_0 + pr2100_write_register(ViPipe, 0x49, 0x00); //G_GAIN_REF0_0 + pr2100_write_register(ViPipe, 0x4a, 0x7b); //G_GAIN_REF1_0 + pr2100_write_register(ViPipe, 0x4b, 0x60); //MAN_C_GAIN_VAL0_0 + pr2100_write_register(ViPipe, 0x4c, 0x00); //MAN_C_GAIN_VAL1_0 + pr2100_write_register(ViPipe, 0x4d, 0x26); //YC_DELAY0 + pr2100_write_register(ViPipe, 0x4e, 0x00); //HD_HALF_MD0 + pr2100_write_register(ViPipe, 0x4f, 0x2c); //OUTFMT_CON0 + pr2100_write_register(ViPipe, 0x50, 0x21); //TST_EQ_POS0_0 + pr2100_write_register(ViPipe, 0x51, 0x28); //TST_EQ_POS1_0 + pr2100_write_register(ViPipe, 0x52, 0x40); //TST_EQ_POS2_0 + pr2100_write_register(ViPipe, 0x53, 0x0c); //TST_VID_DEC0 + pr2100_write_register(ViPipe, 0x54, 0x0f); //TST_VID_RST0 + pr2100_write_register(ViPipe, 0x55, 0x8d); //PTZ_SLICE_LVL0 + pr2100_write_register(ViPipe, 0x70, 0x06); //COMB_VCRL_VTH1_0 + pr2100_write_register(ViPipe, 0x71, 0x08); //COMB_VCRL_VTH2_0 + pr2100_write_register(ViPipe, 0x72, 0x0a); //COMB_VCRL_VTH3_0 + pr2100_write_register(ViPipe, 0x73, 0x0c); //COMB_VCRL_VTH4_0 + pr2100_write_register(ViPipe, 0x74, 0x0e); //COMB_VCRL_VTH5_0 + pr2100_write_register(ViPipe, 0x75, 0x10); //COMB_VCRL_VTH6_0 + pr2100_write_register(ViPipe, 0x76, 0x12); //COMB_VCRL_VTH7_0 + pr2100_write_register(ViPipe, 0x77, 0x14); //COMB_VCRL_VTH8_0 + pr2100_write_register(ViPipe, 0x78, 0x06); //COMB_VMIX_VTH1_0 + pr2100_write_register(ViPipe, 0x79, 0x08); //COMB_VMIX_VTH2_0 + pr2100_write_register(ViPipe, 0x7a, 0x0a); //COMB_VMIX_VTH3_0 + pr2100_write_register(ViPipe, 0x7b, 0x0c); //COMB_VMIX_VTH4_0 + pr2100_write_register(ViPipe, 0x7c, 0x0e); //COMB_VMIX_VTH5_0 + pr2100_write_register(ViPipe, 0x7d, 0x10); //COMB_VMIX_VTH6_0 + pr2100_write_register(ViPipe, 0x7e, 0x12); //COMB_VMIX_VTH7_0 + pr2100_write_register(ViPipe, 0x7f, 0x14); //COMB_VMIX_VTH8_0 + pr2100_write_register(ViPipe, 0x80, 0x00); //STD_VPOS_PVI_960MSB0 + pr2100_write_register(ViPipe, 0x81, 0x09); //STD_VPOS_PVI_960LSB0 + pr2100_write_register(ViPipe, 0x82, 0x00); //STD_VPOS_CVI_960MSB0 + pr2100_write_register(ViPipe, 0x83, 0x07); //STD_VPOS_CVI_960LSB0 + pr2100_write_register(ViPipe, 0x84, 0x00); //STD_VPOS_AHD_960MSB0 + pr2100_write_register(ViPipe, 0x85, 0x17); //STD_VPOS_AHD_960LSB0 + pr2100_write_register(ViPipe, 0x86, 0x03); //STD_VPOS_TVI_960MSB0 + pr2100_write_register(ViPipe, 0x87, 0xe5); //STD_VPOS_TVI_960LSB0 + pr2100_write_register(ViPipe, 0x88, 0x05); //STD_HPOS_PVI_960MSB0 + pr2100_write_register(ViPipe, 0x89, 0x24); //STD_HPOS_PVI_960LSB0 + pr2100_write_register(ViPipe, 0x8a, 0x05); //STD_HPOS_CVI_960MSB0 + pr2100_write_register(ViPipe, 0x8b, 0x24); //STD_HPOS_CVI_960LSB0 + pr2100_write_register(ViPipe, 0x8c, 0x08); //STD_HPOS_AHD_960MSB0 + pr2100_write_register(ViPipe, 0x8d, 0xe8); //STD_HPOS_AHD_960LSB0 + pr2100_write_register(ViPipe, 0x8e, 0x05); //STD_HPOS_TVI_960MSB0 + pr2100_write_register(ViPipe, 0x8f, 0x47); //STD_HPOS_TVI_960LSB0 + pr2100_write_register(ViPipe, 0x90, 0x02); //VSYNC_ACCUM_960MSB0 + pr2100_write_register(ViPipe, 0x91, 0xb4); //VSYNC_ACCUM_960LSB0 + pr2100_write_register(ViPipe, 0x92, 0x73); //VLINE_MAX_960_MSB0 + pr2100_write_register(ViPipe, 0x93, 0xe8); //VLINE_MAX_960_LSB0 + pr2100_write_register(ViPipe, 0x94, 0x0f); //SLICE_VSYNC0 + pr2100_write_register(ViPipe, 0x95, 0x5e); //STD_SLICE_AHD0 + pr2100_write_register(ViPipe, 0x96, 0x03); //HACT_SIZE_960_MSB0 + pr2100_write_register(ViPipe, 0x97, 0xd0); //HACT_SIZE_960_LSB0 + pr2100_write_register(ViPipe, 0x98, 0x17); //HPERIOD_960P25MSB0 + pr2100_write_register(ViPipe, 0x99, 0x34); //HPERIOD_960P25LSB0 + pr2100_write_register(ViPipe, 0x9a, 0x13); //HPERIOD_960P30MSB0 + pr2100_write_register(ViPipe, 0x9b, 0x56); //HPERIOD_960P30LSB0 + pr2100_write_register(ViPipe, 0x9c, 0x0b); //HPERIOD_960P50MSB0 + pr2100_write_register(ViPipe, 0x9d, 0x9a); //HPERIOD_960P50LSB0 + pr2100_write_register(ViPipe, 0x9e, 0x09); //HPERIOD_960P60MSB0 + pr2100_write_register(ViPipe, 0x9f, 0xab); //HPERIOD_960P60LSB0 + pr2100_write_register(ViPipe, 0xa0, 0x01); //VALY_STRT_960P25MSB0 + pr2100_write_register(ViPipe, 0xa1, 0x74); //VALY_STRT_960P25LSB0 + pr2100_write_register(ViPipe, 0xa2, 0x01); //VALY_STRT_960P30MSB0 + pr2100_write_register(ViPipe, 0xa3, 0x6b); //VALY_STRT_960P30LSB0 + pr2100_write_register(ViPipe, 0xa4, 0x00); //VALY_STRT_960P50MSB0 + pr2100_write_register(ViPipe, 0xa5, 0xba); //VALY_STRT_960P50LSB0 + pr2100_write_register(ViPipe, 0xa6, 0x00); //VALY_STRT_960P60MSB0 + pr2100_write_register(ViPipe, 0xa7, 0xa3); //VALY_STRT_960P60LSB0 + pr2100_write_register(ViPipe, 0xa8, 0x01); //PED_STRT_960P25MSB0 + pr2100_write_register(ViPipe, 0xa9, 0x39); //PED_STRT_960P25LSB0 + pr2100_write_register(ViPipe, 0xaa, 0x01); //PED_STRT_960P30MSB0 + pr2100_write_register(ViPipe, 0xab, 0x39); //PED_STRT_960P30LSB0 + pr2100_write_register(ViPipe, 0xac, 0x00); //PED_STRT_960P50MSB0 + pr2100_write_register(ViPipe, 0xad, 0xc1); //PED_STRT_960P50LSB0 + pr2100_write_register(ViPipe, 0xae, 0x00); //PED_STRT_960P60MSB0 + pr2100_write_register(ViPipe, 0xaf, 0xc1); //PED_STRT_960P60LSB0 + pr2100_write_register(ViPipe, 0xb0, 0x05); //COMB_MEM_960PMSB0 + pr2100_write_register(ViPipe, 0xb1, 0xcc); //COMB_MEM_960PLSB0 + pr2100_write_register(ViPipe, 0xb2, 0x09); //C_JIT_GAIN_960PMSB0 + pr2100_write_register(ViPipe, 0xb3, 0x6d); //C_JIT_GAIN_960PLSB0 + pr2100_write_register(ViPipe, 0xb4, 0x00); //STD_VPOS_AHD_MSB0 + pr2100_write_register(ViPipe, 0xb5, 0x17); //STD_VPOS_AHD_LSB0 + pr2100_write_register(ViPipe, 0xb6, 0x08); //STD_HPOS_AHD_MSB0 + pr2100_write_register(ViPipe, 0xb7, 0xe8); //STD_HPOS_AHD_LSB0 + pr2100_write_register(ViPipe, 0xb8, 0xb0); //STD_TVI_OFFSET_25F0 + pr2100_write_register(ViPipe, 0xb9, 0xce); //STD_TVI_OFFSET_30F0 + pr2100_write_register(ViPipe, 0xba, 0x90); //STD_TVI_OFFSET_960P0 + pr2100_write_register(ViPipe, 0xbb, 0x00); //EXT_SYNC_CON0 + pr2100_write_register(ViPipe, 0xbc, 0x00); //VOSYNC_HDELAY_MSB0 + pr2100_write_register(ViPipe, 0xbd, 0x04); //VOSYNC_HDELAY_LSB0 + pr2100_write_register(ViPipe, 0xbe, 0x07); //VOSYNC_HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xbf, 0x80); //VOSYNC_HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xc0, 0x00); //VOSYNC_VDELAY_MSB0 + pr2100_write_register(ViPipe, 0xc1, 0x00); //VOSYNC_VDELAY_LSB0 + #if PR2100_TEST_PATTERN + pr2100_write_register(ViPipe, 0xc2, 0x44); + pr2100_write_register(ViPipe, 0xc3, 0x38); + #else + pr2100_write_register(ViPipe, 0xc2, 0x04); //VOSYNC_VACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xc3, 0x39); //VOSYNC_VACTIVE_LSB0 + #endif + pr2100_write_register(ViPipe, 0xc4, output_pattern_ch0); + pr2100_write_register(ViPipe, 0xc9, 0x00); //VISYNC_HDELAY_MSB0 + pr2100_write_register(ViPipe, 0xca, 0x02); //VISYNC_HDELAY_LSB0 + pr2100_write_register(ViPipe, 0xcb, 0x07); //VISYNC_HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xcc, 0x80); //VISYNC_HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xcd, 0x08); //VISYNC_VDELAY_MSB0 + pr2100_write_register(ViPipe, 0xce, 0x20); //VISYNC_VDELAY_LSB0 + pr2100_write_register(ViPipe, 0xcf, 0x04); //VISYNC_VACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xd0, 0x38); //VISYNC_VACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xd1, 0x00); //MIPI_DATA_FLD_CON_0 + pr2100_write_register(ViPipe, 0xd2, 0x00); //MIPI_DATA_ODD_VAL_0 + pr2100_write_register(ViPipe, 0xd3, 0x00); //MIPI_DATA_EVEN_VAL_0 + + pr2100_write_register(ViPipe, 0xFF, 0x02); + pr2100_write_register(ViPipe, 0x00, 0xe4); //VID_CON1 + pr2100_write_register(ViPipe, 0x01, 0x61); //GAINFIT1 + pr2100_write_register(ViPipe, 0x02, 0x00); //PEDFIT1 + pr2100_write_register(ViPipe, 0x03, 0x56); //CLAMP_CON1 + pr2100_write_register(ViPipe, 0x04, 0x0c); //HPLL_CON0_1 + pr2100_write_register(ViPipe, 0x05, 0x88); //HPLL_CON1_1 + pr2100_write_register(ViPipe, 0x06, 0x04); //HPLL_CON2_1 + pr2100_write_register(ViPipe, 0x07, 0xb2); //HPLL_CON3_1 + pr2100_write_register(ViPipe, 0x08, 0x44); //HPLL_CON4_1 + pr2100_write_register(ViPipe, 0x09, 0x34); //HPLL_CON5_1 + pr2100_write_register(ViPipe, 0x0a, 0x02); //HPLL_CON6_1 + pr2100_write_register(ViPipe, 0x0b, 0x14); //STD_POS0_1 + pr2100_write_register(ViPipe, 0x0c, 0x04); //STD_POS1_1 + pr2100_write_register(ViPipe, 0x0d, 0x08); //STD_POS2_1 + pr2100_write_register(ViPipe, 0x0e, 0x5e); //STD_SLICE0_1 + pr2100_write_register(ViPipe, 0x0f, 0x5e); //STD_SLICE1_1 + pr2100_write_register(ViPipe, 0x10, 0x26); //STD_SLICE2_1 + pr2100_write_register(ViPipe, 0x11, 0x00); //HDELAY_MSB1 + pr2100_write_register(ViPipe, 0x12, 0x87); //HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0x13, 0x24); //HDELAY_LSB1 + pr2100_write_register(ViPipe, 0x14, 0x80); //HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x15, 0x2a); //VDELAY1 + pr2100_write_register(ViPipe, 0x16, 0x38); //VACTIVE1 + pr2100_write_register(ViPipe, 0x17, 0x00); //CBG_DELAY_MSB1 + pr2100_write_register(ViPipe, 0x18, 0x80); //CBG_ACTIVE_MSB1 + pr2100_write_register(ViPipe, 0x19, 0x48); //CBG_DELAY_LSB1 + pr2100_write_register(ViPipe, 0x1a, 0x6c); //CBG_ACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x1b, 0x05); //VSMASK_INV_STRT1 + pr2100_write_register(ViPipe, 0x1c, 0x61); //VSMASK_INV_END1 + pr2100_write_register(ViPipe, 0x1d, 0x07); //CBP_DELAY_MSB1 + pr2100_write_register(ViPipe, 0x1e, 0x7e); //CBP_DELAY_LSB1 + pr2100_write_register(ViPipe, 0x1f, 0x80); //HSCL_ACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x20, 0x80); //CONT1 + pr2100_write_register(ViPipe, 0x21, 0x80); //BRGT1 + pr2100_write_register(ViPipe, 0x22, 0x90); //SAT1 + pr2100_write_register(ViPipe, 0x23, 0x80); //HUE1 + pr2100_write_register(ViPipe, 0x24, 0x80); //CB_GAIN1 + pr2100_write_register(ViPipe, 0x25, 0x80); //CR_GAIN1 + pr2100_write_register(ViPipe, 0x26, 0x84); //CB_OFF1 + pr2100_write_register(ViPipe, 0x27, 0x82); //CR_OFF1 + pr2100_write_register(ViPipe, 0x28, 0x00); //Y_OUT_GAIN1 + pr2100_write_register(ViPipe, 0x29, 0xff); //DOWN_HSCL_MSB1 + pr2100_write_register(ViPipe, 0x2a, 0xff); //DOWN_HSCL_LSB1 + pr2100_write_register(ViPipe, 0x2b, 0x00); //MAN_HSCL_ADD0_1 + pr2100_write_register(ViPipe, 0x2c, 0x00); //MAN_HSCL_ADD1_1 + pr2100_write_register(ViPipe, 0x2d, 0x00); //MAN_HSCL_ADD2_1 + pr2100_write_register(ViPipe, 0x2e, 0x00); //MAN_OUTFMT_ADD0_1 + pr2100_write_register(ViPipe, 0x2f, 0x00); //MAN_OUTFMT_ADD1_1 + pr2100_write_register(ViPipe, 0x30, 0x00); //MAN_OUTFMT_ADD2_1 + pr2100_write_register(ViPipe, 0x31, 0x00); //MAN_COMB_MD1 + pr2100_write_register(ViPipe, 0x32, 0xc0); //COMB_CRL_MD1 + pr2100_write_register(ViPipe, 0x33, 0x14); //COMB_CVBS_CRL0_1 + pr2100_write_register(ViPipe, 0x34, 0x14); //COMB_CVBS_CRL1_1 + pr2100_write_register(ViPipe, 0x35, 0x80); //COMB_CVBS_CRL2_1 + pr2100_write_register(ViPipe, 0x36, 0x80); //COMB_CVBS_CRL3_1 + pr2100_write_register(ViPipe, 0x37, 0xad); //HD_Y_NOTCH_MD1 + pr2100_write_register(ViPipe, 0x38, 0x4b); //HD_COMB_FLT_MD1 + pr2100_write_register(ViPipe, 0x39, 0x08); //Y_DYN_PEAK_GN1 + pr2100_write_register(ViPipe, 0x3a, 0x21); //HD_Y_LPF_MD1 + pr2100_write_register(ViPipe, 0x3b, 0x02); //Y_HPF_CORE_MIN1 + pr2100_write_register(ViPipe, 0x3c, 0x01); //Y_HPF_CORE_STEP1 + pr2100_write_register(ViPipe, 0x3d, 0x23); //CORE_CON1 + pr2100_write_register(ViPipe, 0x3e, 0x05); //MAN_CLPF_MD1 + pr2100_write_register(ViPipe, 0x3f, 0xc8); //HD_CTI_CON1 + pr2100_write_register(ViPipe, 0x40, 0x05); //C_LOOP_CON0_1 + pr2100_write_register(ViPipe, 0x41, 0x55); //C_LOOP_CON1_1 + pr2100_write_register(ViPipe, 0x42, 0x01); //C_LOOP_CON2_1 + pr2100_write_register(ViPipe, 0x43, 0x38); //C_LOOP_CON3_1 + pr2100_write_register(ViPipe, 0x44, 0x6a); //C_HUE_CVI0_1 + pr2100_write_register(ViPipe, 0x45, 0x00); //C_HUE_CVI1_1 + pr2100_write_register(ViPipe, 0x46, 0x14); //C_PHASE_REF0_1 + pr2100_write_register(ViPipe, 0x47, 0xb0); //C_PHASE_REF1_1 + pr2100_write_register(ViPipe, 0x48, 0xdf); //C_PHASE_REF2_1 + pr2100_write_register(ViPipe, 0x49, 0x00); //G_GAIN_REF0_1 + pr2100_write_register(ViPipe, 0x4a, 0x7b); //G_GAIN_REF1_1 + pr2100_write_register(ViPipe, 0x4b, 0x60); //MAN_C_GAIN_VAL0_1 + pr2100_write_register(ViPipe, 0x4c, 0x00); //MAN_C_GAIN_VAL1_1 + pr2100_write_register(ViPipe, 0x4d, 0x26); //YC_DELAY1 + pr2100_write_register(ViPipe, 0x4e, 0x00); //HD_HALF_MD1 + pr2100_write_register(ViPipe, 0x4f, 0x2c); //OUTFMT_CON1 + pr2100_write_register(ViPipe, 0x50, 0x21); //TST_EQ_POS0_1 + pr2100_write_register(ViPipe, 0x51, 0x28); //TST_EQ_POS1_1 + pr2100_write_register(ViPipe, 0x52, 0x40); //TST_EQ_POS2_1 + pr2100_write_register(ViPipe, 0x53, 0x0c); //TST_VID_DEC1 + pr2100_write_register(ViPipe, 0x54, 0x0f); //TST_VID_RST1 + pr2100_write_register(ViPipe, 0x55, 0x8d); //PTZ_SLICE_LVL1 + pr2100_write_register(ViPipe, 0x70, 0x06); //COMB_VCRL_VTH1_1 + pr2100_write_register(ViPipe, 0x71, 0x08); //COMB_VCRL_VTH2_1 + pr2100_write_register(ViPipe, 0x72, 0x0a); //COMB_VCRL_VTH3_1 + pr2100_write_register(ViPipe, 0x73, 0x0c); //COMB_VCRL_VTH4_1 + pr2100_write_register(ViPipe, 0x74, 0x0e); //COMB_VCRL_VTH5_1 + pr2100_write_register(ViPipe, 0x75, 0x10); //COMB_VCRL_VTH6_1 + pr2100_write_register(ViPipe, 0x76, 0x12); //COMB_VCRL_VTH7_1 + pr2100_write_register(ViPipe, 0x77, 0x14); //COMB_VCRL_VTH8_1 + pr2100_write_register(ViPipe, 0x78, 0x06); //COMB_VMIX_VTH1_1 + pr2100_write_register(ViPipe, 0x79, 0x08); //COMB_VMIX_VTH2_1 + pr2100_write_register(ViPipe, 0x7a, 0x0a); //COMB_VMIX_VTH3_1 + pr2100_write_register(ViPipe, 0x7b, 0x0c); //COMB_VMIX_VTH4_1 + pr2100_write_register(ViPipe, 0x7c, 0x0e); //COMB_VMIX_VTH5_1 + pr2100_write_register(ViPipe, 0x7d, 0x10); //COMB_VMIX_VTH6_1 + pr2100_write_register(ViPipe, 0x7e, 0x12); //COMB_VMIX_VTH7_1 + pr2100_write_register(ViPipe, 0x7f, 0x14); //COMB_VMIX_VTH8_1 + pr2100_write_register(ViPipe, 0x80, 0x00); //STD_VPOS_PVI_960MSB1 + pr2100_write_register(ViPipe, 0x81, 0x09); //STD_VPOS_PVI_960LSB1 + pr2100_write_register(ViPipe, 0x82, 0x00); //STD_VPOS_CVI_960MSB1 + pr2100_write_register(ViPipe, 0x83, 0x07); //STD_VPOS_CVI_960LSB1 + pr2100_write_register(ViPipe, 0x84, 0x00); //STD_VPOS_AHD_960MSB1 + pr2100_write_register(ViPipe, 0x85, 0x17); //STD_VPOS_AHD_960LSB1 + pr2100_write_register(ViPipe, 0x86, 0x03); //STD_VPOS_TVI_960MSB1 + pr2100_write_register(ViPipe, 0x87, 0xe5); //STD_VPOS_TVI_960LSB1 + pr2100_write_register(ViPipe, 0x88, 0x05); //STD_HPOS_PVI_960MSB1 + pr2100_write_register(ViPipe, 0x89, 0x24); //STD_HPOS_PVI_960LSB1 + pr2100_write_register(ViPipe, 0x8a, 0x05); //STD_HPOS_CVI_960MSB1 + pr2100_write_register(ViPipe, 0x8b, 0x24); //STD_HPOS_CVI_960LSB1 + pr2100_write_register(ViPipe, 0x8c, 0x08); //STD_HPOS_AHD_960MSB1 + pr2100_write_register(ViPipe, 0x8d, 0xe8); //STD_HPOS_AHD_960LSB1 + pr2100_write_register(ViPipe, 0x8e, 0x05); //STD_HPOS_TVI_960MSB1 + pr2100_write_register(ViPipe, 0x8f, 0x47); //STD_HPOS_TVI_960LSB1 + pr2100_write_register(ViPipe, 0x90, 0x02); //VSYNC_ACCUM_960MSB1 + pr2100_write_register(ViPipe, 0x91, 0xb4); //VSYNC_ACCUM_960LSB1 + pr2100_write_register(ViPipe, 0x92, 0x73); //VLINE_MAX_960_MSB1 + pr2100_write_register(ViPipe, 0x93, 0xe8); //VLINE_MAX_960_LSB1 + pr2100_write_register(ViPipe, 0x94, 0x0f); //SLICE_VSYNC1 + pr2100_write_register(ViPipe, 0x95, 0x5e); //STD_SLICE_AHD1 + pr2100_write_register(ViPipe, 0x96, 0x03); //HACT_SIZE_960_MSB1 + pr2100_write_register(ViPipe, 0x97, 0xd0); //HACT_SIZE_960_LSB1 + pr2100_write_register(ViPipe, 0x98, 0x17); //HPERIOD_960P25MSB1 + pr2100_write_register(ViPipe, 0x99, 0x34); //HPERIOD_960P25LSB1 + pr2100_write_register(ViPipe, 0x9a, 0x13); //HPERIOD_960P30MSB1 + pr2100_write_register(ViPipe, 0x9b, 0x56); //HPERIOD_960P30LSB1 + pr2100_write_register(ViPipe, 0x9c, 0x0b); //HPERIOD_960P50MSB1 + pr2100_write_register(ViPipe, 0x9d, 0x9a); //HPERIOD_960P50LSB1 + pr2100_write_register(ViPipe, 0x9e, 0x09); //HPERIOD_960P60MSB1 + pr2100_write_register(ViPipe, 0x9f, 0xab); //HPERIOD_960P60LSB1 + pr2100_write_register(ViPipe, 0xa0, 0x01); //VALY_STRT_960P25MSB1 + pr2100_write_register(ViPipe, 0xa1, 0x74); //VALY_STRT_960P25LSB1 + pr2100_write_register(ViPipe, 0xa2, 0x01); //VALY_STRT_960P30MSB1 + pr2100_write_register(ViPipe, 0xa3, 0x6b); //VALY_STRT_960P30LSB1 + pr2100_write_register(ViPipe, 0xa4, 0x00); //VALY_STRT_960P50MSB1 + pr2100_write_register(ViPipe, 0xa5, 0xba); //VALY_STRT_960P50LSB1 + pr2100_write_register(ViPipe, 0xa6, 0x00); //VALY_STRT_960P60MSB1 + pr2100_write_register(ViPipe, 0xa7, 0xa3); //VALY_STRT_960P60LSB1 + pr2100_write_register(ViPipe, 0xa8, 0x01); //PED_STRT_960P25MSB1 + pr2100_write_register(ViPipe, 0xa9, 0x39); //PED_STRT_960P25LSB1 + pr2100_write_register(ViPipe, 0xaa, 0x01); //PED_STRT_960P30MSB1 + pr2100_write_register(ViPipe, 0xab, 0x39); //PED_STRT_960P30LSB1 + pr2100_write_register(ViPipe, 0xac, 0x00); //PED_STRT_960P50MSB1 + pr2100_write_register(ViPipe, 0xad, 0xc1); //PED_STRT_960P50LSB1 + pr2100_write_register(ViPipe, 0xae, 0x00); //PED_STRT_960P60MSB1 + pr2100_write_register(ViPipe, 0xaf, 0xc1); //PED_STRT_960P60LSB1 + pr2100_write_register(ViPipe, 0xb0, 0x05); //COMB_MEM_960PMSB1 + pr2100_write_register(ViPipe, 0xb1, 0xcc); //COMB_MEM_960PLSB1 + pr2100_write_register(ViPipe, 0xb2, 0x09); //C_JIT_GAIN_960PMSB1 + pr2100_write_register(ViPipe, 0xb3, 0x6d); //C_JIT_GAIN_960PLSB1 + pr2100_write_register(ViPipe, 0xb4, 0x00); //STD_VPOS_AHD_MSB1 + pr2100_write_register(ViPipe, 0xb5, 0x17); //STD_VPOS_AHD_LSB1 + pr2100_write_register(ViPipe, 0xb6, 0x08); //STD_HPOS_AHD_MSB1 + pr2100_write_register(ViPipe, 0xb7, 0xe8); //STD_HPOS_AHD_LSB1 + pr2100_write_register(ViPipe, 0xb8, 0xb0); //STD_TVI_OFFSET_25F1 + pr2100_write_register(ViPipe, 0xb9, 0xce); //STD_TVI_OFFSET_30F1 + pr2100_write_register(ViPipe, 0xba, 0x90); //STD_TVI_OFFSET_960P1 + pr2100_write_register(ViPipe, 0xbb, 0x00); //EXT_SYNC_CON1 + pr2100_write_register(ViPipe, 0xbc, 0x00); //VOSYNC_HDELAY_MSB1 + pr2100_write_register(ViPipe, 0xbd, 0x04); //VOSYNC_HDELAY_LSB1 + pr2100_write_register(ViPipe, 0xbe, 0x07); //VOSYNC_HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xbf, 0x80); //VOSYNC_HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xc0, 0x00); //VOSYNC_VDELAY_MSB1 + pr2100_write_register(ViPipe, 0xc1, 0x00); //VOSYNC_VDELAY_LSB1 + #if PR2100_TEST_PATTERN + pr2100_write_register(ViPipe, 0xc2, 0x44); + pr2100_write_register(ViPipe, 0xc3, 0x38); + #else + pr2100_write_register(ViPipe, 0xc2, 0x04); //VOSYNC_VACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xc3, 0x39); //VOSYNC_VACTIVE_LSB1 + #endif + pr2100_write_register(ViPipe, 0xc4, output_pattern_ch1); + pr2100_write_register(ViPipe, 0xc9, 0x00); //VISYNC_HDELAY_MSB1 + pr2100_write_register(ViPipe, 0xca, 0x02); //VISYNC_HDELAY_LSB1 + pr2100_write_register(ViPipe, 0xcb, 0x07); //VISYNC_HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xcc, 0x80); //VISYNC_HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xcd, 0x08); //VISYNC_VDELAY_MSB1 + pr2100_write_register(ViPipe, 0xce, 0x20); //VISYNC_VDELAY_LSB1 + pr2100_write_register(ViPipe, 0xcf, 0x04); //VISYNC_VACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xd0, 0x38); //VISYNC_VACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xd1, 0x00); //MIPI_DATA_FLD_CON_1 + pr2100_write_register(ViPipe, 0xd2, 0x00); //MIPI_DATA_ODD_VAL_1 + pr2100_write_register(ViPipe, 0xd3, 0x00); //MIPI_DATA_EVEN_VAL_1 + + pr2100_write_register(ViPipe, 0xFF, 0x05); + pr2100_write_register(ViPipe, 0x09, 0x00); //REF_CH_STRT + pr2100_write_register(ViPipe, 0x0a, 0x03); //REF_CH_VDLY + pr2100_write_register(ViPipe, 0x0e, 0x80); //VBLK_CODE + pr2100_write_register(ViPipe, 0x0f, 0x10); //VBLK_CODE + pr2100_write_register(ViPipe, 0x10, 0xb3); //MTX_CTRL + pr2100_write_register(ViPipe, 0x11, 0x90); //MTX_LONG_DLY_H + pr2100_write_register(ViPipe, 0x12, 0x6e); //MTX_LONG_DLY_L + pr2100_write_register(ViPipe, 0x13, 0x00); //MTX_SHORT_DLY_H + pr2100_write_register(ViPipe, 0x14, 0x6e); //MTX_SHORT_DLY_L + pr2100_write_register(ViPipe, 0x15, 0x00); //REF_OFFSET + pr2100_write_register(ViPipe, 0x16, 0x00); //REF_FE_HDLY + pr2100_write_register(ViPipe, 0x17, 0x00); //REF_FE_HDLY + pr2100_write_register(ViPipe, 0x18, 0x00); //REF_FS_HDLY + pr2100_write_register(ViPipe, 0x19, 0x00); //REF_FS_HDLY + pr2100_write_register(ViPipe, 0x1a, 0x00); //REF_HTOTAL + pr2100_write_register(ViPipe, 0x1b, 0x00); //REF_HTOTAL + pr2100_write_register(ViPipe, 0x1c, 0x00); //REF_VTOTAL + pr2100_write_register(ViPipe, 0x1d, 0x00); //REF_VTOTAL + pr2100_write_register(ViPipe, 0x1e, 0x00); //CHID_MD + pr2100_write_register(ViPipe, 0x20, 0x88); //MTX_CH0_CTRL + pr2100_write_register(ViPipe, 0x21, 0x07); //MTX_CH0_HSIZE + pr2100_write_register(ViPipe, 0x22, 0x80); //MTX_CH0_HSIZE + pr2100_write_register(ViPipe, 0x23, 0x04); //MTX_CH0_VSIZE + pr2100_write_register(ViPipe, 0x24, 0x38); //MTX_CH0_VSIZE + pr2100_write_register(ViPipe, 0x25, 0x0f); //CH0_FS_OS_H + pr2100_write_register(ViPipe, 0x26, 0x00); //CH0_FS_OS_L + pr2100_write_register(ViPipe, 0x27, 0x0f); //CH0_FE_OS_H + pr2100_write_register(ViPipe, 0x28, 0x00); //CH0_FE_OS_L + pr2100_write_register(ViPipe, 0x29, 0x0b); //REF_CH0_VS_OS + pr2100_write_register(ViPipe, 0x2a, 0x40); //REF_CH0_VS_OS + pr2100_write_register(ViPipe, 0x30, 0x98); //MTX_CH1_CTRL + pr2100_write_register(ViPipe, 0x31, 0x07); //MTX_CH1_HSIZE + pr2100_write_register(ViPipe, 0x32, 0x80); //MTX_CH1_HSIZE + pr2100_write_register(ViPipe, 0x33, 0x04); //MTX_CH1_VSIZE + pr2100_write_register(ViPipe, 0x34, 0x38); //MTX_CH1_VSIZE + pr2100_write_register(ViPipe, 0x35, 0x0f); //CH1_FS_OS_H + pr2100_write_register(ViPipe, 0x36, 0x00); //CH1_FS_OS_L + pr2100_write_register(ViPipe, 0x37, 0x0f); //CH1_FE_OS_H + pr2100_write_register(ViPipe, 0x38, 0x00); //CH1_FE_OS_L + pr2100_write_register(ViPipe, 0x39, 0x07); //REF_CH1_VS_OS + pr2100_write_register(ViPipe, 0x3a, 0x80); //REF_CH1_VS_OS + pr2100_write_register(ViPipe, 0x40, 0x28); //MTX_CH2_CTRL + pr2100_write_register(ViPipe, 0x41, 0x07); //MTX_CH2_HSIZE + pr2100_write_register(ViPipe, 0x42, 0x80); //MTX_CH2_HSIZE + pr2100_write_register(ViPipe, 0x43, 0x04); //MTX_CH2_VSIZE + pr2100_write_register(ViPipe, 0x44, 0x38); //MTX_CH2_VSIZE + pr2100_write_register(ViPipe, 0x45, 0x0f); //CH2_FS_OS_H + pr2100_write_register(ViPipe, 0x46, 0x00); //CH2_FS_OS_L + pr2100_write_register(ViPipe, 0x47, 0x0f); //CH2_FE_OS_H + pr2100_write_register(ViPipe, 0x48, 0x00); //CH2_FE_OS_L + pr2100_write_register(ViPipe, 0x49, 0x03); //REF_CH2_VS_OS + pr2100_write_register(ViPipe, 0x4a, 0xc0); //REF_CH2_VS_OS + pr2100_write_register(ViPipe, 0x50, 0x38); //MTX_CH3_CTRL + pr2100_write_register(ViPipe, 0x51, 0x07); //MTX_CH3_HSIZE + pr2100_write_register(ViPipe, 0x52, 0x80); //MTX_CH3_HSIZE + pr2100_write_register(ViPipe, 0x53, 0x04); //MTX_CH3_VSIZE + pr2100_write_register(ViPipe, 0x54, 0x38); //MTX_CH3_VSIZE + pr2100_write_register(ViPipe, 0x55, 0x0f); //CH3_FS_OS_H + pr2100_write_register(ViPipe, 0x56, 0x00); //CH3_FS_OS_L + pr2100_write_register(ViPipe, 0x57, 0x0f); //CH3_FE_OS_H + pr2100_write_register(ViPipe, 0x58, 0x00); //CH3_FE_OS_L + pr2100_write_register(ViPipe, 0x59, 0x00); //REF_CH3_VS_OS + pr2100_write_register(ViPipe, 0x5a, 0x00); //REF_CH3_VS_OS + pr2100_write_register(ViPipe, 0x60, 0x05); //CH0_HWIDTH[13:8] + pr2100_write_register(ViPipe, 0x61, 0x28); //CH0_HWIDTH [7:0] + pr2100_write_register(ViPipe, 0x62, 0x05); //CH1_HWIDTH[13:8] + pr2100_write_register(ViPipe, 0x63, 0x28); //CH1_HWIDTH [7:0] + pr2100_write_register(ViPipe, 0x64, 0x05); //CH2_HWIDTH[13:8] + pr2100_write_register(ViPipe, 0x65, 0x28); //CH2_HWIDTH [7:0] + pr2100_write_register(ViPipe, 0x66, 0x05); //CH3_HWIDTH[13:8] + pr2100_write_register(ViPipe, 0x67, 0x28); //CH3_HWIDTH [7:0] + pr2100_write_register(ViPipe, 0x68, 0xff); //CH0_VRATE[15:8] + pr2100_write_register(ViPipe, 0x69, 0xff); //CH0_VRATE[7:0] + pr2100_write_register(ViPipe, 0x6a, 0xff); //CH1_VRATE[15:8] + pr2100_write_register(ViPipe, 0x6b, 0xff); //CH1_VRATE[7:0] + pr2100_write_register(ViPipe, 0x6c, 0xff); //CH2_VRATE[15:8] + pr2100_write_register(ViPipe, 0x6d, 0xff); //CH2_VRATE[7:0] + pr2100_write_register(ViPipe, 0x6e, 0xff); //CH3_VRATE[15:8] + pr2100_write_register(ViPipe, 0x6f, 0xff); //CH3_VRATE[7:0] + + pr2100_write_register(ViPipe, 0xFF, 0x06); + pr2100_write_register(ViPipe, 0x04, 0x10); //MIPI_CONTROL_0 + pr2100_write_register(ViPipe, 0x05, 0x04); //MIPI_CONTROL_1 + pr2100_write_register(ViPipe, 0x06, 0x00); //MIPI_CONTROL_2 + pr2100_write_register(ViPipe, 0x07, 0x00); //MIPI_CONTROL_3 + pr2100_write_register(ViPipe, 0x08, 0xc9); //MIPI_CONTROL_4 + pr2100_write_register(ViPipe, 0x1c, 0x09); //MIPI_T_LPX + pr2100_write_register(ViPipe, 0x1d, 0x08); //MIPI_T_CLK_PREPARE + pr2100_write_register(ViPipe, 0x1e, 0x09); //MIPI_T_HS_PREPARE + pr2100_write_register(ViPipe, 0x1f, 0x11); //MIPI_T_HS_ZERO + pr2100_write_register(ViPipe, 0x20, 0x0c); //MIPI_T_HS_TRAIL + pr2100_write_register(ViPipe, 0x21, 0x28); //MIPI_T_CLK_ZERO + pr2100_write_register(ViPipe, 0x22, 0x0b); //MIPI_T_CLK_TRAIL + pr2100_write_register(ViPipe, 0x23, 0x01); //MIPI_T_CLK_PRE + pr2100_write_register(ViPipe, 0x24, 0x12); //MIPI_T_CLK_POST + pr2100_write_register(ViPipe, 0x25, 0x82); //MIPI_T_WAKEUP + pr2100_write_register(ViPipe, 0x26, 0x11); //MIPI_T_HSEXIT + pr2100_write_register(ViPipe, 0x27, 0x11); //MIPI_T_CLK_HSEXIT + pr2100_write_register(ViPipe, 0x36, 0x0f); //MIPI_PKT_SIZE0_H + pr2100_write_register(ViPipe, 0x37, 0x00); //MIPI_PKT_SIZE0_L + pr2100_write_register(ViPipe, 0x38, 0x0f); //MIPI_PKT_SIZE1_H + pr2100_write_register(ViPipe, 0x39, 0x00); //MIPI_PKT_SIZE1_L + pr2100_write_register(ViPipe, 0x3a, 0x0f); //MIPI_PKT_SIZE2_H + pr2100_write_register(ViPipe, 0x3b, 0x00); //MIPI_PKT_SIZE2_L + pr2100_write_register(ViPipe, 0x3c, 0x0f); //MIPI_PKT_SIZE3_H + pr2100_write_register(ViPipe, 0x3d, 0x00); //MIPI_PKT_SIZE3_L + pr2100_write_register(ViPipe, 0x46, 0x1e); //MIPI_DATA_ID0 + pr2100_write_register(ViPipe, 0x47, 0x5e); //MIPI_DATA_ID1 + pr2100_write_register(ViPipe, 0x48, 0x9e); //MIPI_DATA_ID2 + pr2100_write_register(ViPipe, 0x49, 0xde); //MIPI_DATA_ID3 + pr2100_write_register(ViPipe, 0x04, 0x50); //MIPI_CONTROL_0 +} + +static void pr2100_set_1080p_4ch_slave(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "4CH Slave ViPipe=%d\n", ViPipe); + //chip id : 0x5d-(ch:0)Set vdec [Camera:3(HDA), videoResolution:11(video_1920x1080p25)] + + pr2100_write_register(ViPipe, 0xFF, 0x00); + pr2100_write_register(ViPipe, 0x10, 0x83); //MAN_IFMT0 + pr2100_write_register(ViPipe, 0x11, 0x0f); //MAN_EQ_DC_GN0 + pr2100_write_register(ViPipe, 0x12, 0x00); //MAN_EQ_AC_GN0 + pr2100_write_register(ViPipe, 0x13, 0x00); //VADC_EQ_BAND0 + pr2100_write_register(ViPipe, 0x14, 0x21); //VADC_CTRL0_0 + pr2100_write_register(ViPipe, 0x15, 0x44); //VADC_CTRL1_0 + pr2100_write_register(ViPipe, 0x16, 0x0d); //VADC_CTRL2_0 + pr2100_write_register(ViPipe, 0x30, 0x83); //MAN_IFMT1 + pr2100_write_register(ViPipe, 0x31, 0x0f); //MAN_EQ_DC_GN1 + pr2100_write_register(ViPipe, 0x32, 0x00); //MAN_EQ_AC_GN1 + pr2100_write_register(ViPipe, 0x33, 0x00); //VADC_EQ_BAND1 + pr2100_write_register(ViPipe, 0x34, 0x21); //VADC_CTRL0_1 + pr2100_write_register(ViPipe, 0x35, 0x44); //VADC_CTRL1_1 + pr2100_write_register(ViPipe, 0x36, 0x0d); //VADC_CTRL2_1 + pr2100_write_register(ViPipe, 0x80, 0x80); //IRQ_CTRL + pr2100_write_register(ViPipe, 0x81, 0x0e); //IRQ_SYNC_PERIOD + pr2100_write_register(ViPipe, 0x82, 0x0d); //WAKE0_PERIOD + pr2100_write_register(ViPipe, 0x84, 0xf0); //IRQ_NOVID_MD + pr2100_write_register(ViPipe, 0x8a, 0x00); //WAKE1_PERIOD + pr2100_write_register(ViPipe, 0x90, 0x00); //IRQENA_WAKE + pr2100_write_register(ViPipe, 0x91, 0x00); //IRQENA_GPIO + pr2100_write_register(ViPipe, 0x94, 0xff); //IRQCLR_WAKE + pr2100_write_register(ViPipe, 0x95, 0xff); //IRQCLR_GPIO + pr2100_write_register(ViPipe, 0xa0, 0x33); //IRQENA_VFD0 + pr2100_write_register(ViPipe, 0xb0, 0x33); //IRQENA_VFD1 + pr2100_write_register(ViPipe, 0xc0, 0x20); //MPP_CTRL0 + pr2100_write_register(ViPipe, 0xc1, 0x20); //MPP_CTRL1 + pr2100_write_register(ViPipe, 0xc2, 0x20); //MPP_CTRL2 + pr2100_write_register(ViPipe, 0xc3, 0x20); //MPP_CTRL3 + pr2100_write_register(ViPipe, 0xc4, 0x20); //MPP_CTRL4 + pr2100_write_register(ViPipe, 0xc5, 0x20); //MPP_CTRL5 + pr2100_write_register(ViPipe, 0xc6, 0x20); //MPP_CTRL6 + pr2100_write_register(ViPipe, 0xc7, 0x20); //MPP_CTRL7 + pr2100_write_register(ViPipe, 0xc8, 0x20); //MPP_CTRL8 + pr2100_write_register(ViPipe, 0xc9, 0x04); //MPP_CTRL9 + pr2100_write_register(ViPipe, 0xca, 0x04); //MPP_CTRLA + pr2100_write_register(ViPipe, 0xcb, 0x04); //MPP_CTRLB + pr2100_write_register(ViPipe, 0xd0, 0x06); //PLL0_CON0 + pr2100_write_register(ViPipe, 0xd1, 0x23); //PLL0_CON1 + pr2100_write_register(ViPipe, 0xd2, 0x21); //PLL0_CON2 + pr2100_write_register(ViPipe, 0xd3, 0x44); //PLL0_CON3 + pr2100_write_register(ViPipe, 0xd4, 0x06); //PLL1_CON0 + pr2100_write_register(ViPipe, 0xd5, 0x23); //PLL1_CON1 + pr2100_write_register(ViPipe, 0xd6, 0x21); //PLL1_CON2 + pr2100_write_register(ViPipe, 0xd7, 0x61); //PLL1_CON3 + pr2100_write_register(ViPipe, 0xd8, 0x86); //PLL2_CON0 + pr2100_write_register(ViPipe, 0xd9, 0x23); //PLL2_CON1 + pr2100_write_register(ViPipe, 0xda, 0x21); //PLL2_CON2 + pr2100_write_register(ViPipe, 0xe0, 0x05); //LATCH_EN_CON0 + pr2100_write_register(ViPipe, 0xe1, 0x05); //LATCH_EN_CON1 + pr2100_write_register(ViPipe, 0xe2, 0x14); //OUT_FMT + pr2100_write_register(ViPipe, 0xe3, 0xc4); //CHID_NUM, Y-Cb-Y-Cr + pr2100_write_register(ViPipe, 0xe4, 0x20); //CH_SEL0 + pr2100_write_register(ViPipe, 0xe5, 0x64); //CH_SEL1 + pr2100_write_register(ViPipe, 0xe6, 0x02); //CH_SEL2 + pr2100_write_register(ViPipe, 0xe7, 0x64); //CH_SEL3 + pr2100_write_register(ViPipe, 0xe8, 0x08); //VDCKP_PHASE + pr2100_write_register(ViPipe, 0xe9, 0x08); //VDCKN_PHASE + pr2100_write_register(ViPipe, 0xea, 0x10); //CLK_PWDN + pr2100_write_register(ViPipe, 0xeb, 0x00); //MIPI_DATA_EN + pr2100_write_register(ViPipe, 0xf0, 0x02); //PAR_OE_M + pr2100_write_register(ViPipe, 0xf1, 0x00); //PAR_OE_L + pr2100_write_register(ViPipe, 0xf3, 0x04); //PAD_MPP_CTL + pr2100_write_register(ViPipe, 0xf4, 0x44); //PAD_VD_CTL + + pr2100_write_register(ViPipe, 0xFF, 0x01); + pr2100_write_register(ViPipe, 0x00, 0xe4); //VID_CON0 + pr2100_write_register(ViPipe, 0x01, 0x61); //GAINFIT0 + pr2100_write_register(ViPipe, 0x02, 0x00); //PEDFIT0 + pr2100_write_register(ViPipe, 0x03, 0x56); //CLAMP_CON0 + pr2100_write_register(ViPipe, 0x04, 0x0c); //HPLL_CON0_0 + pr2100_write_register(ViPipe, 0x05, 0x88); //HPLL_CON1_0 + pr2100_write_register(ViPipe, 0x06, 0x04); //HPLL_CON2_0 + pr2100_write_register(ViPipe, 0x07, 0xb2); //HPLL_CON3_0 + pr2100_write_register(ViPipe, 0x08, 0x44); //HPLL_CON4_0 + pr2100_write_register(ViPipe, 0x09, 0x34); //HPLL_CON5_0 + pr2100_write_register(ViPipe, 0x0a, 0x02); //HPLL_CON6_0 + pr2100_write_register(ViPipe, 0x0b, 0x14); //STD_POS0_0 + pr2100_write_register(ViPipe, 0x0c, 0x04); //STD_POS1_0 + pr2100_write_register(ViPipe, 0x0d, 0x08); //STD_POS2_0 + pr2100_write_register(ViPipe, 0x0e, 0x5e); //STD_SLICE0_0 + pr2100_write_register(ViPipe, 0x0f, 0x5e); //STD_SLICE1_0 + pr2100_write_register(ViPipe, 0x10, 0x26); //STD_SLICE2_0 + pr2100_write_register(ViPipe, 0x11, 0x00); //HDELAY_MSB0 + pr2100_write_register(ViPipe, 0x12, 0x87); //HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0x13, 0x24); //HDELAY_LSB0 + pr2100_write_register(ViPipe, 0x14, 0x80); //HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x15, 0x2a); //VDELAY0 + pr2100_write_register(ViPipe, 0x16, 0x38); //VACTIVE0 + pr2100_write_register(ViPipe, 0x17, 0x00); //CBG_DELAY_MSB0 + pr2100_write_register(ViPipe, 0x18, 0x80); //CBG_ACTIVE_MSB0 + pr2100_write_register(ViPipe, 0x19, 0x48); //CBG_DELAY_LSB0 + pr2100_write_register(ViPipe, 0x1a, 0x6c); //CBG_ACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x1b, 0x05); //VSMASK_INV_STRT0 + pr2100_write_register(ViPipe, 0x1c, 0x61); //VSMASK_INV_END0 + pr2100_write_register(ViPipe, 0x1d, 0x07); //CBP_DELAY_MSB0 + pr2100_write_register(ViPipe, 0x1e, 0x7e); //CBP_DELAY_LSB0 + pr2100_write_register(ViPipe, 0x1f, 0x80); //HSCL_ACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x20, 0x80); //CONT0 + pr2100_write_register(ViPipe, 0x21, 0x80); //BRGT0 + pr2100_write_register(ViPipe, 0x22, 0x90); //SAT0 + pr2100_write_register(ViPipe, 0x23, 0x80); //HUE0 + pr2100_write_register(ViPipe, 0x24, 0x80); //CB_GAIN0 + pr2100_write_register(ViPipe, 0x25, 0x80); //CR_GAIN0 + pr2100_write_register(ViPipe, 0x26, 0x84); //CB_OFF0 + pr2100_write_register(ViPipe, 0x27, 0x82); //CR_OFF0 + pr2100_write_register(ViPipe, 0x28, 0x00); //Y_OUT_GAIN0 + pr2100_write_register(ViPipe, 0x29, 0xff); //DOWN_HSCL_MSB0 + pr2100_write_register(ViPipe, 0x2a, 0xff); //DOWN_HSCL_LSB0 + pr2100_write_register(ViPipe, 0x2b, 0x00); //MAN_HSCL_ADD0_0 + pr2100_write_register(ViPipe, 0x2c, 0x00); //MAN_HSCL_ADD1_0 + pr2100_write_register(ViPipe, 0x2d, 0x00); //MAN_HSCL_ADD2_0 + pr2100_write_register(ViPipe, 0x2e, 0x00); //MAN_OUTFMT_ADD0_0 + pr2100_write_register(ViPipe, 0x2f, 0x00); //MAN_OUTFMT_ADD1_0 + pr2100_write_register(ViPipe, 0x30, 0x00); //MAN_OUTFMT_ADD2_0 + pr2100_write_register(ViPipe, 0x31, 0x00); //MAN_COMB_MD0 + pr2100_write_register(ViPipe, 0x32, 0xc0); //COMB_CRL_MD0 + pr2100_write_register(ViPipe, 0x33, 0x14); //COMB_CVBS_CRL0_0 + pr2100_write_register(ViPipe, 0x34, 0x14); //COMB_CVBS_CRL1_0 + pr2100_write_register(ViPipe, 0x35, 0x80); //COMB_CVBS_CRL2_0 + pr2100_write_register(ViPipe, 0x36, 0x80); //COMB_CVBS_CRL3_0 + pr2100_write_register(ViPipe, 0x37, 0xad); //HD_Y_NOTCH_MD0 + pr2100_write_register(ViPipe, 0x38, 0x4b); //HD_COMB_FLT_MD0 + pr2100_write_register(ViPipe, 0x39, 0x08); //Y_DYN_PEAK_GN0 + pr2100_write_register(ViPipe, 0x3a, 0x21); //HD_Y_LPF_MD0 + pr2100_write_register(ViPipe, 0x3b, 0x02); //Y_HPF_CORE_MIN0 + pr2100_write_register(ViPipe, 0x3c, 0x01); //Y_HPF_CORE_STEP0 + pr2100_write_register(ViPipe, 0x3d, 0x23); //CORE_CON0 + pr2100_write_register(ViPipe, 0x3e, 0x05); //MAN_CLPF_MD0 + pr2100_write_register(ViPipe, 0x3f, 0xc8); //HD_CTI_CON0 + pr2100_write_register(ViPipe, 0x40, 0x05); //C_LOOP_CON0_0 + pr2100_write_register(ViPipe, 0x41, 0x55); //C_LOOP_CON1_0 + pr2100_write_register(ViPipe, 0x42, 0x01); //C_LOOP_CON2_0 + pr2100_write_register(ViPipe, 0x43, 0x38); //C_LOOP_CON3_0 + pr2100_write_register(ViPipe, 0x44, 0x6a); //C_HUE_CVI0_0 + pr2100_write_register(ViPipe, 0x45, 0x00); //C_HUE_CVI1_0 + pr2100_write_register(ViPipe, 0x46, 0x14); //C_PHASE_REF0_0 + pr2100_write_register(ViPipe, 0x47, 0xb0); //C_PHASE_REF1_0 + pr2100_write_register(ViPipe, 0x48, 0xdf); //C_PHASE_REF2_0 + pr2100_write_register(ViPipe, 0x49, 0x00); //G_GAIN_REF0_0 + pr2100_write_register(ViPipe, 0x4a, 0x7b); //G_GAIN_REF1_0 + pr2100_write_register(ViPipe, 0x4b, 0x60); //MAN_C_GAIN_VAL0_0 + pr2100_write_register(ViPipe, 0x4c, 0x00); //MAN_C_GAIN_VAL1_0 + pr2100_write_register(ViPipe, 0x4d, 0x26); //YC_DELAY0 + pr2100_write_register(ViPipe, 0x4e, 0x00); //HD_HALF_MD0 + pr2100_write_register(ViPipe, 0x4f, 0x2c); //OUTFMT_CON0 + pr2100_write_register(ViPipe, 0x50, 0x21); //TST_EQ_POS0_0 + pr2100_write_register(ViPipe, 0x51, 0x28); //TST_EQ_POS1_0 + pr2100_write_register(ViPipe, 0x52, 0x40); //TST_EQ_POS2_0 + pr2100_write_register(ViPipe, 0x53, 0x0c); //TST_VID_DEC0 + pr2100_write_register(ViPipe, 0x54, 0x0f); //TST_VID_RST0 + pr2100_write_register(ViPipe, 0x55, 0x8d); //PTZ_SLICE_LVL0 + pr2100_write_register(ViPipe, 0x70, 0x06); //COMB_VCRL_VTH1_0 + pr2100_write_register(ViPipe, 0x71, 0x08); //COMB_VCRL_VTH2_0 + pr2100_write_register(ViPipe, 0x72, 0x0a); //COMB_VCRL_VTH3_0 + pr2100_write_register(ViPipe, 0x73, 0x0c); //COMB_VCRL_VTH4_0 + pr2100_write_register(ViPipe, 0x74, 0x0e); //COMB_VCRL_VTH5_0 + pr2100_write_register(ViPipe, 0x75, 0x10); //COMB_VCRL_VTH6_0 + pr2100_write_register(ViPipe, 0x76, 0x12); //COMB_VCRL_VTH7_0 + pr2100_write_register(ViPipe, 0x77, 0x14); //COMB_VCRL_VTH8_0 + pr2100_write_register(ViPipe, 0x78, 0x06); //COMB_VMIX_VTH1_0 + pr2100_write_register(ViPipe, 0x79, 0x08); //COMB_VMIX_VTH2_0 + pr2100_write_register(ViPipe, 0x7a, 0x0a); //COMB_VMIX_VTH3_0 + pr2100_write_register(ViPipe, 0x7b, 0x0c); //COMB_VMIX_VTH4_0 + pr2100_write_register(ViPipe, 0x7c, 0x0e); //COMB_VMIX_VTH5_0 + pr2100_write_register(ViPipe, 0x7d, 0x10); //COMB_VMIX_VTH6_0 + pr2100_write_register(ViPipe, 0x7e, 0x12); //COMB_VMIX_VTH7_0 + pr2100_write_register(ViPipe, 0x7f, 0x14); //COMB_VMIX_VTH8_0 + pr2100_write_register(ViPipe, 0x80, 0x00); //STD_VPOS_PVI_960MSB0 + pr2100_write_register(ViPipe, 0x81, 0x09); //STD_VPOS_PVI_960LSB0 + pr2100_write_register(ViPipe, 0x82, 0x00); //STD_VPOS_CVI_960MSB0 + pr2100_write_register(ViPipe, 0x83, 0x07); //STD_VPOS_CVI_960LSB0 + pr2100_write_register(ViPipe, 0x84, 0x00); //STD_VPOS_AHD_960MSB0 + pr2100_write_register(ViPipe, 0x85, 0x17); //STD_VPOS_AHD_960LSB0 + pr2100_write_register(ViPipe, 0x86, 0x03); //STD_VPOS_TVI_960MSB0 + pr2100_write_register(ViPipe, 0x87, 0xe5); //STD_VPOS_TVI_960LSB0 + pr2100_write_register(ViPipe, 0x88, 0x05); //STD_HPOS_PVI_960MSB0 + pr2100_write_register(ViPipe, 0x89, 0x24); //STD_HPOS_PVI_960LSB0 + pr2100_write_register(ViPipe, 0x8a, 0x05); //STD_HPOS_CVI_960MSB0 + pr2100_write_register(ViPipe, 0x8b, 0x24); //STD_HPOS_CVI_960LSB0 + pr2100_write_register(ViPipe, 0x8c, 0x08); //STD_HPOS_AHD_960MSB0 + pr2100_write_register(ViPipe, 0x8d, 0xe8); //STD_HPOS_AHD_960LSB0 + pr2100_write_register(ViPipe, 0x8e, 0x05); //STD_HPOS_TVI_960MSB0 + pr2100_write_register(ViPipe, 0x8f, 0x47); //STD_HPOS_TVI_960LSB0 + pr2100_write_register(ViPipe, 0x90, 0x02); //VSYNC_ACCUM_960MSB0 + pr2100_write_register(ViPipe, 0x91, 0xb4); //VSYNC_ACCUM_960LSB0 + pr2100_write_register(ViPipe, 0x92, 0x73); //VLINE_MAX_960_MSB0 + pr2100_write_register(ViPipe, 0x93, 0xe8); //VLINE_MAX_960_LSB0 + pr2100_write_register(ViPipe, 0x94, 0x0f); //SLICE_VSYNC0 + pr2100_write_register(ViPipe, 0x95, 0x5e); //STD_SLICE_AHD0 + pr2100_write_register(ViPipe, 0x96, 0x03); //HACT_SIZE_960_MSB0 + pr2100_write_register(ViPipe, 0x97, 0xd0); //HACT_SIZE_960_LSB0 + pr2100_write_register(ViPipe, 0x98, 0x17); //HPERIOD_960P25MSB0 + pr2100_write_register(ViPipe, 0x99, 0x34); //HPERIOD_960P25LSB0 + pr2100_write_register(ViPipe, 0x9a, 0x13); //HPERIOD_960P30MSB0 + pr2100_write_register(ViPipe, 0x9b, 0x56); //HPERIOD_960P30LSB0 + pr2100_write_register(ViPipe, 0x9c, 0x0b); //HPERIOD_960P50MSB0 + pr2100_write_register(ViPipe, 0x9d, 0x9a); //HPERIOD_960P50LSB0 + pr2100_write_register(ViPipe, 0x9e, 0x09); //HPERIOD_960P60MSB0 + pr2100_write_register(ViPipe, 0x9f, 0xab); //HPERIOD_960P60LSB0 + pr2100_write_register(ViPipe, 0xa0, 0x01); //VALY_STRT_960P25MSB0 + pr2100_write_register(ViPipe, 0xa1, 0x74); //VALY_STRT_960P25LSB0 + pr2100_write_register(ViPipe, 0xa2, 0x01); //VALY_STRT_960P30MSB0 + pr2100_write_register(ViPipe, 0xa3, 0x6b); //VALY_STRT_960P30LSB0 + pr2100_write_register(ViPipe, 0xa4, 0x00); //VALY_STRT_960P50MSB0 + pr2100_write_register(ViPipe, 0xa5, 0xba); //VALY_STRT_960P50LSB0 + pr2100_write_register(ViPipe, 0xa6, 0x00); //VALY_STRT_960P60MSB0 + pr2100_write_register(ViPipe, 0xa7, 0xa3); //VALY_STRT_960P60LSB0 + pr2100_write_register(ViPipe, 0xa8, 0x01); //PED_STRT_960P25MSB0 + pr2100_write_register(ViPipe, 0xa9, 0x39); //PED_STRT_960P25LSB0 + pr2100_write_register(ViPipe, 0xaa, 0x01); //PED_STRT_960P30MSB0 + pr2100_write_register(ViPipe, 0xab, 0x39); //PED_STRT_960P30LSB0 + pr2100_write_register(ViPipe, 0xac, 0x00); //PED_STRT_960P50MSB0 + pr2100_write_register(ViPipe, 0xad, 0xc1); //PED_STRT_960P50LSB0 + pr2100_write_register(ViPipe, 0xae, 0x00); //PED_STRT_960P60MSB0 + pr2100_write_register(ViPipe, 0xaf, 0xc1); //PED_STRT_960P60LSB0 + pr2100_write_register(ViPipe, 0xb0, 0x05); //COMB_MEM_960PMSB0 + pr2100_write_register(ViPipe, 0xb1, 0xcc); //COMB_MEM_960PLSB0 + pr2100_write_register(ViPipe, 0xb2, 0x09); //C_JIT_GAIN_960PMSB0 + pr2100_write_register(ViPipe, 0xb3, 0x6d); //C_JIT_GAIN_960PLSB0 + pr2100_write_register(ViPipe, 0xb4, 0x00); //STD_VPOS_AHD_MSB0 + pr2100_write_register(ViPipe, 0xb5, 0x17); //STD_VPOS_AHD_LSB0 + pr2100_write_register(ViPipe, 0xb6, 0x08); //STD_HPOS_AHD_MSB0 + pr2100_write_register(ViPipe, 0xb7, 0xe8); //STD_HPOS_AHD_LSB0 + pr2100_write_register(ViPipe, 0xb8, 0xb0); //STD_TVI_OFFSET_25F0 + pr2100_write_register(ViPipe, 0xb9, 0xce); //STD_TVI_OFFSET_30F0 + pr2100_write_register(ViPipe, 0xba, 0x90); //STD_TVI_OFFSET_960P0 + pr2100_write_register(ViPipe, 0xbb, 0x00); //EXT_SYNC_CON0 + pr2100_write_register(ViPipe, 0xbc, 0x00); //VOSYNC_HDELAY_MSB0 + pr2100_write_register(ViPipe, 0xbd, 0x04); //VOSYNC_HDELAY_LSB0 + pr2100_write_register(ViPipe, 0xbe, 0x07); //VOSYNC_HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xbf, 0x80); //VOSYNC_HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xc0, 0x00); //VOSYNC_VDELAY_MSB0 + pr2100_write_register(ViPipe, 0xc1, 0x20); //VOSYNC_VDELAY_LSB0 + #if PR2100_SLAVE_TEST_PATTERN + pr2100_write_register(ViPipe, 0xc2, 0x44); + pr2100_write_register(ViPipe, 0xc3, 0x38); + pr2100_write_register(ViPipe, 0xc4, 0x88); + #else + pr2100_write_register(ViPipe, 0xc2, 0x04); //VOSYNC_VACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xc3, 0x38); //VOSYNC_VACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xc4, 0x00); + #endif + pr2100_write_register(ViPipe, 0xc5, 0x00); //MAN_INFMT_ADD_LSB0 + pr2100_write_register(ViPipe, 0xc6, 0x00); //C_PHASE_LOCK_RNG0_0 + pr2100_write_register(ViPipe, 0xc7, 0x00); //C_PHASE_LOCK_RNG1_0 + pr2100_write_register(ViPipe, 0xc8, 0x00); //C_PHASE_LOCK_RNG2_0 + pr2100_write_register(ViPipe, 0xc9, 0x00); //VISYNC_HDELAY_MSB0 + pr2100_write_register(ViPipe, 0xca, 0x04); //VISYNC_HDELAY_LSB0 + pr2100_write_register(ViPipe, 0xcb, 0x07); //VISYNC_HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xcc, 0x80); //VISYNC_HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xcd, 0x08); //VISYNC_VDELAY_MSB0 + pr2100_write_register(ViPipe, 0xce, 0x20); //VISYNC_VDELAY_LSB0 + pr2100_write_register(ViPipe, 0xcf, 0x04); //VISYNC_VACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xd0, 0x38); //VISYNC_VACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xd1, 0x10); //MIPI_DATA_FLD_CON_0 + + pr2100_write_register(ViPipe, 0xFF, 0x02); + pr2100_write_register(ViPipe, 0x00, 0xe4); //VID_CON1 + pr2100_write_register(ViPipe, 0x01, 0x61); //GAINFIT1 + pr2100_write_register(ViPipe, 0x02, 0x00); //PEDFIT1 + pr2100_write_register(ViPipe, 0x03, 0x56); //CLAMP_CON1 + pr2100_write_register(ViPipe, 0x04, 0x0c); //HPLL_CON0_1 + pr2100_write_register(ViPipe, 0x05, 0x88); //HPLL_CON1_1 + pr2100_write_register(ViPipe, 0x06, 0x04); //HPLL_CON2_1 + pr2100_write_register(ViPipe, 0x07, 0xb2); //HPLL_CON3_1 + pr2100_write_register(ViPipe, 0x08, 0x44); //HPLL_CON4_1 + pr2100_write_register(ViPipe, 0x09, 0x34); //HPLL_CON5_1 + pr2100_write_register(ViPipe, 0x0a, 0x02); //HPLL_CON6_1 + pr2100_write_register(ViPipe, 0x0b, 0x14); //STD_POS0_1 + pr2100_write_register(ViPipe, 0x0c, 0x04); //STD_POS1_1 + pr2100_write_register(ViPipe, 0x0d, 0x08); //STD_POS2_1 + pr2100_write_register(ViPipe, 0x0e, 0x5e); //STD_SLICE0_1 + pr2100_write_register(ViPipe, 0x0f, 0x5e); //STD_SLICE1_1 + pr2100_write_register(ViPipe, 0x10, 0x26); //STD_SLICE2_1 + pr2100_write_register(ViPipe, 0x11, 0x00); //HDELAY_MSB1 + pr2100_write_register(ViPipe, 0x12, 0x87); //HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0x13, 0x24); //HDELAY_LSB1 + pr2100_write_register(ViPipe, 0x14, 0x80); //HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x15, 0x2a); //VDELAY1 + pr2100_write_register(ViPipe, 0x16, 0x38); //VACTIVE1 + pr2100_write_register(ViPipe, 0x17, 0x00); //CBG_DELAY_MSB1 + pr2100_write_register(ViPipe, 0x18, 0x80); //CBG_ACTIVE_MSB1 + pr2100_write_register(ViPipe, 0x19, 0x48); //CBG_DELAY_LSB1 + pr2100_write_register(ViPipe, 0x1a, 0x6c); //CBG_ACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x1b, 0x05); //VSMASK_INV_STRT1 + pr2100_write_register(ViPipe, 0x1c, 0x61); //VSMASK_INV_END1 + pr2100_write_register(ViPipe, 0x1d, 0x07); //CBP_DELAY_MSB1 + pr2100_write_register(ViPipe, 0x1e, 0x7e); //CBP_DELAY_LSB1 + pr2100_write_register(ViPipe, 0x1f, 0x80); //HSCL_ACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x20, 0x80); //CONT1 + pr2100_write_register(ViPipe, 0x21, 0x80); //BRGT1 + pr2100_write_register(ViPipe, 0x22, 0x90); //SAT1 + pr2100_write_register(ViPipe, 0x23, 0x80); //HUE1 + pr2100_write_register(ViPipe, 0x24, 0x80); //CB_GAIN1 + pr2100_write_register(ViPipe, 0x25, 0x80); //CR_GAIN1 + pr2100_write_register(ViPipe, 0x26, 0x84); //CB_OFF1 + pr2100_write_register(ViPipe, 0x27, 0x82); //CR_OFF1 + pr2100_write_register(ViPipe, 0x28, 0x00); //Y_OUT_GAIN1 + pr2100_write_register(ViPipe, 0x29, 0xff); //DOWN_HSCL_MSB1 + pr2100_write_register(ViPipe, 0x2a, 0xff); //DOWN_HSCL_LSB1 + pr2100_write_register(ViPipe, 0x2b, 0x00); //MAN_HSCL_ADD0_1 + pr2100_write_register(ViPipe, 0x2c, 0x00); //MAN_HSCL_ADD1_1 + pr2100_write_register(ViPipe, 0x2d, 0x00); //MAN_HSCL_ADD2_1 + pr2100_write_register(ViPipe, 0x2e, 0x00); //MAN_OUTFMT_ADD0_1 + pr2100_write_register(ViPipe, 0x2f, 0x00); //MAN_OUTFMT_ADD1_1 + pr2100_write_register(ViPipe, 0x30, 0x00); //MAN_OUTFMT_ADD2_1 + pr2100_write_register(ViPipe, 0x31, 0x00); //MAN_COMB_MD1 + pr2100_write_register(ViPipe, 0x32, 0xc0); //COMB_CRL_MD1 + pr2100_write_register(ViPipe, 0x33, 0x14); //COMB_CVBS_CRL0_1 + pr2100_write_register(ViPipe, 0x34, 0x14); //COMB_CVBS_CRL1_1 + pr2100_write_register(ViPipe, 0x35, 0x80); //COMB_CVBS_CRL2_1 + pr2100_write_register(ViPipe, 0x36, 0x80); //COMB_CVBS_CRL3_1 + pr2100_write_register(ViPipe, 0x37, 0xad); //HD_Y_NOTCH_MD1 + pr2100_write_register(ViPipe, 0x38, 0x4b); //HD_COMB_FLT_MD1 + pr2100_write_register(ViPipe, 0x39, 0x08); //Y_DYN_PEAK_GN1 + pr2100_write_register(ViPipe, 0x3a, 0x21); //HD_Y_LPF_MD1 + pr2100_write_register(ViPipe, 0x3b, 0x02); //Y_HPF_CORE_MIN1 + pr2100_write_register(ViPipe, 0x3c, 0x01); //Y_HPF_CORE_STEP1 + pr2100_write_register(ViPipe, 0x3d, 0x23); //CORE_CON1 + pr2100_write_register(ViPipe, 0x3e, 0x05); //MAN_CLPF_MD1 + pr2100_write_register(ViPipe, 0x3f, 0xc8); //HD_CTI_CON1 + pr2100_write_register(ViPipe, 0x40, 0x05); //C_LOOP_CON0_1 + pr2100_write_register(ViPipe, 0x41, 0x55); //C_LOOP_CON1_1 + pr2100_write_register(ViPipe, 0x42, 0x01); //C_LOOP_CON2_1 + pr2100_write_register(ViPipe, 0x43, 0x38); //C_LOOP_CON3_1 + pr2100_write_register(ViPipe, 0x44, 0x6a); //C_HUE_CVI0_1 + pr2100_write_register(ViPipe, 0x45, 0x00); //C_HUE_CVI1_1 + pr2100_write_register(ViPipe, 0x46, 0x14); //C_PHASE_REF0_1 + pr2100_write_register(ViPipe, 0x47, 0xb0); //C_PHASE_REF1_1 + pr2100_write_register(ViPipe, 0x48, 0xdf); //C_PHASE_REF2_1 + pr2100_write_register(ViPipe, 0x49, 0x00); //G_GAIN_REF0_1 + pr2100_write_register(ViPipe, 0x4a, 0x7b); //G_GAIN_REF1_1 + pr2100_write_register(ViPipe, 0x4b, 0x60); //MAN_C_GAIN_VAL0_1 + pr2100_write_register(ViPipe, 0x4c, 0x00); //MAN_C_GAIN_VAL1_1 + pr2100_write_register(ViPipe, 0x4d, 0x26); //YC_DELAY1 + pr2100_write_register(ViPipe, 0x4e, 0x00); //HD_HALF_MD1 + pr2100_write_register(ViPipe, 0x4f, 0x2c); //OUTFMT_CON1 + pr2100_write_register(ViPipe, 0x50, 0x21); //TST_EQ_POS0_1 + pr2100_write_register(ViPipe, 0x51, 0x28); //TST_EQ_POS1_1 + pr2100_write_register(ViPipe, 0x52, 0x40); //TST_EQ_POS2_1 + pr2100_write_register(ViPipe, 0x53, 0x0c); //TST_VID_DEC1 + pr2100_write_register(ViPipe, 0x54, 0x0f); //TST_VID_RST1 + pr2100_write_register(ViPipe, 0x55, 0x8d); //PTZ_SLICE_LVL1 + pr2100_write_register(ViPipe, 0x70, 0x06); //COMB_VCRL_VTH1_1 + pr2100_write_register(ViPipe, 0x71, 0x08); //COMB_VCRL_VTH2_1 + pr2100_write_register(ViPipe, 0x72, 0x0a); //COMB_VCRL_VTH3_1 + pr2100_write_register(ViPipe, 0x73, 0x0c); //COMB_VCRL_VTH4_1 + pr2100_write_register(ViPipe, 0x74, 0x0e); //COMB_VCRL_VTH5_1 + pr2100_write_register(ViPipe, 0x75, 0x10); //COMB_VCRL_VTH6_1 + pr2100_write_register(ViPipe, 0x76, 0x12); //COMB_VCRL_VTH7_1 + pr2100_write_register(ViPipe, 0x77, 0x14); //COMB_VCRL_VTH8_1 + pr2100_write_register(ViPipe, 0x78, 0x06); //COMB_VMIX_VTH1_1 + pr2100_write_register(ViPipe, 0x79, 0x08); //COMB_VMIX_VTH2_1 + pr2100_write_register(ViPipe, 0x7a, 0x0a); //COMB_VMIX_VTH3_1 + pr2100_write_register(ViPipe, 0x7b, 0x0c); //COMB_VMIX_VTH4_1 + pr2100_write_register(ViPipe, 0x7c, 0x0e); //COMB_VMIX_VTH5_1 + pr2100_write_register(ViPipe, 0x7d, 0x10); //COMB_VMIX_VTH6_1 + pr2100_write_register(ViPipe, 0x7e, 0x12); //COMB_VMIX_VTH7_1 + pr2100_write_register(ViPipe, 0x7f, 0x14); //COMB_VMIX_VTH8_1 + pr2100_write_register(ViPipe, 0x80, 0x00); //STD_VPOS_PVI_960MSB1 + pr2100_write_register(ViPipe, 0x81, 0x09); //STD_VPOS_PVI_960LSB1 + pr2100_write_register(ViPipe, 0x82, 0x00); //STD_VPOS_CVI_960MSB1 + pr2100_write_register(ViPipe, 0x83, 0x07); //STD_VPOS_CVI_960LSB1 + pr2100_write_register(ViPipe, 0x84, 0x00); //STD_VPOS_AHD_960MSB1 + pr2100_write_register(ViPipe, 0x85, 0x17); //STD_VPOS_AHD_960LSB1 + pr2100_write_register(ViPipe, 0x86, 0x03); //STD_VPOS_TVI_960MSB1 + pr2100_write_register(ViPipe, 0x87, 0xe5); //STD_VPOS_TVI_960LSB1 + pr2100_write_register(ViPipe, 0x88, 0x05); //STD_HPOS_PVI_960MSB1 + pr2100_write_register(ViPipe, 0x89, 0x24); //STD_HPOS_PVI_960LSB1 + pr2100_write_register(ViPipe, 0x8a, 0x05); //STD_HPOS_CVI_960MSB1 + pr2100_write_register(ViPipe, 0x8b, 0x24); //STD_HPOS_CVI_960LSB1 + pr2100_write_register(ViPipe, 0x8c, 0x08); //STD_HPOS_AHD_960MSB1 + pr2100_write_register(ViPipe, 0x8d, 0xe8); //STD_HPOS_AHD_960LSB1 + pr2100_write_register(ViPipe, 0x8e, 0x05); //STD_HPOS_TVI_960MSB1 + pr2100_write_register(ViPipe, 0x8f, 0x47); //STD_HPOS_TVI_960LSB1 + pr2100_write_register(ViPipe, 0x90, 0x02); //VSYNC_ACCUM_960MSB1 + pr2100_write_register(ViPipe, 0x91, 0xb4); //VSYNC_ACCUM_960LSB1 + pr2100_write_register(ViPipe, 0x92, 0x73); //VLINE_MAX_960_MSB1 + pr2100_write_register(ViPipe, 0x93, 0xe8); //VLINE_MAX_960_LSB1 + pr2100_write_register(ViPipe, 0x94, 0x0f); //SLICE_VSYNC1 + pr2100_write_register(ViPipe, 0x95, 0x5e); //STD_SLICE_AHD1 + pr2100_write_register(ViPipe, 0x96, 0x03); //HACT_SIZE_960_MSB1 + pr2100_write_register(ViPipe, 0x97, 0xd0); //HACT_SIZE_960_LSB1 + pr2100_write_register(ViPipe, 0x98, 0x17); //HPERIOD_960P25MSB1 + pr2100_write_register(ViPipe, 0x99, 0x34); //HPERIOD_960P25LSB1 + pr2100_write_register(ViPipe, 0x9a, 0x13); //HPERIOD_960P30MSB1 + pr2100_write_register(ViPipe, 0x9b, 0x56); //HPERIOD_960P30LSB1 + pr2100_write_register(ViPipe, 0x9c, 0x0b); //HPERIOD_960P50MSB1 + pr2100_write_register(ViPipe, 0x9d, 0x9a); //HPERIOD_960P50LSB1 + pr2100_write_register(ViPipe, 0x9e, 0x09); //HPERIOD_960P60MSB1 + pr2100_write_register(ViPipe, 0x9f, 0xab); //HPERIOD_960P60LSB1 + pr2100_write_register(ViPipe, 0xa0, 0x01); //VALY_STRT_960P25MSB1 + pr2100_write_register(ViPipe, 0xa1, 0x74); //VALY_STRT_960P25LSB1 + pr2100_write_register(ViPipe, 0xa2, 0x01); //VALY_STRT_960P30MSB1 + pr2100_write_register(ViPipe, 0xa3, 0x6b); //VALY_STRT_960P30LSB1 + pr2100_write_register(ViPipe, 0xa4, 0x00); //VALY_STRT_960P50MSB1 + pr2100_write_register(ViPipe, 0xa5, 0xba); //VALY_STRT_960P50LSB1 + pr2100_write_register(ViPipe, 0xa6, 0x00); //VALY_STRT_960P60MSB1 + pr2100_write_register(ViPipe, 0xa7, 0xa3); //VALY_STRT_960P60LSB1 + pr2100_write_register(ViPipe, 0xa8, 0x01); //PED_STRT_960P25MSB1 + pr2100_write_register(ViPipe, 0xa9, 0x39); //PED_STRT_960P25LSB1 + pr2100_write_register(ViPipe, 0xaa, 0x01); //PED_STRT_960P30MSB1 + pr2100_write_register(ViPipe, 0xab, 0x39); //PED_STRT_960P30LSB1 + pr2100_write_register(ViPipe, 0xac, 0x00); //PED_STRT_960P50MSB1 + pr2100_write_register(ViPipe, 0xad, 0xc1); //PED_STRT_960P50LSB1 + pr2100_write_register(ViPipe, 0xae, 0x00); //PED_STRT_960P60MSB1 + pr2100_write_register(ViPipe, 0xaf, 0xc1); //PED_STRT_960P60LSB1 + pr2100_write_register(ViPipe, 0xb0, 0x05); //COMB_MEM_960PMSB1 + pr2100_write_register(ViPipe, 0xb1, 0xcc); //COMB_MEM_960PLSB1 + pr2100_write_register(ViPipe, 0xb2, 0x09); //C_JIT_GAIN_960PMSB1 + pr2100_write_register(ViPipe, 0xb3, 0x6d); //C_JIT_GAIN_960PLSB1 + pr2100_write_register(ViPipe, 0xb4, 0x00); //STD_VPOS_AHD_MSB1 + pr2100_write_register(ViPipe, 0xb5, 0x17); //STD_VPOS_AHD_LSB1 + pr2100_write_register(ViPipe, 0xb6, 0x08); //STD_HPOS_AHD_MSB1 + pr2100_write_register(ViPipe, 0xb7, 0xe8); //STD_HPOS_AHD_LSB1 + pr2100_write_register(ViPipe, 0xb8, 0xb0); //STD_TVI_OFFSET_25F1 + pr2100_write_register(ViPipe, 0xb9, 0xce); //STD_TVI_OFFSET_30F1 + pr2100_write_register(ViPipe, 0xba, 0x90); //STD_TVI_OFFSET_960P1 + pr2100_write_register(ViPipe, 0xbb, 0x00); //EXT_SYNC_CON1 + pr2100_write_register(ViPipe, 0xbc, 0x00); //VOSYNC_HDELAY_MSB1 + pr2100_write_register(ViPipe, 0xbd, 0x04); //VOSYNC_HDELAY_LSB1 + pr2100_write_register(ViPipe, 0xbe, 0x07); //VOSYNC_HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xbf, 0x80); //VOSYNC_HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xc0, 0x00); //VOSYNC_VDELAY_MSB1 + pr2100_write_register(ViPipe, 0xc1, 0x20); //VOSYNC_VDELAY_LSB1 + #if PR2100_SLAVE_TEST_PATTERN + pr2100_write_register(ViPipe, 0xc2, 0x44); + pr2100_write_register(ViPipe, 0xc3, 0x38); + pr2100_write_register(ViPipe, 0xc4, 0x88); + #else + pr2100_write_register(ViPipe, 0xc2, 0x04); //VOSYNC_VACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xc3, 0x38); //VOSYNC_VACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xc4, 0x00); + #endif + pr2100_write_register(ViPipe, 0xc5, 0x00); //MAN_INFMT_ADD_LSB1 + pr2100_write_register(ViPipe, 0xc6, 0x00); //C_PHASE_LOCK_RNG0_1 + pr2100_write_register(ViPipe, 0xc7, 0x00); //C_PHASE_LOCK_RNG1_1 + pr2100_write_register(ViPipe, 0xc8, 0x00); //C_PHASE_LOCK_RNG2_1 + pr2100_write_register(ViPipe, 0xc9, 0x00); //VISYNC_HDELAY_MSB1 + pr2100_write_register(ViPipe, 0xca, 0x04); //VISYNC_HDELAY_LSB1 + pr2100_write_register(ViPipe, 0xcb, 0x07); //VISYNC_HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xcc, 0x80); //VISYNC_HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xcd, 0x08); //VISYNC_VDELAY_MSB1 + pr2100_write_register(ViPipe, 0xce, 0x20); //VISYNC_VDELAY_LSB1 + pr2100_write_register(ViPipe, 0xcf, 0x04); //VISYNC_VACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xd0, 0x38); //VISYNC_VACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xd1, 0x10); //MIPI_DATA_FLD_CON_1 + + pr2100_write_register(ViPipe, 0xFF, 0x06); + pr2100_write_register(ViPipe, 0x04, 0x30); //MIPI_CONTROL_0 +} + +static void pr2100_set_1080p_4ch(VI_PIPE ViPipe) +{ + CVI_TRACE_SNS(CVI_DBG_INFO, "4CH Master ViPipe=%d\n", ViPipe); + + //chip id : 0x5c-(ch:0)Set vdec [Camera:3(HDA), videoResolution:11(video_1920x1080p25)] + pr2100_write_register(ViPipe, 0xFF, 0x00); + pr2100_write_register(ViPipe, 0x10, 0x83); //MAN_IFMT0 + pr2100_write_register(ViPipe, 0x11, 0x0f); //MAN_EQ_DC_GN0 + pr2100_write_register(ViPipe, 0x12, 0x00); //MAN_EQ_AC_GN0 + pr2100_write_register(ViPipe, 0x13, 0x00); //VADC_EQ_BAND0 + pr2100_write_register(ViPipe, 0x14, 0x21); //VADC_CTRL0_0 + pr2100_write_register(ViPipe, 0x15, 0x44); //VADC_CTRL1_0 + pr2100_write_register(ViPipe, 0x16, 0x0d); //VADC_CTRL2_0 + pr2100_write_register(ViPipe, 0x30, 0x83); //MAN_IFMT1 + pr2100_write_register(ViPipe, 0x31, 0x0f); //MAN_EQ_DC_GN1 + pr2100_write_register(ViPipe, 0x32, 0x00); //MAN_EQ_AC_GN1 + pr2100_write_register(ViPipe, 0x33, 0x00); //VADC_EQ_BAND1 + pr2100_write_register(ViPipe, 0x34, 0x21); //VADC_CTRL0_1 + pr2100_write_register(ViPipe, 0x35, 0x44); //VADC_CTRL1_1 + pr2100_write_register(ViPipe, 0x36, 0x0d); //VADC_CTRL2_1 + pr2100_write_register(ViPipe, 0x80, 0x80); //IRQ_CTRL + pr2100_write_register(ViPipe, 0x81, 0x0e); //IRQ_SYNC_PERIOD + pr2100_write_register(ViPipe, 0x82, 0x0d); //WAKE0_PERIOD + pr2100_write_register(ViPipe, 0x84, 0xf0); //IRQ_NOVID_MD + pr2100_write_register(ViPipe, 0x8a, 0x00); //WAKE1_PERIOD + pr2100_write_register(ViPipe, 0x90, 0x00); //IRQENA_WAKE + pr2100_write_register(ViPipe, 0x91, 0x00); //IRQENA_GPIO + pr2100_write_register(ViPipe, 0x94, 0xff); //IRQCLR_WAKE + pr2100_write_register(ViPipe, 0x95, 0xff); //IRQCLR_GPIO + pr2100_write_register(ViPipe, 0xa0, 0x33); //IRQENA_VFD0 + pr2100_write_register(ViPipe, 0xb0, 0x33); //IRQENA_VFD1 + pr2100_write_register(ViPipe, 0xc0, 0x21); //MPP_CTRL0 + pr2100_write_register(ViPipe, 0xc1, 0x21); //MPP_CTRL1 + pr2100_write_register(ViPipe, 0xc2, 0x21); //MPP_CTRL2 + pr2100_write_register(ViPipe, 0xc3, 0x21); //MPP_CTRL3 + pr2100_write_register(ViPipe, 0xc4, 0x21); //MPP_CTRL4 + pr2100_write_register(ViPipe, 0xc5, 0x21); //MPP_CTRL5 + pr2100_write_register(ViPipe, 0xc6, 0x21); //MPP_CTRL6 + pr2100_write_register(ViPipe, 0xc7, 0x21); //MPP_CTRL7 + pr2100_write_register(ViPipe, 0xc8, 0x21); //MPP_CTRL8 + pr2100_write_register(ViPipe, 0xc9, 0x01); //MPP_CTRL9 + pr2100_write_register(ViPipe, 0xca, 0x01); //MPP_CTRLA + pr2100_write_register(ViPipe, 0xcb, 0x01); //MPP_CTRLB + pr2100_write_register(ViPipe, 0xd0, 0x06); //PLL0_CON0 + pr2100_write_register(ViPipe, 0xd1, 0x23); //PLL0_CON1 + pr2100_write_register(ViPipe, 0xd2, 0x21); //PLL0_CON2 + pr2100_write_register(ViPipe, 0xd3, 0x44); //PLL0_CON3 + pr2100_write_register(ViPipe, 0xd4, 0x06); //PLL1_CON0 + pr2100_write_register(ViPipe, 0xd5, 0x23); //PLL1_CON1 + pr2100_write_register(ViPipe, 0xd6, 0x21); //PLL1_CON2 + pr2100_write_register(ViPipe, 0xd7, 0x44); //PLL1_CON3 + pr2100_write_register(ViPipe, 0xd8, 0x06); //PLL2_CON0 + pr2100_write_register(ViPipe, 0xd9, 0x22); //PLL2_CON1 + pr2100_write_register(ViPipe, 0xda, 0x2c); //PLL2_CON2 + pr2100_write_register(ViPipe, 0xe0, 0x05); //LATCH_EN_CON0 + pr2100_write_register(ViPipe, 0xe1, 0x05); //LATCH_EN_CON1 + pr2100_write_register(ViPipe, 0xe2, 0x00); //OUT_FMT + pr2100_write_register(ViPipe, 0xe3, 0xc4); //CHID_NUM, Y-Cb-Y-Cr + pr2100_write_register(ViPipe, 0xe4, 0x20); //CH_SEL0 + pr2100_write_register(ViPipe, 0xe5, 0x64); //CH_SEL1 + pr2100_write_register(ViPipe, 0xe6, 0x20); //CH_SEL2 + pr2100_write_register(ViPipe, 0xe7, 0x64); //CH_SEL3 + pr2100_write_register(ViPipe, 0xe8, 0x00); //VDCKP_PHASE + pr2100_write_register(ViPipe, 0xe9, 0x00); //VDCKN_PHASE + pr2100_write_register(ViPipe, 0xea, 0x00); //CLK_PWDN + pr2100_write_register(ViPipe, 0xeb, 0x01); //MIPI_DATA_EN + pr2100_write_register(ViPipe, 0xf0, 0x03); //PAR_OE_M + pr2100_write_register(ViPipe, 0xf1, 0xff); //PAR_OE_L + pr2100_write_register(ViPipe, 0xf3, 0x06); //PAD_MPP_CTL + pr2100_write_register(ViPipe, 0xf4, 0x66); //PAD_VD_CTL + + pr2100_write_register(ViPipe, 0xFF, 0x01); + pr2100_write_register(ViPipe, 0x00, 0xe4); //VID_CON0 + pr2100_write_register(ViPipe, 0x01, 0x61); //GAINFIT0 + pr2100_write_register(ViPipe, 0x02, 0x00); //PEDFIT0 + pr2100_write_register(ViPipe, 0x03, 0x56); //CLAMP_CON0 + pr2100_write_register(ViPipe, 0x04, 0x0c); //HPLL_CON0_0 + pr2100_write_register(ViPipe, 0x05, 0x88); //HPLL_CON1_0 + pr2100_write_register(ViPipe, 0x06, 0x04); //HPLL_CON2_0 + pr2100_write_register(ViPipe, 0x07, 0xb2); //HPLL_CON3_0 + pr2100_write_register(ViPipe, 0x08, 0x44); //HPLL_CON4_0 + pr2100_write_register(ViPipe, 0x09, 0x34); //HPLL_CON5_0 + pr2100_write_register(ViPipe, 0x0a, 0x02); //HPLL_CON6_0 + pr2100_write_register(ViPipe, 0x0b, 0x14); //STD_POS0_0 + pr2100_write_register(ViPipe, 0x0c, 0x04); //STD_POS1_0 + pr2100_write_register(ViPipe, 0x0d, 0x08); //STD_POS2_0 + pr2100_write_register(ViPipe, 0x0e, 0x5e); //STD_SLICE0_0 + pr2100_write_register(ViPipe, 0x0f, 0x5e); //STD_SLICE1_0 + pr2100_write_register(ViPipe, 0x10, 0x26); //STD_SLICE2_0 + pr2100_write_register(ViPipe, 0x11, 0x00); //HDELAY_MSB0 + pr2100_write_register(ViPipe, 0x12, 0x87); //HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0x13, 0x24); //HDELAY_LSB0 + pr2100_write_register(ViPipe, 0x14, 0x80); //HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x15, 0x2a); //VDELAY0 + pr2100_write_register(ViPipe, 0x16, 0x38); //VACTIVE0 + pr2100_write_register(ViPipe, 0x17, 0x00); //CBG_DELAY_MSB0 + pr2100_write_register(ViPipe, 0x18, 0x80); //CBG_ACTIVE_MSB0 + pr2100_write_register(ViPipe, 0x19, 0x48); //CBG_DELAY_LSB0 + pr2100_write_register(ViPipe, 0x1a, 0x6c); //CBG_ACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x1b, 0x05); //VSMASK_INV_STRT0 + pr2100_write_register(ViPipe, 0x1c, 0x61); //VSMASK_INV_END0 + pr2100_write_register(ViPipe, 0x1d, 0x07); //CBP_DELAY_MSB0 + pr2100_write_register(ViPipe, 0x1e, 0x7e); //CBP_DELAY_LSB0 + pr2100_write_register(ViPipe, 0x1f, 0x80); //HSCL_ACTIVE_LSB0 + pr2100_write_register(ViPipe, 0x20, 0x80); //CONT0 + pr2100_write_register(ViPipe, 0x21, 0x80); //BRGT0 + pr2100_write_register(ViPipe, 0x22, 0x90); //SAT0 + pr2100_write_register(ViPipe, 0x23, 0x80); //HUE0 + pr2100_write_register(ViPipe, 0x24, 0x80); //CB_GAIN0 + pr2100_write_register(ViPipe, 0x25, 0x80); //CR_GAIN0 + pr2100_write_register(ViPipe, 0x26, 0x84); //CB_OFF0 + pr2100_write_register(ViPipe, 0x27, 0x82); //CR_OFF0 + pr2100_write_register(ViPipe, 0x28, 0x00); //Y_OUT_GAIN0 + pr2100_write_register(ViPipe, 0x29, 0xff); //DOWN_HSCL_MSB0 + pr2100_write_register(ViPipe, 0x2a, 0xff); //DOWN_HSCL_LSB0 + pr2100_write_register(ViPipe, 0x2b, 0x00); //MAN_HSCL_ADD0_0 + pr2100_write_register(ViPipe, 0x2c, 0x00); //MAN_HSCL_ADD1_0 + pr2100_write_register(ViPipe, 0x2d, 0x00); //MAN_HSCL_ADD2_0 + pr2100_write_register(ViPipe, 0x2e, 0x00); //MAN_OUTFMT_ADD0_0 + pr2100_write_register(ViPipe, 0x2f, 0x00); //MAN_OUTFMT_ADD1_0 + pr2100_write_register(ViPipe, 0x30, 0x00); //MAN_OUTFMT_ADD2_0 + pr2100_write_register(ViPipe, 0x31, 0x00); //MAN_COMB_MD0 + pr2100_write_register(ViPipe, 0x32, 0xc0); //COMB_CRL_MD0 + pr2100_write_register(ViPipe, 0x33, 0x14); //COMB_CVBS_CRL0_0 + pr2100_write_register(ViPipe, 0x34, 0x14); //COMB_CVBS_CRL1_0 + pr2100_write_register(ViPipe, 0x35, 0x80); //COMB_CVBS_CRL2_0 + pr2100_write_register(ViPipe, 0x36, 0x80); //COMB_CVBS_CRL3_0 + pr2100_write_register(ViPipe, 0x37, 0xad); //HD_Y_NOTCH_MD0 + pr2100_write_register(ViPipe, 0x38, 0x4b); //HD_COMB_FLT_MD0 + pr2100_write_register(ViPipe, 0x39, 0x08); //Y_DYN_PEAK_GN0 + pr2100_write_register(ViPipe, 0x3a, 0x21); //HD_Y_LPF_MD0 + pr2100_write_register(ViPipe, 0x3b, 0x02); //Y_HPF_CORE_MIN0 + pr2100_write_register(ViPipe, 0x3c, 0x01); //Y_HPF_CORE_STEP0 + pr2100_write_register(ViPipe, 0x3d, 0x23); //CORE_CON0 + pr2100_write_register(ViPipe, 0x3e, 0x05); //MAN_CLPF_MD0 + pr2100_write_register(ViPipe, 0x3f, 0xc8); //HD_CTI_CON0 + pr2100_write_register(ViPipe, 0x40, 0x05); //C_LOOP_CON0_0 + pr2100_write_register(ViPipe, 0x41, 0x55); //C_LOOP_CON1_0 + pr2100_write_register(ViPipe, 0x42, 0x01); //C_LOOP_CON2_0 + pr2100_write_register(ViPipe, 0x43, 0x38); //C_LOOP_CON3_0 + pr2100_write_register(ViPipe, 0x44, 0x6a); //C_HUE_CVI0_0 + pr2100_write_register(ViPipe, 0x45, 0x00); //C_HUE_CVI1_0 + pr2100_write_register(ViPipe, 0x46, 0x14); //C_PHASE_REF0_0 + pr2100_write_register(ViPipe, 0x47, 0xb0); //C_PHASE_REF1_0 + pr2100_write_register(ViPipe, 0x48, 0xdf); //C_PHASE_REF2_0 + pr2100_write_register(ViPipe, 0x49, 0x00); //G_GAIN_REF0_0 + pr2100_write_register(ViPipe, 0x4a, 0x7b); //G_GAIN_REF1_0 + pr2100_write_register(ViPipe, 0x4b, 0x60); //MAN_C_GAIN_VAL0_0 + pr2100_write_register(ViPipe, 0x4c, 0x00); //MAN_C_GAIN_VAL1_0 + pr2100_write_register(ViPipe, 0x4d, 0x26); //YC_DELAY0 + pr2100_write_register(ViPipe, 0x4e, 0x00); //HD_HALF_MD0 + pr2100_write_register(ViPipe, 0x4f, 0x2c); //OUTFMT_CON0 + pr2100_write_register(ViPipe, 0x50, 0x21); //TST_EQ_POS0_0 + pr2100_write_register(ViPipe, 0x51, 0x28); //TST_EQ_POS1_0 + pr2100_write_register(ViPipe, 0x52, 0x40); //TST_EQ_POS2_0 + pr2100_write_register(ViPipe, 0x53, 0x0c); //TST_VID_DEC0 + pr2100_write_register(ViPipe, 0x54, 0x0f); //TST_VID_RST0 + pr2100_write_register(ViPipe, 0x55, 0x8d); //PTZ_SLICE_LVL0 + pr2100_write_register(ViPipe, 0x70, 0x06); //COMB_VCRL_VTH1_0 + pr2100_write_register(ViPipe, 0x71, 0x08); //COMB_VCRL_VTH2_0 + pr2100_write_register(ViPipe, 0x72, 0x0a); //COMB_VCRL_VTH3_0 + pr2100_write_register(ViPipe, 0x73, 0x0c); //COMB_VCRL_VTH4_0 + pr2100_write_register(ViPipe, 0x74, 0x0e); //COMB_VCRL_VTH5_0 + pr2100_write_register(ViPipe, 0x75, 0x10); //COMB_VCRL_VTH6_0 + pr2100_write_register(ViPipe, 0x76, 0x12); //COMB_VCRL_VTH7_0 + pr2100_write_register(ViPipe, 0x77, 0x14); //COMB_VCRL_VTH8_0 + pr2100_write_register(ViPipe, 0x78, 0x06); //COMB_VMIX_VTH1_0 + pr2100_write_register(ViPipe, 0x79, 0x08); //COMB_VMIX_VTH2_0 + pr2100_write_register(ViPipe, 0x7a, 0x0a); //COMB_VMIX_VTH3_0 + pr2100_write_register(ViPipe, 0x7b, 0x0c); //COMB_VMIX_VTH4_0 + pr2100_write_register(ViPipe, 0x7c, 0x0e); //COMB_VMIX_VTH5_0 + pr2100_write_register(ViPipe, 0x7d, 0x10); //COMB_VMIX_VTH6_0 + pr2100_write_register(ViPipe, 0x7e, 0x12); //COMB_VMIX_VTH7_0 + pr2100_write_register(ViPipe, 0x7f, 0x14); //COMB_VMIX_VTH8_0 + pr2100_write_register(ViPipe, 0x80, 0x00); //STD_VPOS_PVI_960MSB0 + pr2100_write_register(ViPipe, 0x81, 0x09); //STD_VPOS_PVI_960LSB0 + pr2100_write_register(ViPipe, 0x82, 0x00); //STD_VPOS_CVI_960MSB0 + pr2100_write_register(ViPipe, 0x83, 0x07); //STD_VPOS_CVI_960LSB0 + pr2100_write_register(ViPipe, 0x84, 0x00); //STD_VPOS_AHD_960MSB0 + pr2100_write_register(ViPipe, 0x85, 0x17); //STD_VPOS_AHD_960LSB0 + pr2100_write_register(ViPipe, 0x86, 0x03); //STD_VPOS_TVI_960MSB0 + pr2100_write_register(ViPipe, 0x87, 0xe5); //STD_VPOS_TVI_960LSB0 + pr2100_write_register(ViPipe, 0x88, 0x05); //STD_HPOS_PVI_960MSB0 + pr2100_write_register(ViPipe, 0x89, 0x24); //STD_HPOS_PVI_960LSB0 + pr2100_write_register(ViPipe, 0x8a, 0x05); //STD_HPOS_CVI_960MSB0 + pr2100_write_register(ViPipe, 0x8b, 0x24); //STD_HPOS_CVI_960LSB0 + pr2100_write_register(ViPipe, 0x8c, 0x08); //STD_HPOS_AHD_960MSB0 + pr2100_write_register(ViPipe, 0x8d, 0xe8); //STD_HPOS_AHD_960LSB0 + pr2100_write_register(ViPipe, 0x8e, 0x05); //STD_HPOS_TVI_960MSB0 + pr2100_write_register(ViPipe, 0x8f, 0x47); //STD_HPOS_TVI_960LSB0 + pr2100_write_register(ViPipe, 0x90, 0x02); //VSYNC_ACCUM_960MSB0 + pr2100_write_register(ViPipe, 0x91, 0xb4); //VSYNC_ACCUM_960LSB0 + pr2100_write_register(ViPipe, 0x92, 0x73); //VLINE_MAX_960_MSB0 + pr2100_write_register(ViPipe, 0x93, 0xe8); //VLINE_MAX_960_LSB0 + pr2100_write_register(ViPipe, 0x94, 0x0f); //SLICE_VSYNC0 + pr2100_write_register(ViPipe, 0x95, 0x5e); //STD_SLICE_AHD0 + pr2100_write_register(ViPipe, 0x96, 0x03); //HACT_SIZE_960_MSB0 + pr2100_write_register(ViPipe, 0x97, 0xd0); //HACT_SIZE_960_LSB0 + pr2100_write_register(ViPipe, 0x98, 0x17); //HPERIOD_960P25MSB0 + pr2100_write_register(ViPipe, 0x99, 0x34); //HPERIOD_960P25LSB0 + pr2100_write_register(ViPipe, 0x9a, 0x13); //HPERIOD_960P30MSB0 + pr2100_write_register(ViPipe, 0x9b, 0x56); //HPERIOD_960P30LSB0 + pr2100_write_register(ViPipe, 0x9c, 0x0b); //HPERIOD_960P50MSB0 + pr2100_write_register(ViPipe, 0x9d, 0x9a); //HPERIOD_960P50LSB0 + pr2100_write_register(ViPipe, 0x9e, 0x09); //HPERIOD_960P60MSB0 + pr2100_write_register(ViPipe, 0x9f, 0xab); //HPERIOD_960P60LSB0 + pr2100_write_register(ViPipe, 0xa0, 0x01); //VALY_STRT_960P25MSB0 + pr2100_write_register(ViPipe, 0xa1, 0x74); //VALY_STRT_960P25LSB0 + pr2100_write_register(ViPipe, 0xa2, 0x01); //VALY_STRT_960P30MSB0 + pr2100_write_register(ViPipe, 0xa3, 0x6b); //VALY_STRT_960P30LSB0 + pr2100_write_register(ViPipe, 0xa4, 0x00); //VALY_STRT_960P50MSB0 + pr2100_write_register(ViPipe, 0xa5, 0xba); //VALY_STRT_960P50LSB0 + pr2100_write_register(ViPipe, 0xa6, 0x00); //VALY_STRT_960P60MSB0 + pr2100_write_register(ViPipe, 0xa7, 0xa3); //VALY_STRT_960P60LSB0 + pr2100_write_register(ViPipe, 0xa8, 0x01); //PED_STRT_960P25MSB0 + pr2100_write_register(ViPipe, 0xa9, 0x39); //PED_STRT_960P25LSB0 + pr2100_write_register(ViPipe, 0xaa, 0x01); //PED_STRT_960P30MSB0 + pr2100_write_register(ViPipe, 0xab, 0x39); //PED_STRT_960P30LSB0 + pr2100_write_register(ViPipe, 0xac, 0x00); //PED_STRT_960P50MSB0 + pr2100_write_register(ViPipe, 0xad, 0xc1); //PED_STRT_960P50LSB0 + pr2100_write_register(ViPipe, 0xae, 0x00); //PED_STRT_960P60MSB0 + pr2100_write_register(ViPipe, 0xaf, 0xc1); //PED_STRT_960P60LSB0 + pr2100_write_register(ViPipe, 0xb0, 0x05); //COMB_MEM_960PMSB0 + pr2100_write_register(ViPipe, 0xb1, 0xcc); //COMB_MEM_960PLSB0 + pr2100_write_register(ViPipe, 0xb2, 0x09); //C_JIT_GAIN_960PMSB0 + pr2100_write_register(ViPipe, 0xb3, 0x6d); //C_JIT_GAIN_960PLSB0 + pr2100_write_register(ViPipe, 0xb4, 0x00); //STD_VPOS_AHD_MSB0 + pr2100_write_register(ViPipe, 0xb5, 0x17); //STD_VPOS_AHD_LSB0 + pr2100_write_register(ViPipe, 0xb6, 0x08); //STD_HPOS_AHD_MSB0 + pr2100_write_register(ViPipe, 0xb7, 0xe8); //STD_HPOS_AHD_LSB0 + pr2100_write_register(ViPipe, 0xb8, 0xb0); //STD_TVI_OFFSET_25F0 + pr2100_write_register(ViPipe, 0xb9, 0xce); //STD_TVI_OFFSET_30F0 + pr2100_write_register(ViPipe, 0xba, 0x90); //STD_TVI_OFFSET_960P0 + pr2100_write_register(ViPipe, 0xbb, 0x00); //EXT_SYNC_CON0 + pr2100_write_register(ViPipe, 0xbc, 0x00); //VOSYNC_HDELAY_MSB0 + pr2100_write_register(ViPipe, 0xbd, 0x04); //VOSYNC_HDELAY_LSB0 + pr2100_write_register(ViPipe, 0xbe, 0x07); //VOSYNC_HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xbf, 0x80); //VOSYNC_HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xc0, 0x00); //VOSYNC_VDELAY_MSB0 + pr2100_write_register(ViPipe, 0xc1, 0x00); //VOSYNC_VDELAY_LSB0 + #if PR2100_TEST_PATTERN + pr2100_write_register(ViPipe, 0xc2, 0x44); + pr2100_write_register(ViPipe, 0xc3, 0x38); + #else + pr2100_write_register(ViPipe, 0xc2, 0x04); //VOSYNC_VACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xc3, 0x39); //VOSYNC_VACTIVE_LSB0 + #endif + pr2100_write_register(ViPipe, 0xc4, output_pattern_ch0); + pr2100_write_register(ViPipe, 0xc9, 0x00); //VISYNC_HDELAY_MSB0 + pr2100_write_register(ViPipe, 0xca, 0x02); //VISYNC_HDELAY_LSB0 + pr2100_write_register(ViPipe, 0xcb, 0x07); //VISYNC_HACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xcc, 0x80); //VISYNC_HACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xcd, 0x08); //VISYNC_VDELAY_MSB0 + pr2100_write_register(ViPipe, 0xce, 0x20); //VISYNC_VDELAY_LSB0 + pr2100_write_register(ViPipe, 0xcf, 0x04); //VISYNC_VACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xd0, 0x38); //VISYNC_VACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xd1, 0x10); //MIPI_DATA_FLD_CON_0 + pr2100_write_register(ViPipe, 0xd2, 0x00); //MIPI_DATA_ODD_VAL_0 + pr2100_write_register(ViPipe, 0xd3, 0x00); //MIPI_DATA_EVEN_VAL_0 + #if PR2100_TEST_PATTERN + pr2100_write_register(ViPipe, 0xcf, 0x8c); //VISYNC_VACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xd0, 0x38); //VISYNC_VACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xcd, 0x40); //VISYNC_VDELAY_MSB0 + #endif + pr2100_write_register(ViPipe, 0xFF, 0x02); + pr2100_write_register(ViPipe, 0x00, 0xe4); //VID_CON1 + pr2100_write_register(ViPipe, 0x01, 0x61); //GAINFIT1 + pr2100_write_register(ViPipe, 0x02, 0x00); //PEDFIT1 + pr2100_write_register(ViPipe, 0x03, 0x56); //CLAMP_CON1 + pr2100_write_register(ViPipe, 0x04, 0x0c); //HPLL_CON0_1 + pr2100_write_register(ViPipe, 0x05, 0x88); //HPLL_CON1_1 + pr2100_write_register(ViPipe, 0x06, 0x04); //HPLL_CON2_1 + pr2100_write_register(ViPipe, 0x07, 0xb2); //HPLL_CON3_1 + pr2100_write_register(ViPipe, 0x08, 0x44); //HPLL_CON4_1 + pr2100_write_register(ViPipe, 0x09, 0x34); //HPLL_CON5_1 + pr2100_write_register(ViPipe, 0x0a, 0x02); //HPLL_CON6_1 + pr2100_write_register(ViPipe, 0x0b, 0x14); //STD_POS0_1 + pr2100_write_register(ViPipe, 0x0c, 0x04); //STD_POS1_1 + pr2100_write_register(ViPipe, 0x0d, 0x08); //STD_POS2_1 + pr2100_write_register(ViPipe, 0x0e, 0x5e); //STD_SLICE0_1 + pr2100_write_register(ViPipe, 0x0f, 0x5e); //STD_SLICE1_1 + pr2100_write_register(ViPipe, 0x10, 0x26); //STD_SLICE2_1 + pr2100_write_register(ViPipe, 0x11, 0x00); //HDELAY_MSB1 + pr2100_write_register(ViPipe, 0x12, 0x87); //HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0x13, 0x24); //HDELAY_LSB1 + pr2100_write_register(ViPipe, 0x14, 0x80); //HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x15, 0x2a); //VDELAY1 + pr2100_write_register(ViPipe, 0x16, 0x38); //VACTIVE1 + pr2100_write_register(ViPipe, 0x17, 0x00); //CBG_DELAY_MSB1 + pr2100_write_register(ViPipe, 0x18, 0x80); //CBG_ACTIVE_MSB1 + pr2100_write_register(ViPipe, 0x19, 0x48); //CBG_DELAY_LSB1 + pr2100_write_register(ViPipe, 0x1a, 0x6c); //CBG_ACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x1b, 0x05); //VSMASK_INV_STRT1 + pr2100_write_register(ViPipe, 0x1c, 0x61); //VSMASK_INV_END1 + pr2100_write_register(ViPipe, 0x1d, 0x07); //CBP_DELAY_MSB1 + pr2100_write_register(ViPipe, 0x1e, 0x7e); //CBP_DELAY_LSB1 + pr2100_write_register(ViPipe, 0x1f, 0x80); //HSCL_ACTIVE_LSB1 + pr2100_write_register(ViPipe, 0x20, 0x80); //CONT1 + pr2100_write_register(ViPipe, 0x21, 0x80); //BRGT1 + pr2100_write_register(ViPipe, 0x22, 0x90); //SAT1 + pr2100_write_register(ViPipe, 0x23, 0x80); //HUE1 + pr2100_write_register(ViPipe, 0x24, 0x80); //CB_GAIN1 + pr2100_write_register(ViPipe, 0x25, 0x80); //CR_GAIN1 + pr2100_write_register(ViPipe, 0x26, 0x84); //CB_OFF1 + pr2100_write_register(ViPipe, 0x27, 0x82); //CR_OFF1 + pr2100_write_register(ViPipe, 0x28, 0x00); //Y_OUT_GAIN1 + pr2100_write_register(ViPipe, 0x29, 0xff); //DOWN_HSCL_MSB1 + pr2100_write_register(ViPipe, 0x2a, 0xff); //DOWN_HSCL_LSB1 + pr2100_write_register(ViPipe, 0x2b, 0x00); //MAN_HSCL_ADD0_1 + pr2100_write_register(ViPipe, 0x2c, 0x00); //MAN_HSCL_ADD1_1 + pr2100_write_register(ViPipe, 0x2d, 0x00); //MAN_HSCL_ADD2_1 + pr2100_write_register(ViPipe, 0x2e, 0x00); //MAN_OUTFMT_ADD0_1 + pr2100_write_register(ViPipe, 0x2f, 0x00); //MAN_OUTFMT_ADD1_1 + pr2100_write_register(ViPipe, 0x30, 0x00); //MAN_OUTFMT_ADD2_1 + pr2100_write_register(ViPipe, 0x31, 0x00); //MAN_COMB_MD1 + pr2100_write_register(ViPipe, 0x32, 0xc0); //COMB_CRL_MD1 + pr2100_write_register(ViPipe, 0x33, 0x14); //COMB_CVBS_CRL0_1 + pr2100_write_register(ViPipe, 0x34, 0x14); //COMB_CVBS_CRL1_1 + pr2100_write_register(ViPipe, 0x35, 0x80); //COMB_CVBS_CRL2_1 + pr2100_write_register(ViPipe, 0x36, 0x80); //COMB_CVBS_CRL3_1 + pr2100_write_register(ViPipe, 0x37, 0xad); //HD_Y_NOTCH_MD1 + pr2100_write_register(ViPipe, 0x38, 0x4b); //HD_COMB_FLT_MD1 + pr2100_write_register(ViPipe, 0x39, 0x08); //Y_DYN_PEAK_GN1 + pr2100_write_register(ViPipe, 0x3a, 0x21); //HD_Y_LPF_MD1 + pr2100_write_register(ViPipe, 0x3b, 0x02); //Y_HPF_CORE_MIN1 + pr2100_write_register(ViPipe, 0x3c, 0x01); //Y_HPF_CORE_STEP1 + pr2100_write_register(ViPipe, 0x3d, 0x23); //CORE_CON1 + pr2100_write_register(ViPipe, 0x3e, 0x05); //MAN_CLPF_MD1 + pr2100_write_register(ViPipe, 0x3f, 0xc8); //HD_CTI_CON1 + pr2100_write_register(ViPipe, 0x40, 0x05); //C_LOOP_CON0_1 + pr2100_write_register(ViPipe, 0x41, 0x55); //C_LOOP_CON1_1 + pr2100_write_register(ViPipe, 0x42, 0x01); //C_LOOP_CON2_1 + pr2100_write_register(ViPipe, 0x43, 0x38); //C_LOOP_CON3_1 + pr2100_write_register(ViPipe, 0x44, 0x6a); //C_HUE_CVI0_1 + pr2100_write_register(ViPipe, 0x45, 0x00); //C_HUE_CVI1_1 + pr2100_write_register(ViPipe, 0x46, 0x14); //C_PHASE_REF0_1 + pr2100_write_register(ViPipe, 0x47, 0xb0); //C_PHASE_REF1_1 + pr2100_write_register(ViPipe, 0x48, 0xdf); //C_PHASE_REF2_1 + pr2100_write_register(ViPipe, 0x49, 0x00); //G_GAIN_REF0_1 + pr2100_write_register(ViPipe, 0x4a, 0x7b); //G_GAIN_REF1_1 + pr2100_write_register(ViPipe, 0x4b, 0x60); //MAN_C_GAIN_VAL0_1 + pr2100_write_register(ViPipe, 0x4c, 0x00); //MAN_C_GAIN_VAL1_1 + pr2100_write_register(ViPipe, 0x4d, 0x26); //YC_DELAY1 + pr2100_write_register(ViPipe, 0x4e, 0x00); //HD_HALF_MD1 + pr2100_write_register(ViPipe, 0x4f, 0x2c); //OUTFMT_CON1 + pr2100_write_register(ViPipe, 0x50, 0x21); //TST_EQ_POS0_1 + pr2100_write_register(ViPipe, 0x51, 0x28); //TST_EQ_POS1_1 + pr2100_write_register(ViPipe, 0x52, 0x40); //TST_EQ_POS2_1 + pr2100_write_register(ViPipe, 0x53, 0x0c); //TST_VID_DEC1 + pr2100_write_register(ViPipe, 0x54, 0x0f); //TST_VID_RST1 + pr2100_write_register(ViPipe, 0x55, 0x8d); //PTZ_SLICE_LVL1 + pr2100_write_register(ViPipe, 0x70, 0x06); //COMB_VCRL_VTH1_1 + pr2100_write_register(ViPipe, 0x71, 0x08); //COMB_VCRL_VTH2_1 + pr2100_write_register(ViPipe, 0x72, 0x0a); //COMB_VCRL_VTH3_1 + pr2100_write_register(ViPipe, 0x73, 0x0c); //COMB_VCRL_VTH4_1 + pr2100_write_register(ViPipe, 0x74, 0x0e); //COMB_VCRL_VTH5_1 + pr2100_write_register(ViPipe, 0x75, 0x10); //COMB_VCRL_VTH6_1 + pr2100_write_register(ViPipe, 0x76, 0x12); //COMB_VCRL_VTH7_1 + pr2100_write_register(ViPipe, 0x77, 0x14); //COMB_VCRL_VTH8_1 + pr2100_write_register(ViPipe, 0x78, 0x06); //COMB_VMIX_VTH1_1 + pr2100_write_register(ViPipe, 0x79, 0x08); //COMB_VMIX_VTH2_1 + pr2100_write_register(ViPipe, 0x7a, 0x0a); //COMB_VMIX_VTH3_1 + pr2100_write_register(ViPipe, 0x7b, 0x0c); //COMB_VMIX_VTH4_1 + pr2100_write_register(ViPipe, 0x7c, 0x0e); //COMB_VMIX_VTH5_1 + pr2100_write_register(ViPipe, 0x7d, 0x10); //COMB_VMIX_VTH6_1 + pr2100_write_register(ViPipe, 0x7e, 0x12); //COMB_VMIX_VTH7_1 + pr2100_write_register(ViPipe, 0x7f, 0x14); //COMB_VMIX_VTH8_1 + pr2100_write_register(ViPipe, 0x80, 0x00); //STD_VPOS_PVI_960MSB1 + pr2100_write_register(ViPipe, 0x81, 0x09); //STD_VPOS_PVI_960LSB1 + pr2100_write_register(ViPipe, 0x82, 0x00); //STD_VPOS_CVI_960MSB1 + pr2100_write_register(ViPipe, 0x83, 0x07); //STD_VPOS_CVI_960LSB1 + pr2100_write_register(ViPipe, 0x84, 0x00); //STD_VPOS_AHD_960MSB1 + pr2100_write_register(ViPipe, 0x85, 0x17); //STD_VPOS_AHD_960LSB1 + pr2100_write_register(ViPipe, 0x86, 0x03); //STD_VPOS_TVI_960MSB1 + pr2100_write_register(ViPipe, 0x87, 0xe5); //STD_VPOS_TVI_960LSB1 + pr2100_write_register(ViPipe, 0x88, 0x05); //STD_HPOS_PVI_960MSB1 + pr2100_write_register(ViPipe, 0x89, 0x24); //STD_HPOS_PVI_960LSB1 + pr2100_write_register(ViPipe, 0x8a, 0x05); //STD_HPOS_CVI_960MSB1 + pr2100_write_register(ViPipe, 0x8b, 0x24); //STD_HPOS_CVI_960LSB1 + pr2100_write_register(ViPipe, 0x8c, 0x08); //STD_HPOS_AHD_960MSB1 + pr2100_write_register(ViPipe, 0x8d, 0xe8); //STD_HPOS_AHD_960LSB1 + pr2100_write_register(ViPipe, 0x8e, 0x05); //STD_HPOS_TVI_960MSB1 + pr2100_write_register(ViPipe, 0x8f, 0x47); //STD_HPOS_TVI_960LSB1 + pr2100_write_register(ViPipe, 0x90, 0x02); //VSYNC_ACCUM_960MSB1 + pr2100_write_register(ViPipe, 0x91, 0xb4); //VSYNC_ACCUM_960LSB1 + pr2100_write_register(ViPipe, 0x92, 0x73); //VLINE_MAX_960_MSB1 + pr2100_write_register(ViPipe, 0x93, 0xe8); //VLINE_MAX_960_LSB1 + pr2100_write_register(ViPipe, 0x94, 0x0f); //SLICE_VSYNC1 + pr2100_write_register(ViPipe, 0x95, 0x5e); //STD_SLICE_AHD1 + pr2100_write_register(ViPipe, 0x96, 0x03); //HACT_SIZE_960_MSB1 + pr2100_write_register(ViPipe, 0x97, 0xd0); //HACT_SIZE_960_LSB1 + pr2100_write_register(ViPipe, 0x98, 0x17); //HPERIOD_960P25MSB1 + pr2100_write_register(ViPipe, 0x99, 0x34); //HPERIOD_960P25LSB1 + pr2100_write_register(ViPipe, 0x9a, 0x13); //HPERIOD_960P30MSB1 + pr2100_write_register(ViPipe, 0x9b, 0x56); //HPERIOD_960P30LSB1 + pr2100_write_register(ViPipe, 0x9c, 0x0b); //HPERIOD_960P50MSB1 + pr2100_write_register(ViPipe, 0x9d, 0x9a); //HPERIOD_960P50LSB1 + pr2100_write_register(ViPipe, 0x9e, 0x09); //HPERIOD_960P60MSB1 + pr2100_write_register(ViPipe, 0x9f, 0xab); //HPERIOD_960P60LSB1 + pr2100_write_register(ViPipe, 0xa0, 0x01); //VALY_STRT_960P25MSB1 + pr2100_write_register(ViPipe, 0xa1, 0x74); //VALY_STRT_960P25LSB1 + pr2100_write_register(ViPipe, 0xa2, 0x01); //VALY_STRT_960P30MSB1 + pr2100_write_register(ViPipe, 0xa3, 0x6b); //VALY_STRT_960P30LSB1 + pr2100_write_register(ViPipe, 0xa4, 0x00); //VALY_STRT_960P50MSB1 + pr2100_write_register(ViPipe, 0xa5, 0xba); //VALY_STRT_960P50LSB1 + pr2100_write_register(ViPipe, 0xa6, 0x00); //VALY_STRT_960P60MSB1 + pr2100_write_register(ViPipe, 0xa7, 0xa3); //VALY_STRT_960P60LSB1 + pr2100_write_register(ViPipe, 0xa8, 0x01); //PED_STRT_960P25MSB1 + pr2100_write_register(ViPipe, 0xa9, 0x39); //PED_STRT_960P25LSB1 + pr2100_write_register(ViPipe, 0xaa, 0x01); //PED_STRT_960P30MSB1 + pr2100_write_register(ViPipe, 0xab, 0x39); //PED_STRT_960P30LSB1 + pr2100_write_register(ViPipe, 0xac, 0x00); //PED_STRT_960P50MSB1 + pr2100_write_register(ViPipe, 0xad, 0xc1); //PED_STRT_960P50LSB1 + pr2100_write_register(ViPipe, 0xae, 0x00); //PED_STRT_960P60MSB1 + pr2100_write_register(ViPipe, 0xaf, 0xc1); //PED_STRT_960P60LSB1 + pr2100_write_register(ViPipe, 0xb0, 0x05); //COMB_MEM_960PMSB1 + pr2100_write_register(ViPipe, 0xb1, 0xcc); //COMB_MEM_960PLSB1 + pr2100_write_register(ViPipe, 0xb2, 0x09); //C_JIT_GAIN_960PMSB1 + pr2100_write_register(ViPipe, 0xb3, 0x6d); //C_JIT_GAIN_960PLSB1 + pr2100_write_register(ViPipe, 0xb4, 0x00); //STD_VPOS_AHD_MSB1 + pr2100_write_register(ViPipe, 0xb5, 0x17); //STD_VPOS_AHD_LSB1 + pr2100_write_register(ViPipe, 0xb6, 0x08); //STD_HPOS_AHD_MSB1 + pr2100_write_register(ViPipe, 0xb7, 0xe8); //STD_HPOS_AHD_LSB1 + pr2100_write_register(ViPipe, 0xb8, 0xb0); //STD_TVI_OFFSET_25F1 + pr2100_write_register(ViPipe, 0xb9, 0xce); //STD_TVI_OFFSET_30F1 + pr2100_write_register(ViPipe, 0xba, 0x90); //STD_TVI_OFFSET_960P1 + pr2100_write_register(ViPipe, 0xbb, 0x00); //EXT_SYNC_CON1 + pr2100_write_register(ViPipe, 0xbc, 0x00); //VOSYNC_HDELAY_MSB1 + pr2100_write_register(ViPipe, 0xbd, 0x04); //VOSYNC_HDELAY_LSB1 + pr2100_write_register(ViPipe, 0xbe, 0x07); //VOSYNC_HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xbf, 0x80); //VOSYNC_HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xc0, 0x00); //VOSYNC_VDELAY_MSB1 + pr2100_write_register(ViPipe, 0xc1, 0x00); //VOSYNC_VDELAY_LSB1 + #if PR2100_TEST_PATTERN + pr2100_write_register(ViPipe, 0xc2, 0x44); + pr2100_write_register(ViPipe, 0xc3, 0x38); + #else + pr2100_write_register(ViPipe, 0xc2, 0x04); //VOSYNC_VACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xc3, 0x39); //VOSYNC_VACTIVE_LSB1 + #endif + pr2100_write_register(ViPipe, 0xc4, output_pattern_ch1); + pr2100_write_register(ViPipe, 0xc9, 0x00); //VISYNC_HDELAY_MSB1 + pr2100_write_register(ViPipe, 0xca, 0x02); //VISYNC_HDELAY_LSB1 + pr2100_write_register(ViPipe, 0xcb, 0x07); //VISYNC_HACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xcc, 0x80); //VISYNC_HACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xcd, 0x08); //VISYNC_VDELAY_MSB1 + pr2100_write_register(ViPipe, 0xce, 0x20); //VISYNC_VDELAY_LSB1 + pr2100_write_register(ViPipe, 0xcf, 0x04); //VISYNC_VACTIVE_MSB1 + pr2100_write_register(ViPipe, 0xd0, 0x38); //VISYNC_VACTIVE_LSB1 + pr2100_write_register(ViPipe, 0xd1, 0x10); //MIPI_DATA_FLD_CON_1 + pr2100_write_register(ViPipe, 0xd2, 0x00); //MIPI_DATA_ODD_VAL_1 + pr2100_write_register(ViPipe, 0xd3, 0x00); //MIPI_DATA_EVEN_VAL_1 + #if PR2100_TEST_PATTERN + pr2100_write_register(ViPipe, 0xcf, 0x8c); //VISYNC_VACTIVE_MSB0 + pr2100_write_register(ViPipe, 0xd0, 0x38); //VISYNC_VACTIVE_LSB0 + pr2100_write_register(ViPipe, 0xcd, 0x40); //VISYNC_VDELAY_MSB0 + #endif + pr2100_write_register(ViPipe, 0xFF, 0x05); + pr2100_write_register(ViPipe, 0x09, 0x00); //REF_CH_STRT + pr2100_write_register(ViPipe, 0x0a, 0x03); //REF_CH_VDLY + pr2100_write_register(ViPipe, 0x0e, 0x80); //VBLK_CODE + pr2100_write_register(ViPipe, 0x0f, 0x10); //VBLK_CODE + pr2100_write_register(ViPipe, 0x10, 0xb3); //MTX_CTRL + pr2100_write_register(ViPipe, 0x11, 0xb0); //MTX_LONG_DLY_H + pr2100_write_register(ViPipe, 0x12, 0x6e); //MTX_LONG_DLY_L + pr2100_write_register(ViPipe, 0x13, 0x00); //MTX_SHORT_DLY_H + pr2100_write_register(ViPipe, 0x14, 0x6e); //MTX_SHORT_DLY_L + pr2100_write_register(ViPipe, 0x15, 0x00); //REF_OFFSET + pr2100_write_register(ViPipe, 0x16, 0x00); //REF_FE_HDLY + pr2100_write_register(ViPipe, 0x17, 0x00); //REF_FE_HDLY + pr2100_write_register(ViPipe, 0x18, 0x00); //REF_FS_HDLY + pr2100_write_register(ViPipe, 0x19, 0x00); //REF_FS_HDLY + pr2100_write_register(ViPipe, 0x1a, 0x00); //REF_HTOTAL + pr2100_write_register(ViPipe, 0x1b, 0x00); //REF_HTOTAL + pr2100_write_register(ViPipe, 0x1c, 0x00); //REF_VTOTAL + pr2100_write_register(ViPipe, 0x1d, 0x00); //REF_VTOTAL + pr2100_write_register(ViPipe, 0x1e, 0x00); //CHID_MD + pr2100_write_register(ViPipe, 0x20, 0x88); //MTX_CH0_CTRL + pr2100_write_register(ViPipe, 0x21, 0x07); //MTX_CH0_HSIZE + pr2100_write_register(ViPipe, 0x22, 0x80); //MTX_CH0_HSIZE + pr2100_write_register(ViPipe, 0x23, 0x04); //MTX_CH0_VSIZE + pr2100_write_register(ViPipe, 0x24, 0x38); //MTX_CH0_VSIZE + pr2100_write_register(ViPipe, 0x25, 0x0f); //CH0_FS_OS_H + pr2100_write_register(ViPipe, 0x26, 0x00); //CH0_FS_OS_L + pr2100_write_register(ViPipe, 0x27, 0x0f); //CH0_FE_OS_H + pr2100_write_register(ViPipe, 0x28, 0x00); //CH0_FE_OS_L + pr2100_write_register(ViPipe, 0x29, 0x0b); //REF_CH0_VS_OS + pr2100_write_register(ViPipe, 0x2a, 0x40); //REF_CH0_VS_OS + pr2100_write_register(ViPipe, 0x30, 0x98); //MTX_CH1_CTRL + pr2100_write_register(ViPipe, 0x31, 0x07); //MTX_CH1_HSIZE + pr2100_write_register(ViPipe, 0x32, 0x80); //MTX_CH1_HSIZE + pr2100_write_register(ViPipe, 0x33, 0x04); //MTX_CH1_VSIZE + pr2100_write_register(ViPipe, 0x34, 0x38); //MTX_CH1_VSIZE + pr2100_write_register(ViPipe, 0x35, 0x0f); //CH1_FS_OS_H + pr2100_write_register(ViPipe, 0x36, 0x00); //CH1_FS_OS_L + pr2100_write_register(ViPipe, 0x37, 0x0f); //CH1_FE_OS_H + pr2100_write_register(ViPipe, 0x38, 0x00); //CH1_FE_OS_L + pr2100_write_register(ViPipe, 0x39, 0x07); //REF_CH1_VS_OS + pr2100_write_register(ViPipe, 0x3a, 0x80); //REF_CH1_VS_OS + pr2100_write_register(ViPipe, 0x40, 0xa8); //MTX_CH2_CTRL + pr2100_write_register(ViPipe, 0x41, 0x07); //MTX_CH2_HSIZE + pr2100_write_register(ViPipe, 0x42, 0x80); //MTX_CH2_HSIZE + pr2100_write_register(ViPipe, 0x43, 0x04); //MTX_CH2_VSIZE + pr2100_write_register(ViPipe, 0x44, 0x38); //MTX_CH2_VSIZE + pr2100_write_register(ViPipe, 0x45, 0x0f); //CH2_FS_OS_H + pr2100_write_register(ViPipe, 0x46, 0x00); //CH2_FS_OS_L + pr2100_write_register(ViPipe, 0x47, 0x0f); //CH2_FE_OS_H + pr2100_write_register(ViPipe, 0x48, 0x00); //CH2_FE_OS_L + pr2100_write_register(ViPipe, 0x49, 0x03); //REF_CH2_VS_OS + pr2100_write_register(ViPipe, 0x4a, 0xc0); //REF_CH2_VS_OS + pr2100_write_register(ViPipe, 0x50, 0xb8); //MTX_CH3_CTRL + pr2100_write_register(ViPipe, 0x51, 0x07); //MTX_CH3_HSIZE + pr2100_write_register(ViPipe, 0x52, 0x80); //MTX_CH3_HSIZE + pr2100_write_register(ViPipe, 0x53, 0x04); //MTX_CH3_VSIZE + pr2100_write_register(ViPipe, 0x54, 0x38); //MTX_CH3_VSIZE + pr2100_write_register(ViPipe, 0x55, 0x0f); //CH3_FS_OS_H + pr2100_write_register(ViPipe, 0x56, 0x00); //CH3_FS_OS_L + pr2100_write_register(ViPipe, 0x57, 0x0f); //CH3_FE_OS_H + pr2100_write_register(ViPipe, 0x58, 0x00); //CH3_FE_OS_L + pr2100_write_register(ViPipe, 0x59, 0x00); //REF_CH3_VS_OS + pr2100_write_register(ViPipe, 0x5a, 0x00); //REF_CH3_VS_OS + pr2100_write_register(ViPipe, 0x60, 0x05); //CH0_HWIDTH[13:8] + pr2100_write_register(ViPipe, 0x61, 0x28); //CH0_HWIDTH [7:0] + pr2100_write_register(ViPipe, 0x62, 0x05); //CH1_HWIDTH[13:8] + pr2100_write_register(ViPipe, 0x63, 0x28); //CH1_HWIDTH [7:0] + pr2100_write_register(ViPipe, 0x64, 0x05); //CH2_HWIDTH[13:8] + pr2100_write_register(ViPipe, 0x65, 0x28); //CH2_HWIDTH [7:0] + pr2100_write_register(ViPipe, 0x66, 0x05); //CH3_HWIDTH[13:8] + pr2100_write_register(ViPipe, 0x67, 0x28); //CH3_HWIDTH [7:0] + pr2100_write_register(ViPipe, 0x68, 0xff); //CH0_VRATE[15:8] + pr2100_write_register(ViPipe, 0x69, 0xff); //CH0_VRATE[7:0] + pr2100_write_register(ViPipe, 0x6a, 0xff); //CH1_VRATE[15:8] + pr2100_write_register(ViPipe, 0x6b, 0xff); //CH1_VRATE[7:0] + pr2100_write_register(ViPipe, 0x6c, 0xff); //CH2_VRATE[15:8] + pr2100_write_register(ViPipe, 0x6d, 0xff); //CH2_VRATE[7:0] + pr2100_write_register(ViPipe, 0x6e, 0xff); //CH3_VRATE[15:8] + pr2100_write_register(ViPipe, 0x6f, 0xff); //CH3_VRATE[7:0] + + pr2100_write_register(ViPipe, 0xFF, 0x06); + pr2100_write_register(ViPipe, 0x04, 0x10); //MIPI_CONTROL_0 + pr2100_write_register(ViPipe, 0x05, 0x04); //MIPI_CONTROL_1 + pr2100_write_register(ViPipe, 0x06, 0x00); //MIPI_CONTROL_2 + pr2100_write_register(ViPipe, 0x07, 0x00); //MIPI_CONTROL_3 + pr2100_write_register(ViPipe, 0x08, 0xc9); //MIPI_CONTROL_4 + pr2100_write_register(ViPipe, 0x1c, 0x09); //MIPI_T_LPX + pr2100_write_register(ViPipe, 0x1d, 0x08); //MIPI_T_CLK_PREPARE + pr2100_write_register(ViPipe, 0x1e, 0x09); //MIPI_T_HS_PREPARE + pr2100_write_register(ViPipe, 0x1f, 0x11); //MIPI_T_HS_ZERO + pr2100_write_register(ViPipe, 0x20, 0x0c); //MIPI_T_HS_TRAIL + pr2100_write_register(ViPipe, 0x21, 0x28); //MIPI_T_CLK_ZERO + pr2100_write_register(ViPipe, 0x22, 0x0b); //MIPI_T_CLK_TRAIL + pr2100_write_register(ViPipe, 0x23, 0x01); //MIPI_T_CLK_PRE + pr2100_write_register(ViPipe, 0x24, 0x12); //MIPI_T_CLK_POST + pr2100_write_register(ViPipe, 0x25, 0x82); //MIPI_T_WAKEUP + pr2100_write_register(ViPipe, 0x26, 0x11); //MIPI_T_HSEXIT + pr2100_write_register(ViPipe, 0x27, 0x11); //MIPI_T_CLK_HSEXIT + pr2100_write_register(ViPipe, 0x36, 0x0f); //MIPI_PKT_SIZE0_H + pr2100_write_register(ViPipe, 0x37, 0x00); //MIPI_PKT_SIZE0_L + pr2100_write_register(ViPipe, 0x38, 0x0f); //MIPI_PKT_SIZE1_H + pr2100_write_register(ViPipe, 0x39, 0x00); //MIPI_PKT_SIZE1_L + pr2100_write_register(ViPipe, 0x3a, 0x0f); //MIPI_PKT_SIZE2_H + pr2100_write_register(ViPipe, 0x3b, 0x00); //MIPI_PKT_SIZE2_L + pr2100_write_register(ViPipe, 0x3c, 0x0f); //MIPI_PKT_SIZE3_H + pr2100_write_register(ViPipe, 0x3d, 0x00); //MIPI_PKT_SIZE3_L + pr2100_write_register(ViPipe, 0x46, 0x1e); //MIPI_DATA_ID0 + pr2100_write_register(ViPipe, 0x47, 0x5e); //MIPI_DATA_ID1 + pr2100_write_register(ViPipe, 0x48, 0x9e); //MIPI_DATA_ID2 + pr2100_write_register(ViPipe, 0x49, 0xde); //MIPI_DATA_ID3 + pr2100_write_register(ViPipe, 0x04, 0x50); //MIPI_CONTROL_0 + + pr2100_set_1080p_4ch_slave(slave_pipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs/Makefile b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs/Makefile new file mode 100644 index 000000000..b1901ad9d --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc035gs.a +TARGET_SO = $(MW_LIB)/libsns_sc035gs.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs/sc035gs_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs/sc035gs_cmos.c new file mode 100644 index 000000000..f4eec6d28 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs/sc035gs_cmos.c @@ -0,0 +1,992 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc035gs_cmos_ex.h" +#include "sc035gs_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC035GS_ID 35 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC035GS[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC035GS_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC035GS[dev]) +#define SC035GS_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC035GS[dev] = pstCtx) +#define SC035GS_SENSOR_RESET_CTX(dev) (g_pastSC035GS[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC035GS_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC035GS_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC035GS_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC035GS Lines Range*****/ +#define SC035GS_FULL_LINES_MAX (0xFFFF) + +/*****SC035GS Register Address*****/ +#define SC035GS_EXP_H_ADDR (0x3e01) +#define SC035GS_EXP_L_ADDR (0x3e02) + +#define SC035GS_AGAIN_H_ADDR (0x3e08) +#define SC035GS_AGAIN_L_ADDR (0x3e09) + +#define SC035GS_DGAIN_H_ADDR (0x3e06) +#define SC035GS_DGAIN_L_ADDR (0x3e07) + +#define SC035GS_VMAX_H_ADDR (0x320e) +#define SC035GS_VMAX_L_ADDR (0x320f) + +#define SC035GS_GAIN_MAGIC_0_ADDR (0x3314) +#define SC035GS_GAIN_MAGIC_1_ADDR (0x3317) + +#define SC035GS_RES_IS_480P(w, h) ((w) <= 640 && (h) <= 480) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC035GS_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC035GS_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC035GS_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 120); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 0.0625; /* unit = 1/16 line */ + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 120 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = pstAeSnsDft->u32MaxIntTime; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC035GS_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC035GS_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC035GS_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC035GS_MODE_640X480P120: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC035GS_FULL_LINES_MAX) ? SC035GS_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = (pstSnsState->u32FLStd - 6) << 4; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 1 + * max : 16 * (vts - 6) + * step : 1 + */ + u32MinTime = 1; + u32MaxTime = (pstSnsState->au32FL[0] - 6) << 4; + + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_ADDR].u32Data = ((u32TmpIntTime & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_ADDR].u32Data = (u32TmpIntTime & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +#define MAX_AGAIN_STEP 3 + +struct gain_tbl_info_s { + CVI_U32 gainMax; + CVI_U32 gainMin; + CVI_U32 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; + CVI_U8 stepOrd; +}; + +static struct gain_tbl_info_s AgainInfo[MAX_AGAIN_STEP] = { + { + .gainMin = 1024, + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 6, + }, + { + .gainMin = 2048, + .gainMax = 3968, + .idxBase = 16, + .regGain = 0x01, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 7, + }, + { + .gainMin = 4096, + .gainMax = 4096, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 8, + }, +/* vendor suggest the maximum again shall not be larger than 4X*/ +#if 0 + { + .gainMin = 4096, + .gainMax = 7936, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 8, + }, + { + .gainMin = 8192, + .gainMax = 15872, + .idxBase = 48, + .regGain = 0x07, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 9, + }, +#endif +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i, size = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + struct gain_tbl_info_s *gainInfo = &AgainInfo[size - 1]; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin < 1024) + *pu32AgainLin = 1024; + + if (*pu32AgainLin >= gainInfo->gainMax) { + *pu32AgainDb = gainInfo->idxBase + ((gainInfo->gainMax - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32AgainLin = gainInfo->gainMax; + return CVI_SUCCESS; + } + + for (i = size - 1; i >= 0 ; i--) { + gainInfo = &AgainInfo[i]; + if (*pu32AgainLin >= gainInfo->gainMin) { + *pu32AgainDb = gainInfo->idxBase + + ((*pu32AgainLin - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32AgainLin = ((*pu32AgainDb - gainInfo->idxBase) << gainInfo->stepOrd) + + gainInfo->gainMin; + break; + } + } + return CVI_SUCCESS; +} + +#define MAX_DGAIN_STEP 3 +static struct gain_tbl_info_s DgainInfo[MAX_DGAIN_STEP] = { + { + .gainMin = 1024, + .gainMax = 2040, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 3, + }, + { + .gainMin = 2048, + .gainMax = 4080, + .idxBase = 128, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 4, + }, + { + .gainMin = 4096, + .gainMax = 8160, + .idxBase = 256, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 5, + }, +}; + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i, size = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + struct gain_tbl_info_s *gainInfo = &DgainInfo[size - 1]; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin < 1024) + *pu32DgainLin = 1024; + + if (*pu32DgainLin >= gainInfo->gainMax) { + *pu32DgainDb = gainInfo->idxBase + ((gainInfo->gainMax - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32DgainLin = gainInfo->gainMax; + return CVI_SUCCESS; + } + + for (i = size - 1; i >= 0; i--) { + gainInfo = &DgainInfo[i]; + if (*pu32DgainLin >= gainInfo->gainMin) { + *pu32DgainDb = gainInfo->idxBase + + ((*pu32DgainLin - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32DgainLin = ((*pu32DgainDb - gainInfo->idxBase) << gainInfo->stepOrd) + + gainInfo->gainMin; + break; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H_ADDR].u32Data = ((info->regGain & 0x7) << 2) | 0x3; + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L_ADDR].u32Data = (u32Again & 0xFF); + + /* gain logic setting. */ + if (info->regGain == 0x00) {//gain<2 + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_0_ADDR].u32Data = 0x1e; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_1_ADDR].u32Data = 0x10; + } else {//[gain>=4] + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_0_ADDR].u32Data = 0x4f; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_1_ADDR].u32Data = 0x0f; + } + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H_ADDR].u32Data = 0x0C | (info->regGain & 0x3); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L_ADDR].u32Data = (u32Dgain & 0xFF); + + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC035GS_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC035GS_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC035GS_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC035GS_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC035GS_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 1; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc035gs_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc035gs_addr_byte; + pstI2c_data[i].u32DataByteNum = sc035gs_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC035GS_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC035GS_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H_ADDR].u32RegAddr = SC035GS_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L_ADDR].u32RegAddr = SC035GS_AGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC035GS_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC035GS_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC035GS_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC035GS_VMAX_L_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_0_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_0_ADDR].u32RegAddr = SC035GS_GAIN_MAGIC_0_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_1_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_1_ADDR].u32RegAddr = SC035GS_GAIN_MAGIC_1_ADDR; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 120) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC035GS_RES_IS_480P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC035GS_MODE_640X480P120; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC035GS_MODE_S *pstMode = CVI_NULL; + + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC035GS_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC035GS_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035GS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc035gs_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC035GS_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC035GS_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc035gs_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc035gs_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc035gs_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc035gs_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC035GS_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC035GS_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC035GS_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC035GS_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC035GS_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC035GS_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC035GS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC035GS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC035GS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC035GS_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC035GS_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC035GS_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc035gs_standby, + .pfnRestart = sc035gs_restart, + .pfnMirrorFlip = sc035gs_mirror_flip, + .pfnWriteReg = sc035gs_write_register, + .pfnReadReg = sc035gs_read_register, + .pfnSetBusInfo = sc035gs_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs/sc035gs_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs/sc035gs_cmos_ex.h new file mode 100644 index 000000000..1f727fd18 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs/sc035gs_cmos_ex.h @@ -0,0 +1,80 @@ +#ifndef __SC035GS_CMOS_EX_H_ +#define __SC035GS_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc035gs_linear_regs_e { + LINEAR_EXP_H_ADDR, + LINEAR_EXP_L_ADDR, + LINEAR_AGAIN_H_ADDR, + LINEAR_AGAIN_L_ADDR, + LINEAR_DGAIN_H_ADDR, + LINEAR_DGAIN_L_ADDR, + LINEAR_VMAX_H_ADDR, + LINEAR_VMAX_L_ADDR, + LINEAR_GAIN_MAGIC_0_ADDR, + LINEAR_GAIN_MAGIC_1_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC035GS_MODE_E { + SC035GS_MODE_640X480P120 = 0, + SC035GS_MODE_LINEAR_NUM, + SC035GS_MODE_NUM +} SC035GS_MODE_E; + +typedef struct _SC035GS_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} SC035GS_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC035GS[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC035GS_BusInfo[]; +extern CVI_U16 g_au16SC035GS_GainMode[]; +extern CVI_U16 g_au16SC035GS_L2SMode[]; +extern const CVI_U8 sc035gs_i2c_addr; +extern const CVI_U32 sc035gs_addr_byte; +extern const CVI_U32 sc035gs_data_byte; +extern void sc035gs_init(VI_PIPE ViPipe); +extern void sc035gs_exit(VI_PIPE ViPipe); +extern void sc035gs_standby(VI_PIPE ViPipe); +extern void sc035gs_restart(VI_PIPE ViPipe); +extern int sc035gs_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc035gs_read_register(VI_PIPE ViPipe, int addr); +extern void sc035gs_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC035GS_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs/sc035gs_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs/sc035gs_cmos_param.h new file mode 100644 index 000000000..9e5d0d5c6 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs/sc035gs_cmos_param.h @@ -0,0 +1,122 @@ +#ifndef __SC035GS_CMOS_PARAM_H_ +#define __SC035GS_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc035gs_cmos_ex.h" + +static const SC035GS_MODE_S g_astSC035GS_mode[SC035GS_MODE_NUM] = { + [SC035GS_MODE_640X480P120] = { + .name = "480p120", + .astImg[0] = { + .stSnsSize = { + .u32Width = 640, + .u32Height = 480, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 640, + .u32Height = 480, + }, + .stMaxSize = { + .u32Width = 640, + .u32Height = 480, + }, + }, + .f32MaxFps = 120, + .f32MinFps = 1.25, /* 515 * 120 / 0xFFFF */ + .u32HtsDef = 878, + .u32VtsDef = 683, + .stExp[0] = { + .u16Min = 1, + .u16Max = 677 << 4,// (vts - 6) * 16 + .u16Def = 400 << 4, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 4096, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 8160, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {145, 145, 145, 145, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1061, 1061, 1061, 1061 +#endif + }, /* [TODO] check black leve*/ + .stAuto = { + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc035gs_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {2, 0, 1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .pn_swap = {1, 1, 1, 0, 0}, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC035GS_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs/sc035gs_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs/sc035gs_sensor_ctl.c new file mode 100644 index 000000000..213a9bd3d --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs/sc035gs_sensor_ctl.c @@ -0,0 +1,307 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc035gs_cmos_ex.h" + +static void sc035gs_linear_1296P30_init(VI_PIPE ViPipe); + +const CVI_U8 sc035gs_i2c_addr = 0x30; /* I2C Address of SC035GS */ +const CVI_U32 sc035gs_addr_byte = 2; +const CVI_U32 sc035gs_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc035gs_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC035GS_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc035gs_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc035gs_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc035gs_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc035gs_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc035gs_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc035gs_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc035gs_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int sc035gs_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc035gs_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc035gs_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc035gs_addr_byte + sc035gs_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc035gs_standby(VI_PIPE ViPipe) +{ + sc035gs_write_register(ViPipe, 0x0100, 0x00); +} + +void sc035gs_restart(VI_PIPE ViPipe) +{ + sc035gs_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc035gs_write_register(ViPipe, 0x0100, 0x01); +} + +void sc035gs_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC035GS[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC035GS[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc035gs_write_register(ViPipe, + g_pastSC035GS[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC035GS[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc035gs_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = sc035gs_read_register(ViPipe, 0x3221) & ~0x66; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc035gs_write_register(ViPipe, 0x3221, val); +} + +void sc035gs_init(VI_PIPE ViPipe) +{ + sc035gs_i2c_init(ViPipe); + + //linear mode only + sc035gs_linear_1296P30_init(ViPipe); + + g_pastSC035GS[ViPipe]->bInit = CVI_TRUE; +} + +void sc035gs_exit(VI_PIPE ViPipe) +{ + sc035gs_i2c_exit(ViPipe); +} + +/* 1296P30 and 1296P25 */ +static void sc035gs_linear_1296P30_init(VI_PIPE ViPipe) +{ + sc035gs_write_register(ViPipe, 0x0103, 0x01); + delay_ms(33); + sc035gs_write_register(ViPipe, 0x0100, 0x00); + sc035gs_write_register(ViPipe, 0x36e9, 0x80); + sc035gs_write_register(ViPipe, 0x36f9, 0x80); + sc035gs_write_register(ViPipe, 0x3000, 0x00); + sc035gs_write_register(ViPipe, 0x3001, 0x00); + sc035gs_write_register(ViPipe, 0x300f, 0x0f); + sc035gs_write_register(ViPipe, 0x3018, 0x33); + sc035gs_write_register(ViPipe, 0x3019, 0x0c); + sc035gs_write_register(ViPipe, 0x301c, 0x78); + sc035gs_write_register(ViPipe, 0x3031, 0x0a); + sc035gs_write_register(ViPipe, 0x3037, 0x20); + sc035gs_write_register(ViPipe, 0x303f, 0x01); + sc035gs_write_register(ViPipe, 0x320c, 0x03); + sc035gs_write_register(ViPipe, 0x320d, 0x6e); + sc035gs_write_register(ViPipe, 0x320e, 0x02); + sc035gs_write_register(ViPipe, 0x320f, 0xab); + sc035gs_write_register(ViPipe, 0x3252, 0x02); // 0x1 + sc035gs_write_register(ViPipe, 0x3253, 0x08); // 0xf8 + //sc035gs_write_register(ViPipe, 0x3252, 0x02); + //sc035gs_write_register(ViPipe, 0x3253, 0xa6); + sc035gs_write_register(ViPipe, 0x3220, 0x10); + sc035gs_write_register(ViPipe, 0x3250, 0xc0); + sc035gs_write_register(ViPipe, 0x3251, 0x02); + sc035gs_write_register(ViPipe, 0x3254, 0x02); + sc035gs_write_register(ViPipe, 0x3255, 0x07); + sc035gs_write_register(ViPipe, 0x3304, 0x48); + sc035gs_write_register(ViPipe, 0x3306, 0x38); + sc035gs_write_register(ViPipe, 0x3309, 0x68); + sc035gs_write_register(ViPipe, 0x330b, 0xe0); + sc035gs_write_register(ViPipe, 0x330c, 0x18); + sc035gs_write_register(ViPipe, 0x330f, 0x20); + sc035gs_write_register(ViPipe, 0x3310, 0x10); + sc035gs_write_register(ViPipe, 0x3314, 0x1e); + sc035gs_write_register(ViPipe, 0x3315, 0x38); + sc035gs_write_register(ViPipe, 0x3316, 0x40); + sc035gs_write_register(ViPipe, 0x3317, 0x10); + sc035gs_write_register(ViPipe, 0x3329, 0x34); + sc035gs_write_register(ViPipe, 0x332d, 0x34); + sc035gs_write_register(ViPipe, 0x332f, 0x38); + sc035gs_write_register(ViPipe, 0x3335, 0x3c); + sc035gs_write_register(ViPipe, 0x3344, 0x3c); + sc035gs_write_register(ViPipe, 0x335b, 0x80); + sc035gs_write_register(ViPipe, 0x335f, 0x80); + sc035gs_write_register(ViPipe, 0x3366, 0x06); + sc035gs_write_register(ViPipe, 0x3385, 0x31); + sc035gs_write_register(ViPipe, 0x3387, 0x51); + sc035gs_write_register(ViPipe, 0x3389, 0x01); + sc035gs_write_register(ViPipe, 0x33b1, 0x03); + sc035gs_write_register(ViPipe, 0x33b2, 0x06); + sc035gs_write_register(ViPipe, 0x3621, 0xa4); + sc035gs_write_register(ViPipe, 0x3622, 0x05); + sc035gs_write_register(ViPipe, 0x3624, 0x47); + sc035gs_write_register(ViPipe, 0x3630, 0x46); + sc035gs_write_register(ViPipe, 0x3631, 0x48); + sc035gs_write_register(ViPipe, 0x3633, 0x52); + sc035gs_write_register(ViPipe, 0x3635, 0x18); + sc035gs_write_register(ViPipe, 0x3636, 0x25); + sc035gs_write_register(ViPipe, 0x3637, 0x89); + sc035gs_write_register(ViPipe, 0x3638, 0x0f); + sc035gs_write_register(ViPipe, 0x3639, 0x08); + sc035gs_write_register(ViPipe, 0x363a, 0x00); + sc035gs_write_register(ViPipe, 0x363b, 0x48); + sc035gs_write_register(ViPipe, 0x363c, 0x06); + sc035gs_write_register(ViPipe, 0x363d, 0x00); + sc035gs_write_register(ViPipe, 0x363e, 0xf8); + sc035gs_write_register(ViPipe, 0x3640, 0x00); + sc035gs_write_register(ViPipe, 0x3641, 0x01); + sc035gs_write_register(ViPipe, 0x36ea, 0x3b); + sc035gs_write_register(ViPipe, 0x36eb, 0x0e); + sc035gs_write_register(ViPipe, 0x36ec, 0x1e); + sc035gs_write_register(ViPipe, 0x36ed, 0x33); + sc035gs_write_register(ViPipe, 0x36fa, 0x3a); + sc035gs_write_register(ViPipe, 0x36fc, 0x01); + sc035gs_write_register(ViPipe, 0x3908, 0x91); + sc035gs_write_register(ViPipe, 0x3d08, 0x01); + sc035gs_write_register(ViPipe, 0x3e01, 0x14); + sc035gs_write_register(ViPipe, 0x3e02, 0x80); + sc035gs_write_register(ViPipe, 0x3e06, 0x0c); + sc035gs_write_register(ViPipe, 0x4500, 0x59); + sc035gs_write_register(ViPipe, 0x4501, 0xc4); + sc035gs_write_register(ViPipe, 0x4603, 0x00); + sc035gs_write_register(ViPipe, 0x4809, 0x01); + sc035gs_write_register(ViPipe, 0x4837, 0x37); + sc035gs_write_register(ViPipe, 0x5011, 0x00); + sc035gs_write_register(ViPipe, 0x36e9, 0x00); + sc035gs_write_register(ViPipe, 0x36f9, 0x00); + sc035gs_default_reg_init(ViPipe); + sc035gs_write_register(ViPipe, 0x0100, 0x01); + delay_ms(18); + sc035gs_write_register(ViPipe, 0x4418, 0x08); + sc035gs_write_register(ViPipe, 0x4419, 0x8e); + delay_ms(100); + + printf("ViPipe:%d,===SC035GS 480P 120fps 12bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs_1L/Makefile b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs_1L/Makefile new file mode 100644 index 000000000..64cc1ef82 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs_1L/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc035gs_1L.a +TARGET_SO = $(MW_LIB)/libsns_sc035gs_1L.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs_1L/sc035gs_1L_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs_1L/sc035gs_1L_cmos.c new file mode 100644 index 000000000..6cb31f0e0 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs_1L/sc035gs_1L_cmos.c @@ -0,0 +1,992 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc035gs_1L_cmos_ex.h" +#include "sc035gs_1L_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC035GS_1L_ID 35 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC035GS_1L[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC035GS_1L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC035GS_1L[dev]) +#define SC035GS_1L_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC035GS_1L[dev] = pstCtx) +#define SC035GS_1L_SENSOR_RESET_CTX(dev) (g_pastSC035GS_1L[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC035GS_1L_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC035GS_1L_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC035GS_1L_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC035GS_1L Lines Range*****/ +#define SC035GS_1L_FULL_LINES_MAX (0xFFFF) + +/*****SC035GS_1L Register Address*****/ +#define SC035GS_1L_EXP_H_ADDR (0x3e01) +#define SC035GS_1L_EXP_L_ADDR (0x3e02) + +#define SC035GS_1L_AGAIN_H_ADDR (0x3e08) +#define SC035GS_1L_AGAIN_L_ADDR (0x3e09) + +#define SC035GS_1L_DGAIN_H_ADDR (0x3e06) +#define SC035GS_1L_DGAIN_L_ADDR (0x3e07) + +#define SC035GS_1L_VMAX_H_ADDR (0x320e) +#define SC035GS_1L_VMAX_L_ADDR (0x320f) + +#define SC035GS_1L_GAIN_MAGIC_0_ADDR (0x3314) +#define SC035GS_1L_GAIN_MAGIC_1_ADDR (0x3317) + +#define SC035GS_1L_RES_IS_480P(w, h) ((w) == 640 && (h) == 480) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC035GS_1L_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC035GS_1L_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC035GS_1L_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 120); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 0.0625; /* unit = 1/16 line */ + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 120 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = pstAeSnsDft->u32MaxIntTime; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC035GS_1L_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC035GS_1L_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC035GS_1L_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC035GS_1L_MODE_640X480P120: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC035GS_1L_FULL_LINES_MAX) ? SC035GS_1L_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = (pstSnsState->u32FLStd - 6) << 4; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 1 + * max : 16 * (vts - 6) + * step : 1 + */ + u32MinTime = 1; + u32MaxTime = (pstSnsState->au32FL[0] - 6) << 4; + + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_ADDR].u32Data = ((u32TmpIntTime & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_ADDR].u32Data = (u32TmpIntTime & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +#define MAX_AGAIN_STEP 3 + +struct gain_tbl_info_s { + CVI_U32 gainMax; + CVI_U32 gainMin; + CVI_U32 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; + CVI_U8 stepOrd; +}; + +static struct gain_tbl_info_s AgainInfo[MAX_AGAIN_STEP] = { + { + .gainMin = 1024, + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 6, + }, + { + .gainMin = 2048, + .gainMax = 3968, + .idxBase = 16, + .regGain = 0x01, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 7, + }, + { + .gainMin = 4096, + .gainMax = 4096, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 8, + }, +/* vendor suggest the maximum again shall not be larger than 4X*/ +#if 0 + { + .gainMin = 4096, + .gainMax = 7936, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 8, + }, + { + .gainMin = 8192, + .gainMax = 15872, + .idxBase = 48, + .regGain = 0x07, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 9, + }, +#endif +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i, size = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + struct gain_tbl_info_s *gainInfo = &AgainInfo[size - 1]; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin < 1024) + *pu32AgainLin = 1024; + + if (*pu32AgainLin >= gainInfo->gainMax) { + *pu32AgainDb = gainInfo->idxBase + ((gainInfo->gainMax - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32AgainLin = gainInfo->gainMax; + return CVI_SUCCESS; + } + + for (i = size - 1; i >= 0 ; i--) { + gainInfo = &AgainInfo[i]; + if (*pu32AgainLin >= gainInfo->gainMin) { + *pu32AgainDb = gainInfo->idxBase + + ((*pu32AgainLin - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32AgainLin = ((*pu32AgainDb - gainInfo->idxBase) << gainInfo->stepOrd) + + gainInfo->gainMin; + break; + } + } + return CVI_SUCCESS; +} + +#define MAX_DGAIN_STEP 3 +static struct gain_tbl_info_s DgainInfo[MAX_DGAIN_STEP] = { + { + .gainMin = 1024, + .gainMax = 2040, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 3, + }, + { + .gainMin = 2048, + .gainMax = 4080, + .idxBase = 128, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 4, + }, + { + .gainMin = 4096, + .gainMax = 8160, + .idxBase = 256, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 5, + }, +}; + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i, size = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + struct gain_tbl_info_s *gainInfo = &DgainInfo[size - 1]; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin < 1024) + *pu32DgainLin = 1024; + + if (*pu32DgainLin >= gainInfo->gainMax) { + *pu32DgainDb = gainInfo->idxBase + ((gainInfo->gainMax - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32DgainLin = gainInfo->gainMax; + return CVI_SUCCESS; + } + + for (i = size - 1; i >= 0; i--) { + gainInfo = &DgainInfo[i]; + if (*pu32DgainLin >= gainInfo->gainMin) { + *pu32DgainDb = gainInfo->idxBase + + ((*pu32DgainLin - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32DgainLin = ((*pu32DgainDb - gainInfo->idxBase) << gainInfo->stepOrd) + + gainInfo->gainMin; + break; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H_ADDR].u32Data = ((info->regGain & 0x7) << 2) | 0x3; + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L_ADDR].u32Data = (u32Again & 0xFF); + + /* gain logic setting. */ + if (info->regGain == 0x00) {//gain<2 + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_0_ADDR].u32Data = 0x1e; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_1_ADDR].u32Data = 0x10; + } else {//[gain>=4] + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_0_ADDR].u32Data = 0x4f; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_1_ADDR].u32Data = 0x0f; + } + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H_ADDR].u32Data = 0x0C | (info->regGain & 0x3); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L_ADDR].u32Data = (u32Dgain & 0xFF); + + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC035GS_1L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC035GS_1L_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC035GS_1L_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC035GS_1L_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC035GS_1L_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 1; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc035gs_1L_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc035gs_1L_addr_byte; + pstI2c_data[i].u32DataByteNum = sc035gs_1L_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC035GS_1L_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC035GS_1L_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H_ADDR].u32RegAddr = SC035GS_1L_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L_ADDR].u32RegAddr = SC035GS_1L_AGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC035GS_1L_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC035GS_1L_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC035GS_1L_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC035GS_1L_VMAX_L_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_0_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_0_ADDR].u32RegAddr = SC035GS_1L_GAIN_MAGIC_0_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_1_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_1_ADDR].u32RegAddr = SC035GS_1L_GAIN_MAGIC_1_ADDR; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 120) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC035GS_1L_RES_IS_480P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC035GS_1L_MODE_640X480P120; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC035GS_1L_MODE_S *pstMode = CVI_NULL; + + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC035GS_1L_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC035GS_1L_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc035gs_1L_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC035GS_1L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC035GS_1L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc035gs_1L_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc035gs_1L_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc035gs_1L_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc035gs_1L_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC035GS_1L_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC035GS_1L_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC035GS_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC035GS_1L_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC035GS_1L_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC035GS_1L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC035GS_1L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC035GS_1L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC035GS_1L_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC035GS_1L_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC035GS_1L_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc035gs_1L_standby, + .pfnRestart = sc035gs_1L_restart, + .pfnMirrorFlip = sc035gs_1L_mirror_flip, + .pfnWriteReg = sc035gs_1L_write_register, + .pfnReadReg = sc035gs_1L_read_register, + .pfnSetBusInfo = sc035gs_1L_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs_1L/sc035gs_1L_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs_1L/sc035gs_1L_cmos_ex.h new file mode 100644 index 000000000..dfa0a52ee --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs_1L/sc035gs_1L_cmos_ex.h @@ -0,0 +1,80 @@ +#ifndef __SC035GS_1L_CMOS_EX_H_ +#define __SC035GS_1L_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc035gs_1L_linear_regs_e { + LINEAR_EXP_H_ADDR, + LINEAR_EXP_L_ADDR, + LINEAR_AGAIN_H_ADDR, + LINEAR_AGAIN_L_ADDR, + LINEAR_DGAIN_H_ADDR, + LINEAR_DGAIN_L_ADDR, + LINEAR_VMAX_H_ADDR, + LINEAR_VMAX_L_ADDR, + LINEAR_GAIN_MAGIC_0_ADDR, + LINEAR_GAIN_MAGIC_1_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC035GS_1L_MODE_E { + SC035GS_1L_MODE_640X480P120 = 0, + SC035GS_1L_MODE_LINEAR_NUM, + SC035GS_1L_MODE_NUM +} SC035GS_1L_MODE_E; + +typedef struct _SC035GS_1L_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} SC035GS_1L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC035GS_1L[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC035GS_1L_BusInfo[]; +extern CVI_U16 g_au16SC035GS_1L_GainMode[]; +extern CVI_U16 g_au16SC035GS_1L_L2SMode[]; +extern const CVI_U8 sc035gs_1L_i2c_addr; +extern const CVI_U32 sc035gs_1L_addr_byte; +extern const CVI_U32 sc035gs_1L_data_byte; +extern void sc035gs_1L_init(VI_PIPE ViPipe); +extern void sc035gs_1L_exit(VI_PIPE ViPipe); +extern void sc035gs_1L_standby(VI_PIPE ViPipe); +extern void sc035gs_1L_restart(VI_PIPE ViPipe); +extern int sc035gs_1L_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc035gs_1L_read_register(VI_PIPE ViPipe, int addr); +extern void sc035gs_1L_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC035GS_1L_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs_1L/sc035gs_1L_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs_1L/sc035gs_1L_cmos_param.h new file mode 100644 index 000000000..1df5b1ebb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs_1L/sc035gs_1L_cmos_param.h @@ -0,0 +1,122 @@ +#ifndef __SC035GS_1L_CMOS_PARAM_H_ +#define __SC035GS_1L_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc035gs_1L_cmos_ex.h" + +static const SC035GS_1L_MODE_S g_astSC035GS_1L_mode[SC035GS_1L_MODE_NUM] = { + [SC035GS_1L_MODE_640X480P120] = { + .name = "480p120", + .astImg[0] = { + .stSnsSize = { + .u32Width = 640, + .u32Height = 480, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 640, + .u32Height = 480, + }, + .stMaxSize = { + .u32Width = 640, + .u32Height = 480, + }, + }, + .f32MaxFps = 120, + .f32MinFps = 1.25, /* 515 * 120 / 0xFFFF */ + .u32HtsDef = 878, + .u32VtsDef = 683, + .stExp[0] = { + .u16Min = 1, + .u16Max = 677 << 4,// (vts - 6) * 16 + .u16Def = 400 << 4, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 4096, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 8160, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {145, 145, 145, 145, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1061, 1061, 1061, 1061 +#endif + }, /* [TODO] check black leve*/ + .stAuto = { + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc035gs_1L_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 0, -1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .pn_swap = {1, 1, 0, 0, 0}, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC035GS_1L_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs_1L/sc035gs_1L_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs_1L/sc035gs_1L_sensor_ctl.c new file mode 100644 index 000000000..ff33222ea --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc035gs_1L/sc035gs_1L_sensor_ctl.c @@ -0,0 +1,310 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc035gs_1L_cmos_ex.h" + +static void sc035gs_1L_linear_1296P30_init(VI_PIPE ViPipe); + +const CVI_U8 sc035gs_1L_i2c_addr = 0x30; /* I2C Address of SC035GS_1L */ +const CVI_U32 sc035gs_1L_addr_byte = 2; +const CVI_U32 sc035gs_1L_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc035gs_1L_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC035GS_1L_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc035gs_1L_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc035gs_1L_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc035gs_1L_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc035gs_1L_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc035gs_1L_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc035gs_1L_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc035gs_1L_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int sc035gs_1L_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc035gs_1L_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc035gs_1L_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc035gs_1L_addr_byte + sc035gs_1L_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc035gs_1L_standby(VI_PIPE ViPipe) +{ + sc035gs_1L_write_register(ViPipe, 0x0100, 0x00); +} + +void sc035gs_1L_restart(VI_PIPE ViPipe) +{ + sc035gs_1L_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc035gs_1L_write_register(ViPipe, 0x0100, 0x01); +} + +void sc035gs_1L_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC035GS_1L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC035GS_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc035gs_1L_write_register(ViPipe, + g_pastSC035GS_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC035GS_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc035gs_1L_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = sc035gs_1L_read_register(ViPipe, 0x3221) & ~0x66; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc035gs_1L_write_register(ViPipe, 0x3221, val); +} + +void sc035gs_1L_init(VI_PIPE ViPipe) +{ + sc035gs_1L_i2c_init(ViPipe); + + //linear mode only + sc035gs_1L_linear_1296P30_init(ViPipe); + + g_pastSC035GS_1L[ViPipe]->bInit = CVI_TRUE; +} + +void sc035gs_1L_exit(VI_PIPE ViPipe) +{ + sc035gs_1L_i2c_exit(ViPipe); +} + +/* 1296P30 and 1296P25 */ +static void sc035gs_1L_linear_1296P30_init(VI_PIPE ViPipe) +{ + sc035gs_1L_write_register(ViPipe, 0x0103, 0x01); + delay_ms(33); + sc035gs_1L_write_register(ViPipe, 0x0100, 0x00); + sc035gs_1L_write_register(ViPipe, 0x36e9, 0x80); + sc035gs_1L_write_register(ViPipe, 0x36f9, 0x80); + sc035gs_1L_write_register(ViPipe, 0x3001, 0x00); + sc035gs_1L_write_register(ViPipe, 0x3000, 0x00); + sc035gs_1L_write_register(ViPipe, 0x300f, 0x0f); + sc035gs_1L_write_register(ViPipe, 0x3018, 0x13); + sc035gs_1L_write_register(ViPipe, 0x3019, 0xfe); + sc035gs_1L_write_register(ViPipe, 0x301c, 0x78); + sc035gs_1L_write_register(ViPipe, 0x301f, 0x07); + sc035gs_1L_write_register(ViPipe, 0x3031, 0x0a); + sc035gs_1L_write_register(ViPipe, 0x3037, 0x20); + sc035gs_1L_write_register(ViPipe, 0x303f, 0x01); + sc035gs_1L_write_register(ViPipe, 0x320c, 0x03); + sc035gs_1L_write_register(ViPipe, 0x320d, 0x6e); + sc035gs_1L_write_register(ViPipe, 0x320e, 0x02); + sc035gs_1L_write_register(ViPipe, 0x320f, 0xab); + sc035gs_1L_write_register(ViPipe, 0x3220, 0x10); + sc035gs_1L_write_register(ViPipe, 0x3250, 0xc0); + sc035gs_1L_write_register(ViPipe, 0x3251, 0x02); + sc035gs_1L_write_register(ViPipe, 0x3252, 0x02); + sc035gs_1L_write_register(ViPipe, 0x3253, 0x08); +// sc035gs_1L_write_register(ViPipe, 0x3252, 0x02); +// sc035gs_1L_write_register(ViPipe, 0x3253, 0xa6); + sc035gs_1L_write_register(ViPipe, 0x3254, 0x02); + sc035gs_1L_write_register(ViPipe, 0x3255, 0x07); + sc035gs_1L_write_register(ViPipe, 0x3304, 0x48); + sc035gs_1L_write_register(ViPipe, 0x3306, 0x38); + sc035gs_1L_write_register(ViPipe, 0x3309, 0x68); + sc035gs_1L_write_register(ViPipe, 0x330b, 0xe0); + sc035gs_1L_write_register(ViPipe, 0x330c, 0x18); + sc035gs_1L_write_register(ViPipe, 0x330f, 0x20); + sc035gs_1L_write_register(ViPipe, 0x3310, 0x10); + sc035gs_1L_write_register(ViPipe, 0x3314, 0x1e); + sc035gs_1L_write_register(ViPipe, 0x3315, 0x38); + sc035gs_1L_write_register(ViPipe, 0x3316, 0x40); + sc035gs_1L_write_register(ViPipe, 0x3317, 0x10); + sc035gs_1L_write_register(ViPipe, 0x3329, 0x34); + sc035gs_1L_write_register(ViPipe, 0x332d, 0x34); + sc035gs_1L_write_register(ViPipe, 0x332f, 0x38); + sc035gs_1L_write_register(ViPipe, 0x3335, 0x3c); + sc035gs_1L_write_register(ViPipe, 0x3344, 0x3c); + sc035gs_1L_write_register(ViPipe, 0x335b, 0x80); + sc035gs_1L_write_register(ViPipe, 0x335f, 0x80); + sc035gs_1L_write_register(ViPipe, 0x3366, 0x06); + sc035gs_1L_write_register(ViPipe, 0x3385, 0x31); + sc035gs_1L_write_register(ViPipe, 0x3387, 0x51); + sc035gs_1L_write_register(ViPipe, 0x3389, 0x01); + sc035gs_1L_write_register(ViPipe, 0x33b1, 0x03); + sc035gs_1L_write_register(ViPipe, 0x33b2, 0x06); + sc035gs_1L_write_register(ViPipe, 0x3621, 0xa4); + sc035gs_1L_write_register(ViPipe, 0x3622, 0x05); + sc035gs_1L_write_register(ViPipe, 0x3624, 0x47); + sc035gs_1L_write_register(ViPipe, 0x3630, 0x46); + sc035gs_1L_write_register(ViPipe, 0x3631, 0x48); + sc035gs_1L_write_register(ViPipe, 0x3633, 0x52); + sc035gs_1L_write_register(ViPipe, 0x3635, 0x18); + sc035gs_1L_write_register(ViPipe, 0x3636, 0x25); + sc035gs_1L_write_register(ViPipe, 0x3637, 0x89); + sc035gs_1L_write_register(ViPipe, 0x3638, 0x0f); + sc035gs_1L_write_register(ViPipe, 0x3639, 0x08); + sc035gs_1L_write_register(ViPipe, 0x363a, 0x00); + sc035gs_1L_write_register(ViPipe, 0x363b, 0x48); + sc035gs_1L_write_register(ViPipe, 0x363c, 0x06); + sc035gs_1L_write_register(ViPipe, 0x363d, 0x00); + sc035gs_1L_write_register(ViPipe, 0x363e, 0xf8); + sc035gs_1L_write_register(ViPipe, 0x3640, 0x00); + sc035gs_1L_write_register(ViPipe, 0x3641, 0x01); + sc035gs_1L_write_register(ViPipe, 0x36ea, 0x3b); + sc035gs_1L_write_register(ViPipe, 0x36eb, 0x0e); + sc035gs_1L_write_register(ViPipe, 0x36ec, 0x0e); + sc035gs_1L_write_register(ViPipe, 0x36ed, 0x33); + sc035gs_1L_write_register(ViPipe, 0x36fa, 0x3a); + sc035gs_1L_write_register(ViPipe, 0x36fc, 0x01); + sc035gs_1L_write_register(ViPipe, 0x3908, 0x91); + sc035gs_1L_write_register(ViPipe, 0x3d08, 0x01); + sc035gs_1L_write_register(ViPipe, 0x3e01, 0x14); + sc035gs_1L_write_register(ViPipe, 0x3e02, 0x80); + sc035gs_1L_write_register(ViPipe, 0x3e06, 0x0c); + sc035gs_1L_write_register(ViPipe, 0x4500, 0x59); + sc035gs_1L_write_register(ViPipe, 0x4501, 0xc4); + sc035gs_1L_write_register(ViPipe, 0x4603, 0x00); + sc035gs_1L_write_register(ViPipe, 0x4809, 0x01); + sc035gs_1L_write_register(ViPipe, 0x4837, 0x1b); + sc035gs_1L_write_register(ViPipe, 0x5011, 0x00); + sc035gs_1L_write_register(ViPipe, 0x36e9, 0x00); + sc035gs_1L_write_register(ViPipe, 0x36f9, 0x00); + + sc035gs_1L_default_reg_init(ViPipe); + + sc035gs_1L_write_register(ViPipe, 0x0100, 0x01); + delay_ms(18); + sc035gs_1L_write_register(ViPipe, 0x4418, 0x08); + sc035gs_1L_write_register(ViPipe, 0x4419, 0x8e); + delay_ms(100); + + printf("ViPipe:%d,===SC035GS_1L 480P 120fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc035hgs/Makefile b/middleware/v2/component/isp/sensor/cv181x/sms_sc035hgs/Makefile new file mode 100644 index 000000000..58ef7260c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc035hgs/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc035hgs.a +TARGET_SO = $(MW_LIB)/libsns_sc035hgs.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc035hgs/sc035hgs_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc035hgs/sc035hgs_cmos.c new file mode 100644 index 000000000..4b971ad74 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc035hgs/sc035hgs_cmos.c @@ -0,0 +1,1059 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc035hgs_cmos_ex.h" +#include "sc035hgs_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC035HGS_ID 35 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC035HGS[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC035HGS_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC035HGS[dev]) +#define SC035HGS_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC035HGS[dev] = pstCtx) +#define SC035HGS_SENSOR_RESET_CTX(dev) (g_pastSC035HGS[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC035HGS_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC035HGS_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC035HGS_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC035HGS Lines Range*****/ +#define SC035HGS_FULL_LINES_MAX (0xFFFF) + +/*****SC035HGS Register Address*****/ +#define SC035HGS_EXP_H_ADDR (0x3e01) +#define SC035HGS_EXP_L_ADDR (0x3e02) + +#define SC035HGS_AGAIN_H_ADDR (0x3e08) +#define SC035HGS_AGAIN_L_ADDR (0x3e09) + +#define SC035HGS_DGAIN_H_ADDR (0x3e06) +#define SC035HGS_DGAIN_L_ADDR (0x3e07) + +#define SC035HGS_VMAX_H_ADDR (0x320e) +#define SC035HGS_VMAX_L_ADDR (0x320f) + +#define SC035HGS_GAIN_MAGIC_0_ADDR (0x3314) +#define SC035HGS_GAIN_MAGIC_1_ADDR (0x3317) +#define SC035HGS_GAIN_MAGIC_2_ADDR (0x3631) +#define SC035HGS_GAIN_MAGIC_3_ADDR (0x3329) +#define SC035HGS_GAIN_MAGIC_4_ADDR (0x332d) +#define SC035HGS_GAIN_MAGIC_5_ADDR (0x332f) +#define SC035HGS_GAIN_MAGIC_6_ADDR (0x3335) +#define SC035HGS_GAIN_MAGIC_7_ADDR (0x3344) +#define SC035HGS_GAIN_MAGIC_8_ADDR (0x3316) +#define SC035HGS_GAIN_MAGIC_9_ADDR (0x3630) + +#define SC035HGS_RES_IS_480P(w, h) ((w) <= 640 && (h) <= 480) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC035HGS_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC035HGS_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC035HGS_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 120); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 0.0625; /* unit = 1/16 line */ + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 120 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 3; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = pstAeSnsDft->u32MaxIntTime; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC035HGS_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC035HGS_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC035HGS_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC035HGS_MODE_640X480P120: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC035HGS_FULL_LINES_MAX) ? SC035HGS_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = (pstSnsState->u32FLStd - 6) << 4; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 1 + * max : 16 * (vts - 6) + * step : 1 + */ + u32MinTime = 1; + u32MaxTime = (pstSnsState->au32FL[0] - 6) << 4; + + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_ADDR].u32Data = ((u32TmpIntTime & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_ADDR].u32Data = (u32TmpIntTime & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +#define MAX_AGAIN_STEP 3 + +struct gain_tbl_info_s { + CVI_U32 gainMax; + CVI_U32 gainMin; + CVI_U32 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; + CVI_U8 stepOrd; +}; + +static struct gain_tbl_info_s AgainInfo[MAX_AGAIN_STEP] = { + { + .gainMin = 1024, + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 6, + }, + { + .gainMin = 2048, + .gainMax = 3968, + .idxBase = 16, + .regGain = 0x01, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 7, + }, + { + .gainMin = 4096, + .gainMax = 4096, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 8, + }, +/* vendor suggest the maximum again shall not be larger than 4X*/ +#if 0 + { + .gainMin = 4096, + .gainMax = 7936, + .gainMax = 4096, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 8, + }, + { + .gainMin = 8192, + .gainMax = 15872, + .idxBase = 48, + .regGain = 0x07, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + .stepOrd = 9, + }, +#endif +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i, size = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + struct gain_tbl_info_s *gainInfo = &AgainInfo[size - 1]; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin < 1024) + *pu32AgainLin = 1024; + + if (*pu32AgainLin >= gainInfo->gainMax) { + *pu32AgainDb = gainInfo->idxBase + ((gainInfo->gainMax - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32AgainLin = gainInfo->gainMax; + return CVI_SUCCESS; + } + + for (i = size - 1; i >= 0 ; i--) { + gainInfo = &AgainInfo[i]; + if (*pu32AgainLin >= gainInfo->gainMin) { + *pu32AgainDb = gainInfo->idxBase + + ((*pu32AgainLin - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32AgainLin = ((*pu32AgainDb - gainInfo->idxBase) << gainInfo->stepOrd) + + gainInfo->gainMin; + break; + } + } + return CVI_SUCCESS; +} + +#define MAX_DGAIN_STEP 3 +static struct gain_tbl_info_s DgainInfo[MAX_DGAIN_STEP] = { + { + .gainMin = 1024, + .gainMax = 2040, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 3, + }, + { + .gainMin = 2048, + .gainMax = 4080, + .idxBase = 128, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 4, + }, + { + .gainMin = 4096, + .gainMax = 8160, + .idxBase = 256, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 1, + .stepOrd = 5, + }, +}; + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i, size = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + struct gain_tbl_info_s *gainInfo = &DgainInfo[size - 1]; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin < 1024) + *pu32DgainLin = 1024; + + if (*pu32DgainLin >= gainInfo->gainMax) { + *pu32DgainDb = gainInfo->idxBase + ((gainInfo->gainMax - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32DgainLin = gainInfo->gainMax; + return CVI_SUCCESS; + } + + for (i = size - 1; i >= 0; i--) { + gainInfo = &DgainInfo[i]; + if (*pu32DgainLin >= gainInfo->gainMin) { + *pu32DgainDb = gainInfo->idxBase + + ((*pu32DgainLin - gainInfo->gainMin) >> gainInfo->stepOrd); + *pu32DgainLin = ((*pu32DgainDb - gainInfo->idxBase) << gainInfo->stepOrd) + + gainInfo->gainMin; + break; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H_ADDR].u32Data = ((info->regGain & 0x7) << 2) | 0x3; + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L_ADDR].u32Data = (u32Again & 0xFF); + + /* gain logic setting. */ + if (info->regGain == 0x00) {//gain<2 + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_0_ADDR].u32Data = 0x1e; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_1_ADDR].u32Data = 0x1b; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_2_ADDR].u32Data = 0x58; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_3_ADDR].u32Data = 0x3c; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_4_ADDR].u32Data = 0x3c; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_5_ADDR].u32Data = 0x40; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_6_ADDR].u32Data = 0x44; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_7_ADDR].u32Data = 0x44; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_8_ADDR].u32Data = 0x48; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_9_ADDR].u32Data = 0x4a; + } else if (info->regGain == 0x01) {//[2=astI2cData[LINEAR_GAIN_MAGIC_0_ADDR].u32Data = 0x6f; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_1_ADDR].u32Data = 0x10; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_2_ADDR].u32Data = 0x48; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_3_ADDR].u32Data = 0x5c; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_4_ADDR].u32Data = 0x5c; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_5_ADDR].u32Data = 0x60; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_6_ADDR].u32Data = 0x64; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_7_ADDR].u32Data = 0x64; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_8_ADDR].u32Data = 0x68; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_9_ADDR].u32Data = 0x4c; + } else {//[gain>=4] + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_0_ADDR].u32Data = 0x76; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_1_ADDR].u32Data = 0x15; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_2_ADDR].u32Data = 0x48; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_3_ADDR].u32Data = 0x5c; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_4_ADDR].u32Data = 0x5c; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_5_ADDR].u32Data = 0x60; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_6_ADDR].u32Data = 0x64; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_7_ADDR].u32Data = 0x64; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_8_ADDR].u32Data = 0x68; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_9_ADDR].u32Data = 0x4c; + } + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H_ADDR].u32Data = 0x0C | (info->regGain & 0x3); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L_ADDR].u32Data = (u32Dgain & 0xFF); + + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC035HGS_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC035HGS_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC035HGS_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC035HGS_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC035HGS_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 1; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc035hgs_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc035hgs_addr_byte; + pstI2c_data[i].u32DataByteNum = sc035hgs_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC035HGS_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC035HGS_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H_ADDR].u32RegAddr = SC035HGS_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_H_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_AGAIN_L_ADDR].u32RegAddr = SC035HGS_AGAIN_L_ADDR; + pstI2c_data[LINEAR_AGAIN_L_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC035HGS_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC035HGS_DGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC035HGS_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC035HGS_VMAX_L_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_0_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_0_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_0_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_0_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_1_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_1_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_1_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_1_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_2_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_2_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_2_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_2_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_3_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_3_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_3_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_3_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_4_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_4_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_4_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_4_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_5_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_5_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_5_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_5_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_6_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_6_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_6_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_6_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_7_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_7_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_7_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_7_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_8_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_8_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_8_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_8_ADDR].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_GAIN_MAGIC_9_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_9_ADDR].u32RegAddr = SC035HGS_GAIN_MAGIC_9_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_9_ADDR].u8DelayFrmNum = 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 120) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC035HGS_RES_IS_480P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC035HGS_MODE_640X480P120; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC035HGS_MODE_S *pstMode = CVI_NULL; + + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC035HGS_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC035HGS_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035HGS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc035hgs_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC035HGS_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC035HGS_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc035hgs_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc035hgs_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc035hgs_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc035hgs_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC035HGS_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC035HGS_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC035HGS_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC035HGS_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC035HGS_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC035HGS_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC035HGS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC035HGS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC035HGS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC035HGS_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC035HGS_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC035HGS_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc035hgs_standby, + .pfnRestart = sc035hgs_restart, + .pfnMirrorFlip = CVI_NULL, + .pfnWriteReg = sc035hgs_write_register, + .pfnReadReg = sc035hgs_read_register, + .pfnSetBusInfo = sc035hgs_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc035hgs/sc035hgs_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc035hgs/sc035hgs_cmos_ex.h new file mode 100644 index 000000000..2e9b6e4fb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc035hgs/sc035hgs_cmos_ex.h @@ -0,0 +1,87 @@ +#ifndef __SC035HGS_CMOS_EX_H_ +#define __SC035HGS_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc035hgs_linear_regs_e { + LINEAR_EXP_H_ADDR, + LINEAR_EXP_L_ADDR, + LINEAR_AGAIN_H_ADDR, + LINEAR_AGAIN_L_ADDR, + LINEAR_DGAIN_H_ADDR, + LINEAR_DGAIN_L_ADDR, + LINEAR_VMAX_H_ADDR, + LINEAR_VMAX_L_ADDR, + LINEAR_GAIN_MAGIC_0_ADDR, + LINEAR_GAIN_MAGIC_1_ADDR, + LINEAR_GAIN_MAGIC_2_ADDR, + LINEAR_GAIN_MAGIC_3_ADDR, + LINEAR_GAIN_MAGIC_4_ADDR, + LINEAR_GAIN_MAGIC_5_ADDR, + LINEAR_GAIN_MAGIC_6_ADDR, + LINEAR_GAIN_MAGIC_7_ADDR, + LINEAR_GAIN_MAGIC_8_ADDR, + LINEAR_GAIN_MAGIC_9_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC035HGS_MODE_E { + SC035HGS_MODE_640X480P120 = 0, + SC035HGS_MODE_LINEAR_NUM, + SC035HGS_MODE_NUM +} SC035HGS_MODE_E; + +typedef struct _SC035HGS_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} SC035HGS_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC035HGS[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC035HGS_BusInfo[]; +extern CVI_U16 g_au16SC035HGS_GainMode[]; +extern CVI_U16 g_au16SC035HGS_L2SMode[]; +extern const CVI_U8 sc035hgs_i2c_addr; +extern const CVI_U32 sc035hgs_addr_byte; +extern const CVI_U32 sc035hgs_data_byte; +extern void sc035hgs_init(VI_PIPE ViPipe); +extern void sc035hgs_exit(VI_PIPE ViPipe); +extern void sc035hgs_standby(VI_PIPE ViPipe); +extern void sc035hgs_restart(VI_PIPE ViPipe); +extern int sc035hgs_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc035hgs_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC035HGS_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc035hgs/sc035hgs_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc035hgs/sc035hgs_cmos_param.h new file mode 100644 index 000000000..8331c5ff3 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc035hgs/sc035hgs_cmos_param.h @@ -0,0 +1,122 @@ +#ifndef __SC035HGS_CMOS_PARAM_H_ +#define __SC035HGS_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc035hgs_cmos_ex.h" + +static const SC035HGS_MODE_S g_astSC035HGS_mode[SC035HGS_MODE_NUM] = { + [SC035HGS_MODE_640X480P120] = { + .name = "480p120", + .astImg[0] = { + .stSnsSize = { + .u32Width = 640, + .u32Height = 480, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 640, + .u32Height = 480, + }, + .stMaxSize = { + .u32Width = 640, + .u32Height = 480, + }, + }, + .f32MaxFps = 120, + .f32MinFps = 0.95, /* 515 * 120 / 0xFFFF */ + .u32HtsDef = 1364, + .u32VtsDef = 515, + .stExp[0] = { + .u16Min = 1, + .u16Max = 509 << 4,// (vts - 6) * 16 + .u16Def = 400 << 4, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 4096, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 8160, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {145, 145, 145, 145, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1061, 1061, 1061, 1061 +#endif + }, /* [TODO] check black leve*/ + .stAuto = { + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {145, 145, 145, 145, 145, 145, 145, 145, /*8*/145, 145, 145, 145, 145, 145, 145, 145}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, + {1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, + /*8*/1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc035hgs_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {2, 0, 1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .pn_swap = {1, 1, 1, 0, 0}, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC035HGS_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc035hgs/sc035hgs_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc035hgs/sc035hgs_sensor_ctl.c new file mode 100644 index 000000000..eaad111ef --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc035hgs/sc035hgs_sensor_ctl.c @@ -0,0 +1,307 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc035hgs_cmos_ex.h" + +static void sc035hgs_linear_1296P30_init(VI_PIPE ViPipe); + +const CVI_U8 sc035hgs_i2c_addr = 0x30; /* I2C Address of SC035HGS */ +const CVI_U32 sc035hgs_addr_byte = 2; +const CVI_U32 sc035hgs_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc035hgs_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC035HGS_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc035hgs_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc035hgs_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc035hgs_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc035hgs_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc035hgs_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc035hgs_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc035hgs_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int sc035hgs_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc035hgs_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc035hgs_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc035hgs_addr_byte + sc035hgs_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc035hgs_standby(VI_PIPE ViPipe) +{ + sc035hgs_write_register(ViPipe, 0x0100, 0x00); +} + +void sc035hgs_restart(VI_PIPE ViPipe) +{ + sc035hgs_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc035hgs_write_register(ViPipe, 0x0100, 0x01); +} + +void sc035hgs_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC035HGS[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC035HGS[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc035hgs_write_register(ViPipe, + g_pastSC035HGS[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC035HGS[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc035hgs_init(VI_PIPE ViPipe) +{ + sc035hgs_i2c_init(ViPipe); + + //linear mode only + sc035hgs_linear_1296P30_init(ViPipe); + + g_pastSC035HGS[ViPipe]->bInit = CVI_TRUE; +} + +void sc035hgs_exit(VI_PIPE ViPipe) +{ + sc035hgs_i2c_exit(ViPipe); +} + +/* 1296P30 and 1296P25 */ +static void sc035hgs_linear_1296P30_init(VI_PIPE ViPipe) +{ + sc035hgs_write_register(ViPipe, 0x0103, 0x01); + delay_ms(33); + sc035hgs_write_register(ViPipe, 0x0100, 0x00); + sc035hgs_write_register(ViPipe, 0x36e9, 0x80); + sc035hgs_write_register(ViPipe, 0x36f9, 0x80); + sc035hgs_write_register(ViPipe, 0x3000, 0x00); + sc035hgs_write_register(ViPipe, 0x3001, 0x00); + sc035hgs_write_register(ViPipe, 0x300f, 0x0f); + sc035hgs_write_register(ViPipe, 0x3018, 0x33); + sc035hgs_write_register(ViPipe, 0x3019, 0xfc); + sc035hgs_write_register(ViPipe, 0x301c, 0x78); + sc035hgs_write_register(ViPipe, 0x301f, 0x8e); + sc035hgs_write_register(ViPipe, 0x3031, 0x0c); + sc035hgs_write_register(ViPipe, 0x3037, 0x40); + sc035hgs_write_register(ViPipe, 0x303f, 0x01); + sc035hgs_write_register(ViPipe, 0x320c, 0x05); + sc035hgs_write_register(ViPipe, 0x320d, 0x54); + sc035hgs_write_register(ViPipe, 0x320e, 0x02); + sc035hgs_write_register(ViPipe, 0x320f, 0x03); + sc035hgs_write_register(ViPipe, 0x3217, 0x00); + sc035hgs_write_register(ViPipe, 0x3218, 0x00); + sc035hgs_write_register(ViPipe, 0x3220, 0x10); + sc035hgs_write_register(ViPipe, 0x3223, 0x48); + sc035hgs_write_register(ViPipe, 0x3226, 0x74); + sc035hgs_write_register(ViPipe, 0x3227, 0x07); + sc035hgs_write_register(ViPipe, 0x323b, 0x00); + sc035hgs_write_register(ViPipe, 0x3250, 0xf0); + sc035hgs_write_register(ViPipe, 0x3251, 0x02); + sc035hgs_write_register(ViPipe, 0x3252, 0x02); // 0x1 + sc035hgs_write_register(ViPipe, 0x3253, 0x08); // 0xf8 + sc035hgs_write_register(ViPipe, 0x3254, 0x02); + sc035hgs_write_register(ViPipe, 0x3255, 0x07); + sc035hgs_write_register(ViPipe, 0x3304, 0x48); + sc035hgs_write_register(ViPipe, 0x3305, 0x00); + sc035hgs_write_register(ViPipe, 0x3306, 0x98); + sc035hgs_write_register(ViPipe, 0x3309, 0x50); + sc035hgs_write_register(ViPipe, 0x330a, 0x01); + sc035hgs_write_register(ViPipe, 0x330b, 0x18); + sc035hgs_write_register(ViPipe, 0x330c, 0x18); + sc035hgs_write_register(ViPipe, 0x330f, 0x40); + sc035hgs_write_register(ViPipe, 0x3310, 0x10); + sc035hgs_write_register(ViPipe, 0x3314, 0x1e); + sc035hgs_write_register(ViPipe, 0x3315, 0x30); + sc035hgs_write_register(ViPipe, 0x3316, 0x48); + sc035hgs_write_register(ViPipe, 0x3317, 0x1b); + sc035hgs_write_register(ViPipe, 0x3329, 0x3c); + sc035hgs_write_register(ViPipe, 0x332d, 0x3c); + sc035hgs_write_register(ViPipe, 0x332f, 0x40); + sc035hgs_write_register(ViPipe, 0x3335, 0x44); + sc035hgs_write_register(ViPipe, 0x3344, 0x44); + sc035hgs_write_register(ViPipe, 0x335b, 0x80); + sc035hgs_write_register(ViPipe, 0x335f, 0x80); + sc035hgs_write_register(ViPipe, 0x3366, 0x06); + sc035hgs_write_register(ViPipe, 0x3385, 0x31); + sc035hgs_write_register(ViPipe, 0x3387, 0x39); + sc035hgs_write_register(ViPipe, 0x3389, 0x01); + sc035hgs_write_register(ViPipe, 0x33b1, 0x03); + sc035hgs_write_register(ViPipe, 0x33b2, 0x06); + sc035hgs_write_register(ViPipe, 0x33bd, 0xe0); + sc035hgs_write_register(ViPipe, 0x33bf, 0x10); + sc035hgs_write_register(ViPipe, 0x3621, 0xa4); + sc035hgs_write_register(ViPipe, 0x3622, 0x05); + sc035hgs_write_register(ViPipe, 0x3624, 0x47); + sc035hgs_write_register(ViPipe, 0x3630, 0x4a); + sc035hgs_write_register(ViPipe, 0x3631, 0x68); + sc035hgs_write_register(ViPipe, 0x3633, 0x52); + sc035hgs_write_register(ViPipe, 0x3635, 0x03); + sc035hgs_write_register(ViPipe, 0x3636, 0x25); + sc035hgs_write_register(ViPipe, 0x3637, 0x8a); + sc035hgs_write_register(ViPipe, 0x3638, 0x0f); + sc035hgs_write_register(ViPipe, 0x3639, 0x08); + sc035hgs_write_register(ViPipe, 0x363a, 0x00); + sc035hgs_write_register(ViPipe, 0x363b, 0x48); + sc035hgs_write_register(ViPipe, 0x363c, 0x86); + sc035hgs_write_register(ViPipe, 0x363e, 0xf8); + sc035hgs_write_register(ViPipe, 0x3640, 0x00); + sc035hgs_write_register(ViPipe, 0x3641, 0x01); + sc035hgs_write_register(ViPipe, 0x36ea, 0x31); + sc035hgs_write_register(ViPipe, 0x36eb, 0x0f); + sc035hgs_write_register(ViPipe, 0x36ec, 0x1f); + sc035hgs_write_register(ViPipe, 0x36ed, 0x20); + sc035hgs_write_register(ViPipe, 0x36fa, 0x36); + sc035hgs_write_register(ViPipe, 0x36fb, 0x10); + sc035hgs_write_register(ViPipe, 0x36fc, 0x02); + sc035hgs_write_register(ViPipe, 0x36fd, 0x00); + sc035hgs_write_register(ViPipe, 0x3908, 0x91); + sc035hgs_write_register(ViPipe, 0x391b, 0x81); + sc035hgs_write_register(ViPipe, 0x3d08, 0x01); + sc035hgs_write_register(ViPipe, 0x3e01, 0x18); + sc035hgs_write_register(ViPipe, 0x3e02, 0xf0); + sc035hgs_write_register(ViPipe, 0x3e03, 0x2b); + sc035hgs_write_register(ViPipe, 0x3e06, 0x0c); + sc035hgs_write_register(ViPipe, 0x3f04, 0x03); + sc035hgs_write_register(ViPipe, 0x3f05, 0x80); + sc035hgs_write_register(ViPipe, 0x4500, 0x59); + sc035hgs_write_register(ViPipe, 0x4501, 0xc4); + sc035hgs_write_register(ViPipe, 0x4603, 0x00); + sc035hgs_write_register(ViPipe, 0x4800, 0x64); + sc035hgs_write_register(ViPipe, 0x4809, 0x01); + sc035hgs_write_register(ViPipe, 0x4810, 0x00); + sc035hgs_write_register(ViPipe, 0x4811, 0x01); + sc035hgs_write_register(ViPipe, 0x4837, 0x30); + sc035hgs_write_register(ViPipe, 0x5011, 0x00); + sc035hgs_write_register(ViPipe, 0x5988, 0x02); + sc035hgs_write_register(ViPipe, 0x598e, 0x05); + sc035hgs_write_register(ViPipe, 0x598f, 0x17); + sc035hgs_write_register(ViPipe, 0x36e9, 0x20); + sc035hgs_write_register(ViPipe, 0x36f9, 0x52); + + sc035hgs_default_reg_init(ViPipe); + + sc035hgs_write_register(ViPipe, 0x0100, 0x01); + sc035hgs_write_register(ViPipe, 0x363d, 0x10); + sc035hgs_write_register(ViPipe, 0x4418, 0x08); + sc035hgs_write_register(ViPipe, 0x4419, 0x80); + + delay_ms(100); + + printf("ViPipe:%d,===SC035HGS 480P 120fps 12bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc200ai/Makefile b/middleware/v2/component/isp/sensor/cv181x/sms_sc200ai/Makefile new file mode 100644 index 000000000..f98c8fb88 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc200ai/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc200ai.a +TARGET_SO = $(MW_LIB)/libsns_sc200ai.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc200ai/sc200ai_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc200ai/sc200ai_cmos.c new file mode 100644 index 000000000..2fd5fa0a9 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc200ai/sc200ai_cmos.c @@ -0,0 +1,1327 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc200ai_cmos_ex.h" +#include "sc200ai_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC200AI_ID 35 +#define SENSOR_SC200AI_WIDTH 1920 +#define SENSOR_SC200AI_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC200AI[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC200AI_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC200AI[dev]) +#define SC200AI_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC200AI[dev] = pstCtx) +#define SC200AI_SENSOR_RESET_CTX(dev) (g_pastSC200AI[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC200AI_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC200AI_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC200AI_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC200AI_STATE_S g_astSC200AI_State[VI_MAX_PIPE_NUM] = {{0} }; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC200AI Lines Range*****/ +#define SC200AI_FULL_LINES_MAX (0x7FFF) +#define SC200AI_FULL_LINES_MAX_2TO1_WDR (0x7FFF) + +/*****SC200AI Register Address*****/ +#define SC200AI_SHS1_0_ADDR 0x3E00 +#define SC200AI_SHS1_1_ADDR 0x3E01 +#define SC200AI_SHS1_2_ADDR 0x3E02 +#define SC200AI_SHS2_0_ADDR 0x3E22 +#define SC200AI_SHS2_1_ADDR 0x3E04 +#define SC200AI_SHS2_2_ADDR 0x3E05 +#define SC200AI_AGAIN1_ADDR 0x3E08 +#define SC200AI_DGAIN1_ADDR 0x3E06 +#define SC200AI_AGAIN2_ADDR 0x3E12 +#define SC200AI_DGAIN2_ADDR 0x3E10 +#define SC200AI_VMAX_ADDR 0x320E +#define SC200AI_MAXSEXP_ADDR 0x3E23 +#define SC200AI_TABLE_END 0xFFFF + +#define SC200AI_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC200AI_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astSC200AI_mode[SC200AI_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC200AI_mode[SC200AI_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 55270; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 32512; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 4; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astSC200AI_mode[SC200AI_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC200AI_mode[SC200AI_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstAeSnsDft->u32MinIntTime = 1; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 55270; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 32512; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + CVI_U16 u16MaxSexpReg; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC200AI_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC200AI_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC200AI_mode[pstSnsState->u8ImgMode].f32MinFps; + u16MaxSexpReg = g_astSC200AI_mode[pstSnsState->u8ImgMode].u16SexpMaxReg; + + switch (pstSnsState->u8ImgMode) { + case SC200AI_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + u16MaxSexpReg = u16MaxSexpReg * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC200AI_FULL_LINES_MAX_2TO1_WDR) ? SC200AI_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case SC200AI_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC200AI_FULL_LINES_MAX) ? SC200AI_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + g_astSC200AI_State[ViPipe].u32Sexp_MAX = u16MaxSexpReg - 5; + } + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + pstSnsRegsInfo->astI2cData[WDR2_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_MAXSEXP_0_ADDR].u32Data = ((u16MaxSexpReg & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_MAXSEXP_1_ADDR].u32Data = u16MaxSexpReg & 0xFF; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + CVI_U16 u16SexpReg, u16LexpReg; + CVI_U32 u32MaxLExp; + + /* short exposure reg range: + * min : 1 + * max : 2 * reg_sexp_max - 10 + * step : 4 + */ + pstSnsState->au32WDRIntTime[0] = (u32ShortIntTime > g_astSC200AI_State[ViPipe].u32Sexp_MAX) ? + g_astSC200AI_State[ViPipe].u32Sexp_MAX : u32ShortIntTime; + if (!pstSnsState->au32WDRIntTime[0]) + pstSnsState->au32WDRIntTime[0] = 1; + /* short exp = SexpReg / 2 */ + u16SexpReg = (CVI_U16)(pstSnsState->au32WDRIntTime[0] * 2 - 1); + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + + /* long exposure reg range: + * min : 1 + * max : 2 * (vts - max sexp) + * step : 4 + */ + u32MaxLExp = pstSnsState->au32FL[0] - g_astSC200AI_State[ViPipe].u32Sexp_MAX; + pstSnsState->au32WDRIntTime[1] = (u32LongIntTime > u32MaxLExp) ? u32MaxLExp : u32LongIntTime; + if (!pstSnsState->au32WDRIntTime[1]) + pstSnsState->au32WDRIntTime[1] = 1; + u16LexpReg = (CVI_U16)(pstSnsState->au32WDRIntTime[1] * 2 - 1); + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + pstSnsRegsInfo->astI2cData[WDR2_SHS1_0_ADDR].u32Data = ((u16LexpReg & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[WDR2_SHS1_1_ADDR].u32Data = ((u16LexpReg & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[WDR2_SHS1_2_ADDR].u32Data = (u16LexpReg & 0xF) << 4; + + pstSnsRegsInfo->astI2cData[WDR2_SHS2_0_ADDR].u32Data = ((u16SexpReg & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[WDR2_SHS2_1_ADDR].u32Data = ((u16SexpReg & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[WDR2_SHS2_2_ADDR].u32Data = (u16SexpReg & 0xF) << 4; + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + CVI_U32 u32TmpIntTime = u32IntTime[0]; + /* linear exposure reg range: + * min : 1 + * max : 2 * (vts - 8) + * step : 1 + */ + u32TmpIntTime = (u32TmpIntTime > (pstSnsState->au32FL[0] - 4)) ? + (pstSnsState->au32FL[0] - 4) : u32TmpIntTime; + u32TmpIntTime = u32TmpIntTime << 1; + if (!u32TmpIntTime) + u32TmpIntTime = 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = (u32TmpIntTime & 0xF) << 4; + } + + return CVI_SUCCESS; + +} + +struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +}; + +static struct gain_tbl_info_s AgainInfo[6] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x03, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 3456, + .idxBase = 64, + .regGain = 0x07, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 6908, + .idxBase = 109, + .regGain = 0x23, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 13817, + .idxBase = 173, + .regGain = 0x27, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 27635, + .idxBase = 237, + .regGain = 0x2f, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 55270, + .idxBase = 301, + .regGain = 0x3f, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, +}; + +static CVI_U32 Again_table[365] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, 1248, 1263, 1280, + 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, 1472, 1487, 1504, 1519, 1536, 1552, + 1567, 1584, 1600, 1615, 1632, 1647, 1664, 1680, 1695, 1712, 1728, 1743, 1760, 1775, 1792, 1808, 1823, + 1840, 1856, 1871, 1888, 1903, 1920, 1936, 1951, 1968, 1984, 1999, 2016, 2031, 2048, 2079, 2112, 2144, + 2176, 2207, 2240, 2272, 2304, 2335, 2368, 2400, 2432, 2463, 2496, 2528, 2560, 2591, 2624, 2656, 2688, + 2719, 2752, 2784, 2816, 2847, 2880, 2912, 2944, 2975, 3008, 3040, 3072, 3103, 3136, 3168, 3200, 3231, + 3264, 3296, 3328, 3359, 3392, 3424, 3456, 3481, 3535, 3590, 3644, 3699, 3753, 3808, 3862, 3916, 3971, + 4025, 4079, 4134, 4189, 4243, 4297, 4352, 4406, 4460, 4514, 4570, 4624, 4678, 4732, 4787, 4841, 4895, + 4950, 5005, 5059, 5113, 5168, 5222, 5276, 5330, 5385, 5440, 5494, 5549, 5603, 5657, 5711, 5766, 5820, + 5875, 5929, 5984, 6038, 6092, 6147, 6201, 6255, 6310, 6365, 6419, 6473, 6528, 6582, 6636, 6690, 6746, + 6800, 6854, 6908, 6963, 7071, 7181, 7289, 7398, 7506, 7616, 7725, 7833, 7942, 8051, 8160, 8268, 8377, + 8486, 8595, 8704, 8812, 8922, 9030, 9139, 9247, 9357, 9465, 9574, 9682, 9792, 9901, 10009, 10118, 10227, + 10336, 10444, 10553, 10662, 10771, 10880, 10988, 11098, 11206, 11315, 11423, 11533, 11641, 11750, 11858, + 11968, 12077, 12185, 12294, 12403, 12512, 12620, 12729, 12838, 12947, 13056, 13164, 13274, 13382, 13491, + 13599, 13709, 13817, 13926, 14144, 14361, 14579, 14796, 15014, 15232, 15450, 15667, 15885, 16102, 16320, + 16537, 16755, 16972, 17190, 17408, 17626, 17843, 18061, 18278, 18496, 18713, 18931, 19148, 19366, 19584, + 19802, 20019, 20237, 20454, 20672, 20889, 21107, 21324, 21542, 21760, 21978, 22195, 22413, 22630, 22848, + 23065, 23283, 23500, 23718, 23936, 24154, 24371, 24589, 24806, 25024, 25241, 25459, 25676, 25894, 26112, + 26330, 26547, 26765, 26982, 27200, 27417, 27635, 27852, 28288, 28723, 29158, 29593, 30028, 30464, 30899, + 31334, 31769, 32204, 32640, 33075, 33510, 33945, 34380, 34816, 35251, 35686, 36121, 36556, 36992, 37427, + 37862, 38297, 38732, 39168, 39603, 40038, 40473, 40908, 41344, 41779, 42214, 42649, 43084, 43520, 43955, + 44390, 44825, 45260, 45696, 46131, 46566, 47001, 47436, 47872, 48307, 48742, 49177, 49612, 50048, 50483, + 50918, 51353, 51788, 52224, 52659, 53094, 53529, 53964, 54400, 54835, 55270 +}; + +static struct gain_tbl_info_s DgainInfo[5] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 8128, + .idxBase = 128, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 16256, + .idxBase = 192, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 32512, + .idxBase = 256, + .regGain = 0x0f, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, +}; + +static CVI_U32 Dgain_table[320] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, 1248, + 1263, 1280, 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, 1472, 1487, + 1504, 1519, 1536, 1552, 1567, 1584, 1600, 1615, 1632, 1647, 1664, 1680, 1695, 1712, 1728, + 1743, 1760, 1775, 1792, 1808, 1823, 1840, 1856, 1871, 1888, 1903, 1920, 1936, 1951, 1968, + 1984, 1999, 2016, 2031, 2048, 2079, 2112, 2144, 2176, 2207, 2240, 2272, 2304, 2335, 2368, + 2400, 2432, 2463, 2496, 2528, 2560, 2591, 2624, 2656, 2688, 2719, 2752, 2784, 2816, 2847, + 2880, 2912, 2944, 2975, 3008, 3040, 3072, 3103, 3136, 3168, 3200, 3231, 3264, 3296, 3328, + 3359, 3392, 3424, 3456, 3487, 3520, 3552, 3584, 3615, 3648, 3680, 3712, 3743, 3776, 3808, + 3840, 3871, 3904, 3936, 3968, 3999, 4032, 4064, 4096, 4160, 4224, 4288, 4352, 4416, 4480, + 4544, 4608, 4672, 4736, 4800, 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, + 5504, 5568, 5632, 5696, 5760, 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, + 6464, 6528, 6592, 6656, 6720, 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, + 7424, 7488, 7552, 7616, 7680, 7744, 7808, 7872, 7936, 8000, 8064, 8128, 8192, 8320, 8448, + 8576, 8704, 8832, 8960, 9088, 9216, 9344, 9472, 9600, 9728, 9856, 9984, 10112, 10240, 10368, + 10496, 10624, 10752, 10880, 11008, 11136, 11264, 11392, 11520, 11648, 11776, 11904, 12032, + 12160, 12288, 12416, 12544, 12672, 12800, 12928, 13056, 13184, 13312, 13440, 13568, 13696, + 13824, 13952, 14080, 14208, 14336, 14464, 14592, 14720, 14848, 14976, 15104, 15232, 15360, + 15488, 15616, 15744, 15872, 16000, 16128, 16256, 16384, 16640, 16896, 17152, 17408, 17664, + 17920, 18176, 18432, 18688, 18944, 19200, 19456, 19712, 19968, 20224, 20480, 20736, 20992, + 21248, 21504, 21760, 22016, 22272, 22528, 22784, 23040, 23296, 23552, 23808, 24064, 24320, + 24576, 24832, 25088, 25344, 25600, 25856, 26112, 26368, 26624, 26880, 27136, 27392, 27648, + 27904, 28160, 28416, 28672, 28928, 29184, 29440, 29696, 29952, 30208, 30464, 30720, 30976, + 31232, 31488, 31744, 32000, 32256, 32512 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[364]) { + *pu32AgainLin = Again_table[364]; + *pu32AgainDb = 364; + return CVI_SUCCESS; + } + + for (i = 1; i < 365; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[319]) { + *pu32DgainLin = Dgain_table[319]; + *pu32DgainDb = 319; + return CVI_SUCCESS; + } + + for (i = 1; i < 320; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u16Mode = g_au16SC200AI_GainMode[ViPipe]; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + static bool bGainLogicChanged[VI_MAX_PIPE_NUM] = {true}; + + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + // control sensor DPC to fix high-gain noise + if (Again_table[u32Again] >= 30720 && bGainLogicChanged[ViPipe]) { + sc200ai_write_register(ViPipe, 0x5799, 0x7); + bGainLogicChanged[ViPipe] = false; + } else if (Again_table[u32Again] <= 20480 && !bGainLogicChanged[ViPipe]) { + sc200ai_write_register(ViPipe, 0x5799, 0x0); + bGainLogicChanged[ViPipe] = true; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1_ADDR].u32Data = (u32Dgain & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + /* find SEF Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find SEF Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_1_ADDR].u32Data = (u32Dgain & 0xFF); + + u32Again = pu32Again[1]; + u32Dgain = pu32Dgain[1]; + + /* find LEF Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find LEF Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_1_ADDR].u32Data = (u32Dgain & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_0_ADDR].u32Data = (info->regGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_1_ADDR].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_0_ADDR].u32Data = (info->regGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_1_ADDR].u32Data = (u32Dgain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_1_ADDR].u32Data = (u32Dgain & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0; + CVI_U32 u32ShortTimeMinLimit = 1; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + (void) u16ManRatioEnable; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + /* short exposure reg range: + * min : 1 + * max : 2 * (max sexp - 5) + * step : 4 + * long exposure reg range: + * min : 1 + * max : 2 * (vts - max sexp - 5) + * step : 4 + */ + u32IntTimeMaxTmp = ((2 * pstSnsState->au32FL[0] - 10) * 0x40) / (au32Ratio[0] + 0x40) / 4 * 4; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astSC200AI_State[ViPipe].u32Sexp_MAX * 2)) ? + (g_astSC200AI_State[ViPipe].u32Sexp_MAX * 2) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? u32ShortTimeMinLimit : u32IntTimeMaxTmp; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + /* [TODO] Convert to 1-line unit */ + u32IntTimeMaxTmp = (u32IntTimeMaxTmp - 1) / 2; + u32ShortTimeMinLimit = (u32ShortTimeMinLimit + 1) / 2; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + syslog(LOG_DEBUG, "ViPipe = %d ratio = %d, (%d, %d)\n", ViPipe, au32Ratio[0], + u32IntTimeMaxTmp, u32ShortTimeMinLimit); + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC200AI_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC200AI_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == SC200AI_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = SC200AI_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC200AI_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == SC200AI_MODE_1080P30) + pstSnsState->u8ImgMode = SC200AI_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astSC200AI_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "2to1 line WDR 1080p mode(60fps->30fps)\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC200AI_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc200ai_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc200ai_addr_byte; + pstI2c_data[i].u32DataByteNum = sc200ai_data_byte; + } + + //DOL 2t1 Mode Regs + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + //WDR Mode Regs + pstI2c_data[WDR2_SHS1_0_ADDR].u32RegAddr = SC200AI_SHS1_0_ADDR; + pstI2c_data[WDR2_SHS1_1_ADDR].u32RegAddr = SC200AI_SHS1_1_ADDR; + pstI2c_data[WDR2_SHS1_2_ADDR].u32RegAddr = SC200AI_SHS1_2_ADDR; + pstI2c_data[WDR2_SHS2_0_ADDR].u32RegAddr = SC200AI_SHS2_0_ADDR; + pstI2c_data[WDR2_SHS2_1_ADDR].u32RegAddr = SC200AI_SHS2_1_ADDR; + pstI2c_data[WDR2_SHS2_2_ADDR].u32RegAddr = SC200AI_SHS2_2_ADDR; + pstI2c_data[WDR2_AGAIN1_0_ADDR].u32RegAddr = SC200AI_AGAIN1_ADDR; + pstI2c_data[WDR2_AGAIN1_1_ADDR].u32RegAddr = SC200AI_AGAIN1_ADDR + 1; + pstI2c_data[WDR2_DGAIN1_0_ADDR].u32RegAddr = SC200AI_DGAIN1_ADDR; + pstI2c_data[WDR2_DGAIN1_1_ADDR].u32RegAddr = SC200AI_DGAIN1_ADDR + 1; + pstI2c_data[WDR2_AGAIN2_0_ADDR].u32RegAddr = SC200AI_AGAIN2_ADDR; + pstI2c_data[WDR2_AGAIN2_1_ADDR].u32RegAddr = SC200AI_AGAIN2_ADDR + 1; + pstI2c_data[WDR2_DGAIN2_0_ADDR].u32RegAddr = SC200AI_DGAIN2_ADDR; + pstI2c_data[WDR2_DGAIN2_1_ADDR].u32RegAddr = SC200AI_DGAIN2_ADDR + 1; + pstI2c_data[WDR2_VMAX_0_ADDR].u32RegAddr = SC200AI_VMAX_ADDR; + pstI2c_data[WDR2_VMAX_1_ADDR].u32RegAddr = SC200AI_VMAX_ADDR + 1; + pstI2c_data[WDR2_MAXSEXP_0_ADDR].u32RegAddr = SC200AI_MAXSEXP_ADDR; + pstI2c_data[WDR2_MAXSEXP_1_ADDR].u32RegAddr = SC200AI_MAXSEXP_ADDR + 1; + + break; + default: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC200AI_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC200AI_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC200AI_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC200AI_AGAIN1_ADDR; + pstI2c_data[LINEAR_AGAIN_1_ADDR].u32RegAddr = SC200AI_AGAIN1_ADDR + 1; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC200AI_DGAIN1_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC200AI_DGAIN1_ADDR + 1; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC200AI_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC200AI_VMAX_ADDR + 1; + + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC200AI_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC200AI_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (SC200AI_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC200AI_MODE_1080P30_WDR; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC200AI_MODE_S *pstMode = CVI_NULL; + + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC200AI_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC200AI_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC200AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc200ai_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC200AI_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC200AI_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc200ai_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc200ai_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc200ai_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc200ai_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC200AI_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC200AI_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC200AI_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC200AI_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC200AI_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC200AI_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC200AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC200AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC200AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC200AI_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC200AI_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC200AI_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc200ai_standby, + .pfnRestart = sc200ai_restart, + .pfnMirrorFlip = sc200ai_mirror_flip, + .pfnWriteReg = sc200ai_write_register, + .pfnReadReg = sc200ai_read_register, + .pfnSetBusInfo = sc200ai_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc200ai_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc200ai/sc200ai_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc200ai/sc200ai_cmos_ex.h new file mode 100644 index 000000000..07ce23225 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc200ai/sc200ai_cmos_ex.h @@ -0,0 +1,108 @@ +#ifndef __SC200AI_CMOS_EX_H_ +#define __SC200AI_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc200ai_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_2_ADDR, + LINEAR_AGAIN_0_ADDR, + LINEAR_AGAIN_1_ADDR, + LINEAR_DGAIN_0_ADDR, + LINEAR_DGAIN_1_ADDR, + LINEAR_VMAX_0_ADDR, + LINEAR_VMAX_1_ADDR, + LINEAR_REGS_NUM +}; + +enum sc200ai_dol2_regs_e { + WDR2_SHS1_0_ADDR, + WDR2_SHS1_1_ADDR, + WDR2_SHS1_2_ADDR, + WDR2_SHS2_0_ADDR, + WDR2_SHS2_1_ADDR, + WDR2_SHS2_2_ADDR, + WDR2_AGAIN1_0_ADDR, + WDR2_AGAIN1_1_ADDR, + WDR2_DGAIN1_0_ADDR, + WDR2_DGAIN1_1_ADDR, + WDR2_AGAIN2_0_ADDR, + WDR2_AGAIN2_1_ADDR, + WDR2_DGAIN2_0_ADDR, + WDR2_DGAIN2_1_ADDR, + WDR2_VMAX_0_ADDR, + WDR2_VMAX_1_ADDR, + WDR2_MAXSEXP_0_ADDR, + WDR2_MAXSEXP_1_ADDR, + WDR2_REGS_NUM +}; + +typedef enum _SC200AI_MODE_E { + SC200AI_MODE_1080P30 = 0, + SC200AI_MODE_LINEAR_NUM, + SC200AI_MODE_1080P30_WDR = SC200AI_MODE_LINEAR_NUM, + SC200AI_MODE_NUM +} SC200AI_MODE_E; + +typedef struct _SC200AI_STATE_S { + CVI_U32 u32Sexp_MAX; /* (2*{16’h3e23,16’h3e24} – 'd10)/2 */ +} SC200AI_STATE_S; + +typedef struct _SC200AI_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16SexpMaxReg; /* {16’h3e23,16’h3e24} */ + char name[64]; +} SC200AI_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC200AI[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC200AI_BusInfo[]; +extern CVI_U16 g_au16SC200AI_GainMode[]; +extern CVI_U16 g_au16SC200AI_L2SMode[]; +extern const CVI_U8 sc200ai_i2c_addr; +extern const CVI_U32 sc200ai_addr_byte; +extern const CVI_U32 sc200ai_data_byte; +extern void sc200ai_init(VI_PIPE ViPipe); +extern void sc200ai_exit(VI_PIPE ViPipe); +extern void sc200ai_standby(VI_PIPE ViPipe); +extern void sc200ai_restart(VI_PIPE ViPipe); +extern int sc200ai_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc200ai_read_register(VI_PIPE ViPipe, int addr); +extern void sc200ai_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc200ai_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC200AI_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc200ai/sc200ai_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc200ai/sc200ai_cmos_param.h new file mode 100644 index 000000000..1a02c07e5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc200ai/sc200ai_cmos_param.h @@ -0,0 +1,265 @@ +#ifndef __SC200AI_CMOS_PARAM_H_ +#define __SC200AI_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc200ai_cmos_ex.h" + +static const SC200AI_MODE_S g_astSC200AI_mode[SC200AI_MODE_NUM] = { + [SC200AI_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.03, /* 1125 * 30 / 0x7FFF*/ + .u32HtsDef = 2560, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1121, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 4096, + .u16Def = 1024, + .u16Step = 1, + }, + }, + [SC200AI_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.06, /* 2250 * 30 / 0x7FFF*/ + .u32HtsDef = 640, + .u32VtsDef = 2250, + .u16SexpMaxReg = 0x13E, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.02792946062982082367, 3.36534714698791503906}, //B: slope, intercept + {0.02071751467883586884, 5.34583568572998046875}, //Gb: slope, intercept + {0.02110148966312408447, 5.02954530715942382813}, //Gr: slope, intercept + {0.02168512716889381409, 4.89776754379272460938}, //R: slope, intercept + }, + { //iso 200 + {0.03194080293178558350, 5.61192893981933593750}, //B: slope, intercept + {0.02428408525884151459, 7.94834280014038085938}, //Gb: slope, intercept + {0.02499442733824253082, 7.72430133819580078125}, //Gr: slope, intercept + {0.02584112435579299927, 7.20574426651000976563}, //R: slope, intercept + }, + { //iso 400 + {0.04612467437982559204, 6.88752269744873046875}, //B: slope, intercept + {0.03022909909486770630, 11.05101776123046875000}, //Gb: slope, intercept + {0.03175539523363113403, 10.60332489013671875000}, //Gr: slope, intercept + {0.03522306308150291443, 9.36425399780273437500}, //R: slope, intercept + }, + { //iso 800 + {0.06092500314116477966, 9.79670524597167968750}, //B: slope, intercept + {0.03984217345714569092, 15.30182266235351562500}, //Gb: slope, intercept + {0.04019560664892196655, 14.93132972717285156250}, //Gr: slope, intercept + {0.04470816254615783691, 13.26843166351318359375}, //R: slope, intercept + }, + { //iso 1600 + {0.08295634388923645020, 14.20334625244140625000}, //B: slope, intercept + {0.05075264349579811096, 20.99221038818359375000}, //Gb: slope, intercept + {0.05426201224327087402, 20.08068656921386718750}, //Gr: slope, intercept + {0.05945669487118721008, 19.02898788452148437500}, //R: slope, intercept + }, + { //iso 3200 + {0.09782519936561584473, 21.84967994689941406250}, //B: slope, intercept + {0.06690908223390579224, 26.53993988037109375000}, //Gb: slope, intercept + {0.06954573839902877808, 25.74129104614257812500}, //Gr: slope, intercept + {0.09061723947525024414, 22.98998260498046875000}, //R: slope, intercept + }, + { //iso 6400 + {0.14311420917510986328, 28.96467971801757812500}, //B: slope, intercept + {0.08148498833179473877, 37.93062591552734375000}, //Gb: slope, intercept + {0.08273542672395706177, 38.37096405029296875000}, //Gr: slope, intercept + {0.12093253433704376221, 33.31475067138671875000}, //R: slope, intercept + }, + { //iso 12800 + {0.17958122491836547852, 43.49506759643554687500}, //B: slope, intercept + {0.09839969873428344727, 55.43268966674804687500}, //Gb: slope, intercept + {0.10201884806156158447, 52.97607040405273437500}, //Gr: slope, intercept + {0.15302789211273193359, 47.54779434204101562500}, //R: slope, intercept + }, + { //iso 25600 + {0.25833165645599365234, 56.96470642089843750000}, //B: slope, intercept + {0.13260601460933685303, 74.69016265869140625000}, //Gb: slope, intercept + {0.14035490155220031738, 75.44366455078125000000}, //Gr: slope, intercept + {0.23465165495872497559, 60.52228164672851562500}, //R: slope, intercept + }, + { //iso 51200 + {0.37595292925834655762, 78.54853057861328125000}, //B: slope, intercept + {0.21475413441658020020, 102.12300872802734375000}, //Gb: slope, intercept + {0.20840260386466979980, 103.65763854980468750000}, //Gr: slope, intercept + {0.34428051114082336426, 87.83551025390625000000}, //R: slope, intercept + }, + { //iso 102400 + {0.51122575998306274414, 113.49224090576171875000}, //B: slope, intercept + {0.29245173931121826172, 154.26939392089843750000}, //Gb: slope, intercept + {0.31501635909080505371, 148.29017639160156250000}, //Gr: slope, intercept + {0.47034618258476257324, 124.06208038330078125000}, //R: slope, intercept + }, + { //iso 204800 + {0.67213481664657592773, 134.71751403808593750000}, //B: slope, intercept + {0.40368056297302246094, 189.80801391601562500000}, //Gb: slope, intercept + {0.43581819534301757813, 186.44682312011718750000}, //Gr: slope, intercept + {0.60127359628677368164, 160.66384887695312500000}, //R: slope, intercept + }, + { //iso 409600 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 819200 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {257, 260, 260, 260, 260, 261, 259, 258, /*8*/255, 248, 264, 300, 291, 310, 310, 311}, + {257, 260, 260, 260, 260, 261, 259, 257, /*8*/254, 247, 261, 296, 287, 309, 309, 306}, + {257, 260, 260, 260, 260, 261, 259, 257, /*8*/255, 248, 262, 298, 289, 308, 308, 308}, + {257, 260, 260, 260, 260, 261, 259, 258, /*8*/255, 247, 261, 301, 293, 310, 308, 314}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1095, 1105, 1102, 1108, 1108, 1108}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1104, 1101, 1108, 1108, 1107}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1104, 1102, 1107, 1107, 1107}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1105, 1103, 1108, 1107, 1109}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc200ai_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 0, 4, -1, -1}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + .dphy = { + .enable = 1, + .hs_settle = 8, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC200AI_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc200ai/sc200ai_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc200ai/sc200ai_sensor_ctl.c new file mode 100644 index 000000000..d38ca7396 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc200ai/sc200ai_sensor_ctl.c @@ -0,0 +1,511 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc200ai_cmos_ex.h" + +static void sc200ai_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void sc200ai_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc200ai_i2c_addr = 0x30; /* I2C Address of SC200AI */ +const CVI_U32 sc200ai_addr_byte = 2; +const CVI_U32 sc200ai_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc200ai_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC200AI_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc200ai_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc200ai_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc200ai_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc200ai_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc200ai_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc200ai_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc200ai_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc200ai_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc200ai_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc200ai_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc200ai_addr_byte + sc200ai_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc200ai_standby(VI_PIPE ViPipe) +{ + sc200ai_write_register(ViPipe, 0x0100, 0x00); +} + +void sc200ai_restart(VI_PIPE ViPipe) +{ + sc200ai_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc200ai_write_register(ViPipe, 0x0100, 0x01); +} + +void sc200ai_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC200AI[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc200ai_write_register(ViPipe, + g_pastSC200AI[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC200AI[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC200AI_CHIP_ID_HI_ADDR 0x3107 +#define SC200AI_CHIP_ID_LO_ADDR 0x3108 +#define SC200AI_CHIP_ID 0xcb1c + +void sc200ai_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc200ai_write_register(ViPipe, 0x3221, val); +} + +int sc200ai_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + delay_ms(4); + if (sc200ai_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc200ai_read_register(ViPipe, SC200AI_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc200ai_read_register(ViPipe, SC200AI_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC200AI_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc200ai_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + CVI_U8 u8ImgMode; + + bInit = g_pastSC200AI[ViPipe]->bInit; + enWDRMode = g_pastSC200AI[ViPipe]->enWDRMode; + u8ImgMode = g_pastSC200AI[ViPipe]->u8ImgMode; + + sc200ai_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == SC200AI_MODE_1080P30_WDR) { + /* SC200AI_MODE_1080P30_WDR */ + sc200ai_wdr_1080p30_2to1_init(ViPipe); + } else { + } + } else { + sc200ai_linear_1080p30_init(ViPipe); + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == SC200AI_MODE_1080P30_WDR) { + /* SC200AI_MODE_1080P30_WDR */ + sc200ai_wdr_1080p30_2to1_init(ViPipe); + } else { + } + } else { + sc200ai_linear_1080p30_init(ViPipe); + } + } + g_pastSC200AI[ViPipe]->bInit = CVI_TRUE; +} + +void sc200ai_exit(VI_PIPE ViPipe) +{ + sc200ai_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void sc200ai_linear_1080p30_init(VI_PIPE ViPipe) +{ + sc200ai_write_register(ViPipe, 0x0103, 0x01); + sc200ai_write_register(ViPipe, 0x0100, 0x00); + sc200ai_write_register(ViPipe, 0x36e9, 0x80); + sc200ai_write_register(ViPipe, 0x36f9, 0x80); + sc200ai_write_register(ViPipe, 0x59e0, 0x60); + sc200ai_write_register(ViPipe, 0x59e1, 0x08); + sc200ai_write_register(ViPipe, 0x59e2, 0x3f); + sc200ai_write_register(ViPipe, 0x59e3, 0x18); + sc200ai_write_register(ViPipe, 0x59e4, 0x18); + sc200ai_write_register(ViPipe, 0x59e5, 0x3f); + sc200ai_write_register(ViPipe, 0x59e6, 0x06); + sc200ai_write_register(ViPipe, 0x59e7, 0x02); + sc200ai_write_register(ViPipe, 0x59e8, 0x38); + sc200ai_write_register(ViPipe, 0x59e9, 0x10); + sc200ai_write_register(ViPipe, 0x59ea, 0x0c); + sc200ai_write_register(ViPipe, 0x59eb, 0x10); + sc200ai_write_register(ViPipe, 0x59ec, 0x04); + sc200ai_write_register(ViPipe, 0x59ed, 0x02); + sc200ai_write_register(ViPipe, 0x59ee, 0xa0); + sc200ai_write_register(ViPipe, 0x59ef, 0x08); + sc200ai_write_register(ViPipe, 0x59f4, 0x18); + sc200ai_write_register(ViPipe, 0x59f5, 0x10); + sc200ai_write_register(ViPipe, 0x59f6, 0x0c); + sc200ai_write_register(ViPipe, 0x59f7, 0x10); + sc200ai_write_register(ViPipe, 0x59f8, 0x06); + sc200ai_write_register(ViPipe, 0x59f9, 0x02); + sc200ai_write_register(ViPipe, 0x59fa, 0x18); + sc200ai_write_register(ViPipe, 0x59fb, 0x10); + sc200ai_write_register(ViPipe, 0x59fc, 0x0c); + sc200ai_write_register(ViPipe, 0x59fd, 0x10); + sc200ai_write_register(ViPipe, 0x59fe, 0x04); + sc200ai_write_register(ViPipe, 0x59ff, 0x02); + sc200ai_write_register(ViPipe, 0x3e16, 0x00); + sc200ai_write_register(ViPipe, 0x3e17, 0x80); + sc200ai_write_register(ViPipe, 0x3f09, 0x48); + sc200ai_write_register(ViPipe, 0x3e01, 0x8c); + sc200ai_write_register(ViPipe, 0x3e02, 0x20); + sc200ai_write_register(ViPipe, 0x391f, 0x18); + sc200ai_write_register(ViPipe, 0x363a, 0x1f); + sc200ai_write_register(ViPipe, 0x3637, 0x1b); + sc200ai_write_register(ViPipe, 0x391d, 0x14); + sc200ai_write_register(ViPipe, 0x330b, 0x88); + sc200ai_write_register(ViPipe, 0x3908, 0x41); + sc200ai_write_register(ViPipe, 0x3333, 0x10); + sc200ai_write_register(ViPipe, 0x3301, 0x20); + sc200ai_write_register(ViPipe, 0x3304, 0x40); + sc200ai_write_register(ViPipe, 0x331e, 0x39); + sc200ai_write_register(ViPipe, 0x330f, 0x02); + sc200ai_write_register(ViPipe, 0x3306, 0x32); + sc200ai_write_register(ViPipe, 0x363c, 0x0e); + sc200ai_write_register(ViPipe, 0x363b, 0xc6); + sc200ai_write_register(ViPipe, 0x3622, 0x16); + sc200ai_write_register(ViPipe, 0x5787, 0x10); + sc200ai_write_register(ViPipe, 0x5788, 0x06); + sc200ai_write_register(ViPipe, 0x578a, 0x10); + sc200ai_write_register(ViPipe, 0x578b, 0x06); + sc200ai_write_register(ViPipe, 0x5790, 0x10); + sc200ai_write_register(ViPipe, 0x5791, 0x10); + sc200ai_write_register(ViPipe, 0x5792, 0x00); + sc200ai_write_register(ViPipe, 0x5793, 0x10); + sc200ai_write_register(ViPipe, 0x5794, 0x10); + sc200ai_write_register(ViPipe, 0x5795, 0x00); + sc200ai_write_register(ViPipe, 0x5799, 0x00); + sc200ai_write_register(ViPipe, 0x57c7, 0x10); + sc200ai_write_register(ViPipe, 0x57c8, 0x06); + sc200ai_write_register(ViPipe, 0x57ca, 0x10); + sc200ai_write_register(ViPipe, 0x57cb, 0x06); + sc200ai_write_register(ViPipe, 0x57d1, 0x10); + sc200ai_write_register(ViPipe, 0x57d4, 0x10); + sc200ai_write_register(ViPipe, 0x57d9, 0x00); + sc200ai_write_register(ViPipe, 0x369c, 0x40); + sc200ai_write_register(ViPipe, 0x369d, 0x48); + sc200ai_write_register(ViPipe, 0x3690, 0x34); + sc200ai_write_register(ViPipe, 0x3691, 0x33); + sc200ai_write_register(ViPipe, 0x3692, 0x44); + sc200ai_write_register(ViPipe, 0x3670, 0x0a); + sc200ai_write_register(ViPipe, 0x367c, 0x48); + sc200ai_write_register(ViPipe, 0x367d, 0x58); + sc200ai_write_register(ViPipe, 0x3674, 0x82); + sc200ai_write_register(ViPipe, 0x3675, 0x76); + sc200ai_write_register(ViPipe, 0x3676, 0x78); + sc200ai_write_register(ViPipe, 0x3253, 0x08); + sc200ai_write_register(ViPipe, 0x301f, 0x03); + sc200ai_write_register(ViPipe, 0x36e9, 0x20); + sc200ai_write_register(ViPipe, 0x36f9, 0x27); + + sc200ai_default_reg_init(ViPipe); + + sc200ai_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC200AI 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +static void sc200ai_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + sc200ai_write_register(ViPipe, 0x0103, 0x01); + sc200ai_write_register(ViPipe, 0x0100, 0x00); + sc200ai_write_register(ViPipe, 0x36e9, 0x80); + sc200ai_write_register(ViPipe, 0x36f9, 0x80); + sc200ai_write_register(ViPipe, 0x59e0, 0x60); + sc200ai_write_register(ViPipe, 0x59e1, 0x08); + sc200ai_write_register(ViPipe, 0x59e2, 0x3f); + sc200ai_write_register(ViPipe, 0x59e3, 0x18); + sc200ai_write_register(ViPipe, 0x59e4, 0x18); + sc200ai_write_register(ViPipe, 0x59e5, 0x3f); + sc200ai_write_register(ViPipe, 0x59e6, 0x06); + sc200ai_write_register(ViPipe, 0x59e7, 0x02); + sc200ai_write_register(ViPipe, 0x59e8, 0x38); + sc200ai_write_register(ViPipe, 0x59e9, 0x10); + sc200ai_write_register(ViPipe, 0x59ea, 0x0c); + sc200ai_write_register(ViPipe, 0x59eb, 0x10); + sc200ai_write_register(ViPipe, 0x59ec, 0x04); + sc200ai_write_register(ViPipe, 0x59ed, 0x02); + sc200ai_write_register(ViPipe, 0x59ee, 0xa0); + sc200ai_write_register(ViPipe, 0x59ef, 0x08); + sc200ai_write_register(ViPipe, 0x59f4, 0x18); + sc200ai_write_register(ViPipe, 0x59f5, 0x10); + sc200ai_write_register(ViPipe, 0x59f6, 0x0c); + sc200ai_write_register(ViPipe, 0x59f7, 0x10); + sc200ai_write_register(ViPipe, 0x59f8, 0x06); + sc200ai_write_register(ViPipe, 0x59f9, 0x02); + sc200ai_write_register(ViPipe, 0x59fa, 0x18); + sc200ai_write_register(ViPipe, 0x59fb, 0x10); + sc200ai_write_register(ViPipe, 0x59fc, 0x0c); + sc200ai_write_register(ViPipe, 0x59fd, 0x10); + sc200ai_write_register(ViPipe, 0x59fe, 0x04); + sc200ai_write_register(ViPipe, 0x59ff, 0x02); + sc200ai_write_register(ViPipe, 0x3e16, 0x00); + sc200ai_write_register(ViPipe, 0x3e17, 0x80); + sc200ai_write_register(ViPipe, 0x3f09, 0x48); + sc200ai_write_register(ViPipe, 0x391f, 0x10); + sc200ai_write_register(ViPipe, 0x363a, 0x1f); + sc200ai_write_register(ViPipe, 0x3908, 0x41); + sc200ai_write_register(ViPipe, 0x330d, 0x16); + sc200ai_write_register(ViPipe, 0x3302, 0x0c); + sc200ai_write_register(ViPipe, 0x3303, 0x08); + sc200ai_write_register(ViPipe, 0x3308, 0x10); + sc200ai_write_register(ViPipe, 0x3310, 0x02); + sc200ai_write_register(ViPipe, 0x334c, 0x08); + sc200ai_write_register(ViPipe, 0x330f, 0x02); + sc200ai_write_register(ViPipe, 0x330e, 0x1c); + sc200ai_write_register(ViPipe, 0x331c, 0x04); + sc200ai_write_register(ViPipe, 0x3320, 0x07); + sc200ai_write_register(ViPipe, 0x33ac, 0x08); + sc200ai_write_register(ViPipe, 0x33ae, 0x10); + sc200ai_write_register(ViPipe, 0x3356, 0x09); + sc200ai_write_register(ViPipe, 0x33af, 0x19); + sc200ai_write_register(ViPipe, 0x3333, 0x10); + sc200ai_write_register(ViPipe, 0x3622, 0x16); + sc200ai_write_register(ViPipe, 0x3630, 0xa0); + sc200ai_write_register(ViPipe, 0x36eb, 0x0c); + sc200ai_write_register(ViPipe, 0x36ec, 0x0c); + sc200ai_write_register(ViPipe, 0x36fd, 0x14); + sc200ai_write_register(ViPipe, 0x5787, 0x10); + sc200ai_write_register(ViPipe, 0x5788, 0x06); + sc200ai_write_register(ViPipe, 0x578a, 0x10); + sc200ai_write_register(ViPipe, 0x578b, 0x06); + sc200ai_write_register(ViPipe, 0x5790, 0x10); + sc200ai_write_register(ViPipe, 0x5791, 0x10); + sc200ai_write_register(ViPipe, 0x5792, 0x00); + sc200ai_write_register(ViPipe, 0x5793, 0x10); + sc200ai_write_register(ViPipe, 0x5794, 0x10); + sc200ai_write_register(ViPipe, 0x5795, 0x00); + sc200ai_write_register(ViPipe, 0x5799, 0x00); + sc200ai_write_register(ViPipe, 0x57c7, 0x10); + sc200ai_write_register(ViPipe, 0x57c8, 0x06); + sc200ai_write_register(ViPipe, 0x57ca, 0x10); + sc200ai_write_register(ViPipe, 0x57cb, 0x06); + sc200ai_write_register(ViPipe, 0x57d1, 0x10); + sc200ai_write_register(ViPipe, 0x57d4, 0x10); + sc200ai_write_register(ViPipe, 0x57d9, 0x00); + sc200ai_write_register(ViPipe, 0x3364, 0x17); + sc200ai_write_register(ViPipe, 0x3390, 0x08); + sc200ai_write_register(ViPipe, 0x3391, 0x18); + sc200ai_write_register(ViPipe, 0x3392, 0x38); + sc200ai_write_register(ViPipe, 0x3301, 0x06); + sc200ai_write_register(ViPipe, 0x3393, 0x06); + sc200ai_write_register(ViPipe, 0x3394, 0x06); + sc200ai_write_register(ViPipe, 0x3395, 0x06); + sc200ai_write_register(ViPipe, 0x3396, 0x08); + sc200ai_write_register(ViPipe, 0x3397, 0x18); + sc200ai_write_register(ViPipe, 0x3398, 0x38); + sc200ai_write_register(ViPipe, 0x3399, 0x06); + sc200ai_write_register(ViPipe, 0x339a, 0x0a); + sc200ai_write_register(ViPipe, 0x339b, 0x10); + sc200ai_write_register(ViPipe, 0x339c, 0x20); + sc200ai_write_register(ViPipe, 0x369c, 0x40); + sc200ai_write_register(ViPipe, 0x369d, 0x48); + sc200ai_write_register(ViPipe, 0x3690, 0x34); + sc200ai_write_register(ViPipe, 0x3691, 0x33); + sc200ai_write_register(ViPipe, 0x3692, 0x44); + sc200ai_write_register(ViPipe, 0x3670, 0x0a); + sc200ai_write_register(ViPipe, 0x367c, 0x48); + sc200ai_write_register(ViPipe, 0x367d, 0x58); + sc200ai_write_register(ViPipe, 0x3674, 0x82); + sc200ai_write_register(ViPipe, 0x3675, 0x76); + sc200ai_write_register(ViPipe, 0x3676, 0x78); + sc200ai_write_register(ViPipe, 0x3637, 0x36); + sc200ai_write_register(ViPipe, 0x3304, 0x60); + sc200ai_write_register(ViPipe, 0x3309, 0x70); + sc200ai_write_register(ViPipe, 0x331e, 0x51); + sc200ai_write_register(ViPipe, 0x331f, 0x61); + sc200ai_write_register(ViPipe, 0x3306, 0x30); + sc200ai_write_register(ViPipe, 0x330b, 0x80); + sc200ai_write_register(ViPipe, 0x363c, 0x0e); + sc200ai_write_register(ViPipe, 0x363b, 0xc6); + sc200ai_write_register(ViPipe, 0x3253, 0x08); + sc200ai_write_register(ViPipe, 0x3220, 0x53); + sc200ai_write_register(ViPipe, 0x3250, 0x3f); + sc200ai_write_register(ViPipe, 0x320e, 0x08); + sc200ai_write_register(ViPipe, 0x320f, 0xca); + sc200ai_write_register(ViPipe, 0x4816, 0xb1); + sc200ai_write_register(ViPipe, 0x3e00, 0x01); + sc200ai_write_register(ViPipe, 0x3e01, 0x06); + sc200ai_write_register(ViPipe, 0x3e02, 0x00); + sc200ai_write_register(ViPipe, 0x3e04, 0x10); + sc200ai_write_register(ViPipe, 0x3e05, 0x60); + sc200ai_write_register(ViPipe, 0x3e06, 0x00); + sc200ai_write_register(ViPipe, 0x3e07, 0x80); + sc200ai_write_register(ViPipe, 0x3e08, 0x03); + sc200ai_write_register(ViPipe, 0x3e09, 0x40); + sc200ai_write_register(ViPipe, 0x3e10, 0x00); + sc200ai_write_register(ViPipe, 0x3e11, 0x80); + sc200ai_write_register(ViPipe, 0x3e12, 0x03); + sc200ai_write_register(ViPipe, 0x3e13, 0x40); + sc200ai_write_register(ViPipe, 0x3e23, 0x00); + sc200ai_write_register(ViPipe, 0x3e24, 0x88); + sc200ai_write_register(ViPipe, 0x301f, 0x02); + sc200ai_write_register(ViPipe, 0x36e9, 0x20); + sc200ai_write_register(ViPipe, 0x36f9, 0x24); + + sc200ai_default_reg_init(ViPipe); + + sc200ai_write_register(ViPipe, 0x0100, 0x01); + + delay_ms(50); + + printf("===SC200AI sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc2335/Makefile b/middleware/v2/component/isp/sensor/cv181x/sms_sc2335/Makefile new file mode 100644 index 000000000..8bd9dde45 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc2335/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc2335.a +TARGET_SO = $(MW_LIB)/libsns_sc2335.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc2335/sc2335_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc2335/sc2335_cmos.c new file mode 100644 index 000000000..b618ef02c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc2335/sc2335_cmos.c @@ -0,0 +1,1058 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" + +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc2335_cmos_ex.h" +#include "sc2335_cmos_param.h" + + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC2335_ID 2335 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC2335[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC2335_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC2335[dev]) +#define SC2335_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC2335[dev] = pstCtx) +#define SC2335_SENSOR_RESET_CTX(dev) (g_pastSC2335[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC2335_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC2335_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC2335_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc2335_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC2335 Lines Range*****/ +#define SC2335_FULL_LINES_MAX (0x7FFF) + +/*****SC2335 Register Address*****/ +#define SC2335_EXP_H_ADDR (0x3e00) +#define SC2335_EXP_M_ADDR (0x3e01) +#define SC2335_EXP_L_ADDR (0x3e02) + +#define SC2335_AGAIN_H_ADDR (0x3e08) +#define SC2335_AGAIN_L_ADDR (0x3e09) + +#define SC2335_DGAIN_H_ADDR (0x3e06) +#define SC2335_DGAIN_L_ADDR (0x3e07) + +#define SC2335_VMAX_H_ADDR (0x320e) +#define SC2335_VMAX_L_ADDR (0x320f) + +#define SC2335_GAIN_LOGIC_ADDR (0x363c) + +#define SC2335_GAIN_DPC_ADDR (0x5799) +#define SC2335_HOLD_ADDR (0x3812) + +#define SC2335_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +#define SC2335_EXPACCURACY (0.5) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC2335_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC2335_mode[pstSnsState->u8ImgMode]; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC2335_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC2335_EXPACCURACY; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = pstAeSnsDft->u32MaxIntTime; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC2335_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC2335_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC2335_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC2335_MODE_1920X1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC2335_FULL_LINES_MAX) ? SC2335_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = 2 * pstSnsState->u32FLStd - 10; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 3 + * max : 2 * vts - 10 + * step : 1 + */ + u32MinTime = 3; + u32MaxTime = 2 * pstSnsState->au32FL[0] - 10; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_M_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_ADDR].u32Data = ((u32TmpIntTime & 0x000F) << 4); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +typedef struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} gain_tbl_info_s; + +static struct gain_tbl_info_s AgainInfo[4] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x03, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x07, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 8128, + .idxBase = 128, + .regGain = 0x0F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 16256, + .idxBase = 192, + .regGain = 0x1F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, +}; +static CVI_U32 Again_table[256] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, 1248, 1263, 1280, + 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, 1472, 1487, 1504, 1519, 1536, 1552, + 1567, 1584, 1600, 1615, 1632, 1647, 1664, 1680, 1695, 1712, 1728, 1743, 1760, 1775, 1792, 1808, 1823, + 1840, 1856, 1871, 1888, 1903, 1920, 1936, 1951, 1968, 1984, 1999, 2016, 2031, 2048, 2079, 2112, 2144, + 2176, 2207, 2240, 2272, 2304, 2335, 2368, 2400, 2432, 2463, 2496, 2528, 2560, 2591, 2624, 2656, 2688, + 2719, 2752, 2784, 2816, 2847, 2880, 2912, 2944, 2975, 3008, 3040, 3072, 3103, 3136, 3168, 3200, 3231, + 3264, 3296, 3328, 3359, 3392, 3424, 3456, 3487, 3520, 3552, 3584, 3615, 3648, 3680, 3712, 3743, 3776, + 3808, 3840, 3871, 3904, 3936, 3968, 3999, 4032, 4064, 4096, 4160, 4224, 4288, 4352, 4416, 4480, 4544, + 4608, 4672, 4736, 4800, 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, 5504, 5568, 5632, + 5696, 5760, 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, 6464, 6528, 6592, 6656, 6720, + 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, 7424, 7488, 7552, 7616, 7680, 7744, 7808, + 7872, 7936, 8000, 8064, 8128, 8192, 8320, 8448, 8576, 8704, 8832, 8960, 9088, 9216, 9344, 9472, 9600, + 9728, 9856, 9984, 10112, 10240, 10368, 10496, 10624, 10752, 10880, 11008, 11136, 11264, 11392, 11520, + 11648, 11776, 11904, 12032, 12160, 12288, 12416, 12544, 12672, 12800, 12928, 13056, 13184, 13312, 13440, + 13568, 13696, 13824, 13952, 14080, 14208, 14336, 14464, 14592, 14720, 14848, 14976, 15104, 15232, 15360, + 15488, 15616, 15744, 15872, 16000, 16128, 16256 +}; + +static struct gain_tbl_info_s DgainInfo[5] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 8128, + .idxBase = 128, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 16256, + .idxBase = 192, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 32512, + .idxBase = 256, + .regGain = 0x0F, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, +}; + +static CVI_U32 Dgain_table[320] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, 1248, + 1263, 1280, 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, 1472, 1487, + 1504, 1519, 1536, 1552, 1567, 1584, 1600, 1615, 1632, 1647, 1664, 1680, 1695, 1712, 1728, + 1743, 1760, 1775, 1792, 1808, 1823, 1840, 1856, 1871, 1888, 1903, 1920, 1936, 1951, 1968, + 1984, 1999, 2016, 2031, 2048, 2079, 2112, 2144, 2176, 2207, 2240, 2272, 2304, 2335, 2368, + 2400, 2432, 2463, 2496, 2528, 2560, 2591, 2624, 2656, 2688, 2719, 2752, 2784, 2816, 2847, + 2880, 2912, 2944, 2975, 3008, 3040, 3072, 3103, 3136, 3168, 3200, 3231, 3264, 3296, 3328, + 3359, 3392, 3424, 3456, 3487, 3520, 3552, 3584, 3615, 3648, 3680, 3712, 3743, 3776, 3808, + 3840, 3871, 3904, 3936, 3968, 3999, 4032, 4064, 4096, 4160, 4224, 4288, 4352, 4416, 4480, + 4544, 4608, 4672, 4736, 4800, 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, + 5504, 5568, 5632, 5696, 5760, 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, + 6464, 6528, 6592, 6656, 6720, 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, + 7424, 7488, 7552, 7616, 7680, 7744, 7808, 7872, 7936, 8000, 8064, 8128, 8192, 8320, 8448, + 8576, 8704, 8832, 8960, 9088, 9216, 9344, 9472, 9600, 9728, 9856, 9984, 10112, 10240, 10368, + 10496, 10624, 10752, 10880, 11008, 11136, 11264, 11392, 11520, 11648, 11776, 11904, 12032, + 12160, 12288, 12416, 12544, 12672, 12800, 12928, 13056, 13184, 13312, 13440, 13568, 13696, + 13824, 13952, 14080, 14208, 14336, 14464, 14592, 14720, 14848, 14976, 15104, 15232, 15360, + 15488, 15616, 15744, 15872, 16000, 16128, 16256, 16384, 16640, 16896, 17152, 17408, 17664, + 17920, 18176, 18432, 18688, 18944, 19200, 19456, 19712, 19968, 20224, 20480, 20736, 20992, + 21248, 21504, 21760, 22016, 22272, 22528, 22784, 23040, 23296, 23552, 23808, 24064, 24320, + 24576, 24832, 25088, 25344, 25600, 25856, 26112, 26368, 26624, 26880, 27136, 27392, 27648, + 27904, 28160, 28416, 28672, 28928, 29184, 29440, 29696, 29952, 30208, 30464, 30720, 30976, + 31232, 31488, 31744, 32000, 32256, 32512 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[255]) { + *pu32AgainLin = Again_table[255]; + *pu32AgainDb = 255; + return CVI_SUCCESS; + } + + for (i = 1; i < 256; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[319]) { + *pu32DgainLin = Dgain_table[319]; + *pu32DgainDb = 319; + return CVI_SUCCESS; + } + + for (i = 1; i < 320; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L_ADDR].u32Data = (u32Again & 0xFF); + + if (info->regGain < 0x07) { //gain < 2x + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_ADDR].u32Data = 0x0e; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } else { //2x <= gain + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_ADDR].u32Data = 0x07; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } + if (sc2335_read_register(ViPipe, 0x3040) == 0x41) { + if (info->regGain < 0x07) { //gain < 2x + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_ADDR].u32Data = 0x0f; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } else { //2x <= gain + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_ADDR].u32Data = 0x07; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } + } else { + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_ADDR].u32Data = 0x07; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } + /* gain DPC setting. */ + if ((info->regGain > 0x1F) || ((info->regGain == 0x1F) && (u32Again == 0x7F))) { //gain >= 15.875 + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_DPC_ADDR].u32Data = 0x07; + } else if ((info->regGain < 0x1F) || ((info->regGain == 0x1F) && (u32Again <= 0x50))) { //gain <= 10x + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_DPC_ADDR].u32Data = 0x00; + } + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L_ADDR].u32Data = (u32Dgain & 0xFF); + + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC2335_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC2335_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC2335_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC2335_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC2335_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc2335_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc2335_addr_byte; + pstI2c_data[i].u32DataByteNum = sc2335_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC2335_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_M_ADDR].u32RegAddr = SC2335_EXP_M_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC2335_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H_ADDR].u32RegAddr = SC2335_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L_ADDR].u32RegAddr = SC2335_AGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC2335_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC2335_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC2335_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC2335_VMAX_L_ADDR; + pstI2c_data[LINEAR_HOLD].u32RegAddr = SC2335_HOLD_ADDR; + pstI2c_data[LINEAR_GAIN_LOGIC_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_LOGIC_ADDR].u32RegAddr = SC2335_GAIN_LOGIC_ADDR; + pstI2c_data[LINEAR_GAIN_DPC_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_DPC_ADDR].u32RegAddr = SC2335_GAIN_DPC_ADDR; + pstI2c_data[LINEAR_REL].u32RegAddr = SC2335_HOLD_ADDR; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update group hold or not*/ + if (pstCfg0->snsCfg.astI2cData[LINEAR_GAIN_LOGIC_ADDR].bUpdate == CVI_TRUE) { + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + /* DPC updata when A/Dgain change */ + if ((pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H_ADDR].bUpdate == CVI_TRUE) + || (pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L_ADDR].bUpdate == CVI_TRUE) + || (pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H_ADDR].bUpdate == CVI_TRUE) + || (pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L_ADDR].bUpdate == CVI_TRUE)) { + pstI2c_data[LINEAR_GAIN_DPC_ADDR].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_HOLD].u32Data = 0x00; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0x30; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC2335_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC2335_MODE_1920X1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeSc2335_MirrorFip[ViPipe] != eSnsMirrorFlip) { + sc2335_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeSc2335_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC2335_MODE_S *pstMode = CVI_NULL; + + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC2335_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC2335_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc2335_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC2335_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC2335_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc2335_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc2335_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc2335_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc2335_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC2335_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC2335_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC2335_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC2335_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC2335_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC2335_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC2335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC2335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC2335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC2335_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC2335_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC2335_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc2335_standby, + .pfnRestart = sc2335_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = sc2335_write_register, + .pfnReadReg = sc2335_read_register, + .pfnSetBusInfo = sc2335_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc2335_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc2335/sc2335_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc2335/sc2335_cmos_ex.h new file mode 100644 index 000000000..d2b7d2246 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc2335/sc2335_cmos_ex.h @@ -0,0 +1,84 @@ +#ifndef __SC2335_CMOS_EX_H_ +#define __SC2335_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc2335_linear_regs_e { + LINEAR_EXP_H_ADDR, + LINEAR_EXP_M_ADDR, + LINEAR_EXP_L_ADDR, + LINEAR_AGAIN_H_ADDR, + LINEAR_AGAIN_L_ADDR, + LINEAR_DGAIN_H_ADDR, + LINEAR_DGAIN_L_ADDR, + LINEAR_VMAX_H_ADDR, + LINEAR_VMAX_L_ADDR, + LINEAR_HOLD, + LINEAR_GAIN_LOGIC_ADDR, + LINEAR_GAIN_DPC_ADDR, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +typedef enum _SC2335_MODE_E { + SC2335_MODE_1920X1080P30 = 0, + SC2335_MODE_LINEAR_NUM, + SC2335_MODE_NUM +} SC2335_MODE_E; + +typedef struct _SC2335_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + char name[64]; +} SC2335_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC2335[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC2335_BusInfo[]; +extern CVI_U16 g_au16SC2335_GainMode[]; +extern CVI_U16 g_au16SC2335_L2SMode[]; +extern const CVI_U8 sc2335_i2c_addr; +extern const CVI_U32 sc2335_addr_byte; +extern const CVI_U32 sc2335_data_byte; +extern void sc2335_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void sc2335_init(VI_PIPE ViPipe); +extern void sc2335_exit(VI_PIPE ViPipe); +extern void sc2335_standby(VI_PIPE ViPipe); +extern void sc2335_restart(VI_PIPE ViPipe); +extern int sc2335_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc2335_read_register(VI_PIPE ViPipe, int addr); +extern int sc2335_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC2335_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc2335/sc2335_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc2335/sc2335_cmos_param.h new file mode 100644 index 000000000..3f55de1a5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc2335/sc2335_cmos_param.h @@ -0,0 +1,125 @@ +#ifndef __SC2335_CMOS_PARAM_H_ +#define __SC2335_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc2335_cmos_ex.h" + +static const SC2335_MODE_S g_astSC2335_mode[SC2335_MODE_NUM] = { + [SC2335_MODE_1920X1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.51, /* 1125 * 30 / 0x7FFF */ + .u32HtsDef = 2560, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 3,//3 + .u16Max = 1125*2 - 10, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 16256, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 32512, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 + #ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 + #endif + }, + .stAuto = { + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + #ifdef ARCH_CV182X + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + #endif + }, + }, +}; + +struct combo_dev_attr_s sc2335_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 0, 1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 8, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC2335_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc2335/sc2335_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc2335/sc2335_sensor_ctl.c new file mode 100644 index 000000000..8ac4d16fb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc2335/sc2335_sensor_ctl.c @@ -0,0 +1,369 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "cvi_sns_ctrl.h" +#include "sc2335_cmos_ex.h" + +#define SC2335_CHIP_ID_HI_ADDR 0x3107 +#define SC2335_CHIP_ID_LO_ADDR 0x3108 +#define SC2335_CHIP_ID 0xcb14 + +static void sc2335_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc2335_i2c_addr = 0x30; /* I2C Address of SC2335 */ +const CVI_U32 sc2335_addr_byte = 2; +const CVI_U32 sc2335_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc2335_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC2335_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc2335_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc2335_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc2335_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc2335_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc2335_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc2335_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc2335_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc2335_write_register(VI_PIPE ViPipe, int addr, int data) +{ + int idx = 0; + int ret; + char buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc2335_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc2335_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc2335_addr_byte + sc2335_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc2335_prog(VI_PIPE ViPipe, int *rom) +{ + int i = 0; + + while (1) { + int lookup = rom[i++]; + int addr = (lookup >> 16) & 0xFFFF; + int data = lookup & 0xFFFF; + + if (addr == 0xFFFE) + delay_ms(data); + else if (addr != 0xFFFF) + sc2335_write_register(ViPipe, addr, data); + } +} + +void sc2335_standby(VI_PIPE ViPipe) +{ + sc2335_write_register(ViPipe, 0x0100, 0x00); +} + +void sc2335_restart(VI_PIPE ViPipe) +{ + sc2335_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc2335_write_register(ViPipe, 0x0100, 0x01); +} + +void sc2335_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC2335[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC2335[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc2335_write_register(ViPipe, + g_pastSC2335[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC2335[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc2335_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc2335_write_register(ViPipe, 0x3221, val); +} + + +int sc2335_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc2335_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc2335_read_register(ViPipe, SC2335_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc2335_read_register(ViPipe, SC2335_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC2335_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + + +/* 1080P30 and 1080P25 */ +static void sc2335_linear_1080p30_init(VI_PIPE ViPipe) +{ + sc2335_write_register(ViPipe, 0x0103, 0x01); + sc2335_write_register(ViPipe, 0x0100, 0x00); + sc2335_write_register(ViPipe, 0x36e9, 0x80); + sc2335_write_register(ViPipe, 0x36f9, 0x80); + sc2335_write_register(ViPipe, 0x301f, 0x02); + sc2335_write_register(ViPipe, 0x3207, 0x3f); + sc2335_write_register(ViPipe, 0x3249, 0x0f); + sc2335_write_register(ViPipe, 0x3253, 0x08); + sc2335_write_register(ViPipe, 0x3271, 0x00); + sc2335_write_register(ViPipe, 0x3273, 0x03); + sc2335_write_register(ViPipe, 0x3301, 0x06); + sc2335_write_register(ViPipe, 0x3302, 0x09); + sc2335_write_register(ViPipe, 0x3304, 0x28); + sc2335_write_register(ViPipe, 0x3306, 0x30); + sc2335_write_register(ViPipe, 0x330b, 0x94); + sc2335_write_register(ViPipe, 0x330c, 0x08); + sc2335_write_register(ViPipe, 0x330d, 0x18); + sc2335_write_register(ViPipe, 0x330e, 0x14); + sc2335_write_register(ViPipe, 0x330f, 0x05); + sc2335_write_register(ViPipe, 0x3310, 0x06); + sc2335_write_register(ViPipe, 0x3314, 0x96); + sc2335_write_register(ViPipe, 0x3316, 0x00); + sc2335_write_register(ViPipe, 0x331e, 0x21); + sc2335_write_register(ViPipe, 0x332b, 0x08); + sc2335_write_register(ViPipe, 0x3333, 0x10); + sc2335_write_register(ViPipe, 0x3338, 0x80); + sc2335_write_register(ViPipe, 0x333a, 0x04); + sc2335_write_register(ViPipe, 0x334c, 0x04); + sc2335_write_register(ViPipe, 0x335f, 0x04); + sc2335_write_register(ViPipe, 0x3364, 0x17); + sc2335_write_register(ViPipe, 0x3366, 0x62); + sc2335_write_register(ViPipe, 0x337c, 0x05); + sc2335_write_register(ViPipe, 0x337d, 0x09); + sc2335_write_register(ViPipe, 0x337e, 0x00); + sc2335_write_register(ViPipe, 0x3390, 0x08); + sc2335_write_register(ViPipe, 0x3391, 0x18); + sc2335_write_register(ViPipe, 0x3392, 0x38); + sc2335_write_register(ViPipe, 0x3393, 0x09); + sc2335_write_register(ViPipe, 0x3394, 0x20); + sc2335_write_register(ViPipe, 0x3395, 0x20); + sc2335_write_register(ViPipe, 0x33a2, 0x07); + sc2335_write_register(ViPipe, 0x33ac, 0x04); + sc2335_write_register(ViPipe, 0x33ae, 0x14); + sc2335_write_register(ViPipe, 0x3614, 0x00); + sc2335_write_register(ViPipe, 0x3622, 0x16); + sc2335_write_register(ViPipe, 0x3630, 0x68); + sc2335_write_register(ViPipe, 0x3631, 0x84); + sc2335_write_register(ViPipe, 0x3637, 0x20); + sc2335_write_register(ViPipe, 0x363a, 0x1f); + sc2335_write_register(ViPipe, 0x363c, 0x0e); + sc2335_write_register(ViPipe, 0x3670, 0x0e); + sc2335_write_register(ViPipe, 0x3674, 0xa1); + sc2335_write_register(ViPipe, 0x3675, 0x9c); + sc2335_write_register(ViPipe, 0x3676, 0x9e); + sc2335_write_register(ViPipe, 0x3677, 0x84); + sc2335_write_register(ViPipe, 0x3678, 0x85); + sc2335_write_register(ViPipe, 0x3679, 0x87); + sc2335_write_register(ViPipe, 0x367c, 0x18); + sc2335_write_register(ViPipe, 0x367d, 0x38); + sc2335_write_register(ViPipe, 0x367e, 0x08); + sc2335_write_register(ViPipe, 0x367f, 0x18); + sc2335_write_register(ViPipe, 0x3690, 0x32); + sc2335_write_register(ViPipe, 0x3691, 0x32); + sc2335_write_register(ViPipe, 0x3692, 0x44); + sc2335_write_register(ViPipe, 0x369c, 0x08); + sc2335_write_register(ViPipe, 0x369d, 0x38); + sc2335_write_register(ViPipe, 0x3908, 0x82); + sc2335_write_register(ViPipe, 0x391f, 0x18); + sc2335_write_register(ViPipe, 0x3e01, 0x8c); + sc2335_write_register(ViPipe, 0x3e02, 0x00); + sc2335_write_register(ViPipe, 0x3f00, 0x0d); + sc2335_write_register(ViPipe, 0x3f04, 0x02); + sc2335_write_register(ViPipe, 0x3f05, 0x0e); + sc2335_write_register(ViPipe, 0x3f09, 0x48); + sc2335_write_register(ViPipe, 0x4505, 0x0a); + sc2335_write_register(ViPipe, 0x4509, 0x20); + sc2335_write_register(ViPipe, 0x481d, 0x0a); + sc2335_write_register(ViPipe, 0x4827, 0x03); + sc2335_write_register(ViPipe, 0x5787, 0x10); + sc2335_write_register(ViPipe, 0x5788, 0x06); + sc2335_write_register(ViPipe, 0x578a, 0x10); + sc2335_write_register(ViPipe, 0x578b, 0x06); + sc2335_write_register(ViPipe, 0x5790, 0x10); + sc2335_write_register(ViPipe, 0x5791, 0x10); + sc2335_write_register(ViPipe, 0x5792, 0x00); + sc2335_write_register(ViPipe, 0x5793, 0x10); + sc2335_write_register(ViPipe, 0x5794, 0x10); + sc2335_write_register(ViPipe, 0x5795, 0x00); + sc2335_write_register(ViPipe, 0x5799, 0x00); + sc2335_write_register(ViPipe, 0x57c7, 0x10); + sc2335_write_register(ViPipe, 0x57c8, 0x06); + sc2335_write_register(ViPipe, 0x57ca, 0x10); + sc2335_write_register(ViPipe, 0x57cb, 0x06); + sc2335_write_register(ViPipe, 0x57d1, 0x10); + sc2335_write_register(ViPipe, 0x57d4, 0x10); + sc2335_write_register(ViPipe, 0x57d9, 0x00); + sc2335_write_register(ViPipe, 0x36e9, 0x20); + sc2335_write_register(ViPipe, 0x36f9, 0x27); + sc2335_write_register(ViPipe, 0x0100, 0x01); + + sc2335_default_reg_init(ViPipe); + + sc2335_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC2335 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +void sc2335_init(VI_PIPE ViPipe) +{ + sc2335_i2c_init(ViPipe); + + //linear mode only + sc2335_linear_1080p30_init(ViPipe); + + g_pastSC2335[ViPipe]->bInit = CVI_TRUE; +} + +void sc2335_exit(VI_PIPE ViPipe) +{ + sc2335_i2c_exit(ViPipe); +} \ No newline at end of file diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc2336/Makefile b/middleware/v2/component/isp/sensor/cv181x/sms_sc2336/Makefile new file mode 100644 index 000000000..cfab5277d --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc2336/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc2336.a +TARGET_SO = $(MW_LIB)/libsns_sc2336.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJ) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc2336/sc2336_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc2336/sc2336_cmos.c new file mode 100644 index 000000000..19d4d014a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc2336/sc2336_cmos.c @@ -0,0 +1,894 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc2336_cmos_ex.h" +#include "sc2336_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC2336_ID 35 +#define SENSOR_SC2336_WIDTH 1920 +#define SENSOR_SC2336_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC2336[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC2336_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC2336[dev]) +#define SC2336_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC2336[dev] = pstCtx) +#define SC2336_SENSOR_RESET_CTX(dev) (g_pastSC2336[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC2336_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC2336_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC2336_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC2336_STATE_S g_astSC2336_State[VI_MAX_PIPE_NUM] = {{0} }; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ + +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC2336 Lines Range*****/ +#define SC2336_FULL_LINES_MAX (0xFFFF) + +/*****SC2336 Register Address*****/ +#define SC2336_SHS1_0_ADDR 0x3E00 +#define SC2336_SHS1_1_ADDR 0x3E01 +#define SC2336_SHS1_2_ADDR 0x3E02 +#define SC2336_AGAIN0_ADDR 0x3E09 +#define SC2336_DGAIN0_ADDR 0x3E06 +#define SC2336_VMAX_ADDR 0x320E +#define SC2336_TABLE_END 0xFFFF + +#define SC2336_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC2336_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC2336_mode[pstSnsState->u8ImgMode]; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC2336_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC2336_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC2336_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC2336_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC2336_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC2336_FULL_LINES_MAX) ? SC2336_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 6; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE != pstSnsState->enWDRMode) { + CVI_U32 u32TmpIntTime = u32IntTime[0]; + /* linear exposure reg range: + * min : 1 + * max : (vts - 6) + * step : 1 + */ + u32TmpIntTime = (u32TmpIntTime > (pstSnsState->au32FL[0] - 6)) ? + (pstSnsState->au32FL[0] - 6) : u32TmpIntTime; + if (!u32TmpIntTime) + u32TmpIntTime = 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = (u32TmpIntTime & 0xF) << 4; + } + + return CVI_SUCCESS; + +} + +struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +}; + +static CVI_U32 Again_table[] = { + 1024, 2048, 4096, 8192, 16384, 32768 +}; + +static CVI_U32 AgainReg[] = { + 0x00, 0x08, 0x09, 0x0b, 0x0f, 0x1f +}; + +static struct gain_tbl_info_s DgainInfo[] = { + { + .gainMax = 2016, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 4096, + .idxBase = 64, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 0, + }, +}; + +static CVI_U32 Dgain_table[] = { + 1024, 1056, 1088, 1120, 1152, 1184, 1216, 1248, 1280, 1312, 1344, 1376, 1408, 1440, 1472, 1504, + 1536, 1568, 1600, 1632, 1664, 1696, 1728, 1760, 1792, 1824, 1856, 1888, 1920, 1952, 1984, 2016, + 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008, + 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, 3904, 3968, 4032, + 4096, +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 tableSize = sizeof(Again_table) / sizeof(CVI_U32); + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[tableSize - 1]) { + *pu32AgainLin = Again_table[tableSize - 1]; + *pu32AgainDb = AgainReg[tableSize - 1]; + return CVI_SUCCESS; + } + + for (CVI_U32 i = 1; i < tableSize; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = AgainReg[i - 1]; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 tableSize = sizeof(Dgain_table) / sizeof(CVI_U32); + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[tableSize - 1]) { + *pu32DgainLin = Dgain_table[tableSize - 1]; + *pu32DgainDb = tableSize - 1; + return CVI_SUCCESS; + } + + for (CVI_U32 i = 1; i < tableSize; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + CVI_S32 i = 0, tbl_num = 0; + + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* Again. */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1_ADDR].u32Data = (u32Dgain & 0xFF); + } + return CVI_SUCCESS; +} + + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + // pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + // pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC2336_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC2336_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC2336_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC2336_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC2336_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc2336_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc2336_addr_byte; + pstI2c_data[i].u32DataByteNum = sc2336_data_byte; + } + + //DOL 2t1 Mode Regs + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + break; + default: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC2336_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC2336_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC2336_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC2336_AGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC2336_DGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC2336_DGAIN0_ADDR + 1; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC2336_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC2336_VMAX_ADDR + 1; + + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC2336_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC2336_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC2336_MODE_S *pstMode = CVI_NULL; + + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC2336_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC2336_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc2336_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC2336_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC2336_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc2336_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= VI_MAX_DEV_NUM) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc2336_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc2336_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc2336_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC2336_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC2336_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC2336_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC2336_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC2336_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC2336_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC2336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC2336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC2336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC2336_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC2336_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC2336_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc2336_standby, + .pfnRestart = sc2336_restart, + .pfnMirrorFlip = sc2336_mirror_flip, + .pfnWriteReg = sc2336_write_register, + .pfnReadReg = sc2336_read_register, + .pfnSetBusInfo = sc2336_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc2336_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc2336/sc2336_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc2336/sc2336_cmos_ex.h new file mode 100644 index 000000000..88eb624cb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc2336/sc2336_cmos_ex.h @@ -0,0 +1,85 @@ +#ifndef __SC2336_CMOS_EX_H_ +#define __SC2336_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc2336_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_2_ADDR, + LINEAR_AGAIN_0_ADDR, + LINEAR_DGAIN_0_ADDR, + LINEAR_DGAIN_1_ADDR, + LINEAR_VMAX_0_ADDR, + LINEAR_VMAX_1_ADDR, + LINEAR_REGS_NUM +}; + + +typedef enum _SC2336_MODE_E { + SC2336_MODE_1080P30 = 0, + SC2336_MODE_LINEAR_NUM, + SC2336_MODE_NUM +} SC2336_MODE_E; + +typedef struct _SC2336_STATE_S { + CVI_U32 u32Sexp_MAX; +} SC2336_STATE_S; + +typedef struct _SC2336_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16SexpMaxReg; + char name[64]; +} SC2336_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC2336[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC2336_BusInfo[]; +extern CVI_U16 g_au16SC2336_GainMode[]; +extern CVI_U16 g_au16SC2336_L2SMode[]; +extern const CVI_U8 sc2336_i2c_addr; +extern const CVI_U32 sc2336_addr_byte; +extern const CVI_U32 sc2336_data_byte; +extern void sc2336_init(VI_PIPE ViPipe); +extern void sc2336_exit(VI_PIPE ViPipe); +extern void sc2336_standby(VI_PIPE ViPipe); +extern void sc2336_restart(VI_PIPE ViPipe); +extern int sc2336_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc2336_read_register(VI_PIPE ViPipe, int addr); +extern void sc2336_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc2336_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC2336_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc2336/sc2336_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc2336/sc2336_cmos_param.h new file mode 100644 index 000000000..1825ccbd2 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc2336/sc2336_cmos_param.h @@ -0,0 +1,125 @@ +#ifndef __SC2336_CMOS_PARAM_H_ +#define __SC2336_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc2336_cmos_ex.h" + +static const SC2336_MODE_S g_astSC2336_mode[SC2336_MODE_NUM] = { + [SC2336_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.51, /* 1125 * 30 / 0xFFFF*/ + .u32HtsDef = 2560, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 12184 - 6, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 32768, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 4096, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {260, 260, 260, 260, 260, 252, 252, 252, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 252, 252, 252, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 252, 252, 252, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 252, 252, 252, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1091, 1091, 1091, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1091, 1091, 1091, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1091, 1091, 1091, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1091, 1091, 1091, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc2336_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 0, 1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 8, + } + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC2336_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc2336/sc2336_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc2336/sc2336_sensor_ctl.c new file mode 100644 index 000000000..635aacdbb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc2336/sc2336_sensor_ctl.c @@ -0,0 +1,409 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc2336_cmos_ex.h" + +static void sc2336_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc2336_i2c_addr = 0x30; /* I2C Address of SC2336 */ +const CVI_U32 sc2336_addr_byte = 2; +const CVI_U32 sc2336_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc2336_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC2336_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc2336_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc2336_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc2336_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + char buf[8]; + int idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc2336_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc2336_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc2336_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc2336_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc2336_write_register(VI_PIPE ViPipe, int addr, int data) +{ + int idx = 0; + int ret; + char buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc2336_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc2336_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc2336_addr_byte + sc2336_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc2336_prog(VI_PIPE ViPipe, int *rom) +{ + int i = 0; + + while (1) { + int lookup = rom[i++]; + int addr = (lookup >> 16) & 0xFFFF; + int data = lookup & 0xFFFF; + + if (addr == 0xFFFE) + delay_ms(data); + else if (addr != 0xFFFF) + sc2336_write_register(ViPipe, addr, data); + } +} + +void sc2336_standby(VI_PIPE ViPipe) +{ + sc2336_write_register(ViPipe, 0x0100, 0x00); +} + +void sc2336_restart(VI_PIPE ViPipe) +{ + sc2336_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc2336_write_register(ViPipe, 0x0100, 0x01); +} + +void sc2336_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC2336[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc2336_write_register(ViPipe, + g_pastSC2336[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC2336[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC2336_CHIP_ID_HI_ADDR 0x3107 +#define SC2336_CHIP_ID_LO_ADDR 0x3108 +#define SC2336_CHIP_ID 0xcb3a + +void sc2336_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc2336_write_register(ViPipe, 0x3221, val); +} + +int sc2336_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc2336_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc2336_read_register(ViPipe, SC2336_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc2336_read_register(ViPipe, SC2336_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC2336_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc2336_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + + bInit = g_pastSC2336[ViPipe]->bInit; + enWDRMode = g_pastSC2336[ViPipe]->enWDRMode; + + sc2336_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_NONE) { + sc2336_linear_1080p30_init(ViPipe); + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_NONE) { + sc2336_linear_1080p30_init(ViPipe); + } + } + g_pastSC2336[ViPipe]->bInit = CVI_TRUE; +} + +void sc2336_exit(VI_PIPE ViPipe) +{ + sc2336_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void sc2336_linear_1080p30_init(VI_PIPE ViPipe) +{ + sc2336_write_register(ViPipe, 0x0103, 0x01); + sc2336_write_register(ViPipe, 0x0100, 0x00); + sc2336_write_register(ViPipe, 0x36e9, 0x80); + sc2336_write_register(ViPipe, 0x37f9, 0x80); + sc2336_write_register(ViPipe, 0x301f, 0x01); + sc2336_write_register(ViPipe, 0x3106, 0x05); + sc2336_write_register(ViPipe, 0x3248, 0x04); + sc2336_write_register(ViPipe, 0x3249, 0x0b); + sc2336_write_register(ViPipe, 0x3253, 0x08); + sc2336_write_register(ViPipe, 0x3301, 0x09); + sc2336_write_register(ViPipe, 0x3302, 0xff); + sc2336_write_register(ViPipe, 0x3303, 0x10); + sc2336_write_register(ViPipe, 0x3306, 0x60); + sc2336_write_register(ViPipe, 0x3307, 0x02); + sc2336_write_register(ViPipe, 0x330a, 0x01); + sc2336_write_register(ViPipe, 0x330b, 0x10); + sc2336_write_register(ViPipe, 0x330c, 0x16); + sc2336_write_register(ViPipe, 0x330d, 0xff); + sc2336_write_register(ViPipe, 0x3318, 0x02); + sc2336_write_register(ViPipe, 0x3321, 0x0a); + sc2336_write_register(ViPipe, 0x3327, 0x0e); + sc2336_write_register(ViPipe, 0x332b, 0x12); + sc2336_write_register(ViPipe, 0x3333, 0x10); + sc2336_write_register(ViPipe, 0x3334, 0x40); + sc2336_write_register(ViPipe, 0x335e, 0x06); + sc2336_write_register(ViPipe, 0x335f, 0x0a); + sc2336_write_register(ViPipe, 0x3364, 0x1f); + sc2336_write_register(ViPipe, 0x337c, 0x02); + sc2336_write_register(ViPipe, 0x337d, 0x0e); + sc2336_write_register(ViPipe, 0x3390, 0x09); + sc2336_write_register(ViPipe, 0x3391, 0x0f); + sc2336_write_register(ViPipe, 0x3392, 0x1f); + sc2336_write_register(ViPipe, 0x3393, 0x20); + sc2336_write_register(ViPipe, 0x3394, 0x20); + sc2336_write_register(ViPipe, 0x3395, 0xff); + sc2336_write_register(ViPipe, 0x33a2, 0x04); + sc2336_write_register(ViPipe, 0x33b1, 0x80); + sc2336_write_register(ViPipe, 0x33b2, 0x68); + sc2336_write_register(ViPipe, 0x33b3, 0x42); + sc2336_write_register(ViPipe, 0x33f9, 0x70); + sc2336_write_register(ViPipe, 0x33fb, 0xd0); + sc2336_write_register(ViPipe, 0x33fc, 0x0f); + sc2336_write_register(ViPipe, 0x33fd, 0x1f); + sc2336_write_register(ViPipe, 0x349f, 0x03); + sc2336_write_register(ViPipe, 0x34a6, 0x0f); + sc2336_write_register(ViPipe, 0x34a7, 0x1f); + sc2336_write_register(ViPipe, 0x34a8, 0x42); + sc2336_write_register(ViPipe, 0x34a9, 0x06); + sc2336_write_register(ViPipe, 0x34aa, 0x01); + sc2336_write_register(ViPipe, 0x34ab, 0x23); + sc2336_write_register(ViPipe, 0x34ac, 0x01); + sc2336_write_register(ViPipe, 0x34ad, 0x84); + sc2336_write_register(ViPipe, 0x3630, 0xf4); + sc2336_write_register(ViPipe, 0x3633, 0x22); + sc2336_write_register(ViPipe, 0x3639, 0xf4); + sc2336_write_register(ViPipe, 0x363c, 0x47); + sc2336_write_register(ViPipe, 0x3670, 0x09); + sc2336_write_register(ViPipe, 0x3674, 0xf4); + sc2336_write_register(ViPipe, 0x3675, 0xfb); + sc2336_write_register(ViPipe, 0x3676, 0xed); + sc2336_write_register(ViPipe, 0x367c, 0x09); + sc2336_write_register(ViPipe, 0x367d, 0x0f); + sc2336_write_register(ViPipe, 0x3690, 0x33); + sc2336_write_register(ViPipe, 0x3691, 0x33); + sc2336_write_register(ViPipe, 0x3692, 0x43); + sc2336_write_register(ViPipe, 0x3698, 0x89); + sc2336_write_register(ViPipe, 0x3699, 0x96); + sc2336_write_register(ViPipe, 0x369a, 0xd0); + sc2336_write_register(ViPipe, 0x369b, 0xd0); + sc2336_write_register(ViPipe, 0x369c, 0x09); + sc2336_write_register(ViPipe, 0x369d, 0x0f); + sc2336_write_register(ViPipe, 0x36a2, 0x09); + sc2336_write_register(ViPipe, 0x36a3, 0x0f); + sc2336_write_register(ViPipe, 0x36a4, 0x1f); + sc2336_write_register(ViPipe, 0x36d0, 0x01); + sc2336_write_register(ViPipe, 0x3722, 0xe1); + sc2336_write_register(ViPipe, 0x3724, 0x41); + sc2336_write_register(ViPipe, 0x3725, 0xc1); + sc2336_write_register(ViPipe, 0x3728, 0x20); + sc2336_write_register(ViPipe, 0x3900, 0x0d); + sc2336_write_register(ViPipe, 0x3905, 0x98); + sc2336_write_register(ViPipe, 0x391b, 0x81); + sc2336_write_register(ViPipe, 0x391c, 0x10); + sc2336_write_register(ViPipe, 0x3933, 0x81); + sc2336_write_register(ViPipe, 0x3934, 0xc5); + sc2336_write_register(ViPipe, 0x3940, 0x68); + sc2336_write_register(ViPipe, 0x3941, 0x00); + sc2336_write_register(ViPipe, 0x3942, 0x01); + sc2336_write_register(ViPipe, 0x3943, 0xc6); + sc2336_write_register(ViPipe, 0x3952, 0x02); + sc2336_write_register(ViPipe, 0x3953, 0x0f); + sc2336_write_register(ViPipe, 0x3e01, 0x45); + sc2336_write_register(ViPipe, 0x3e02, 0xf0); + sc2336_write_register(ViPipe, 0x3e08, 0x1f); + sc2336_write_register(ViPipe, 0x3e1b, 0x14); + sc2336_write_register(ViPipe, 0x440e, 0x02); + sc2336_write_register(ViPipe, 0x4509, 0x38); + sc2336_write_register(ViPipe, 0x5799, 0x06); + sc2336_write_register(ViPipe, 0x5ae0, 0xfe); + sc2336_write_register(ViPipe, 0x5ae1, 0x40); + sc2336_write_register(ViPipe, 0x5ae2, 0x30); + sc2336_write_register(ViPipe, 0x5ae3, 0x28); + sc2336_write_register(ViPipe, 0x5ae4, 0x20); + sc2336_write_register(ViPipe, 0x5ae5, 0x30); + sc2336_write_register(ViPipe, 0x5ae6, 0x28); + sc2336_write_register(ViPipe, 0x5ae7, 0x20); + sc2336_write_register(ViPipe, 0x5ae8, 0x3c); + sc2336_write_register(ViPipe, 0x5ae9, 0x30); + sc2336_write_register(ViPipe, 0x5aea, 0x28); + sc2336_write_register(ViPipe, 0x5aeb, 0x3c); + sc2336_write_register(ViPipe, 0x5aec, 0x30); + sc2336_write_register(ViPipe, 0x5aed, 0x28); + sc2336_write_register(ViPipe, 0x5aee, 0xfe); + sc2336_write_register(ViPipe, 0x5aef, 0x40); + sc2336_write_register(ViPipe, 0x5af4, 0x30); + sc2336_write_register(ViPipe, 0x5af5, 0x28); + sc2336_write_register(ViPipe, 0x5af6, 0x20); + sc2336_write_register(ViPipe, 0x5af7, 0x30); + sc2336_write_register(ViPipe, 0x5af8, 0x28); + sc2336_write_register(ViPipe, 0x5af9, 0x20); + sc2336_write_register(ViPipe, 0x5afa, 0x3c); + sc2336_write_register(ViPipe, 0x5afb, 0x30); + sc2336_write_register(ViPipe, 0x5afc, 0x28); + sc2336_write_register(ViPipe, 0x5afd, 0x3c); + sc2336_write_register(ViPipe, 0x5afe, 0x30); + sc2336_write_register(ViPipe, 0x5aff, 0x28); + sc2336_write_register(ViPipe, 0x36e9, 0x20); + sc2336_write_register(ViPipe, 0x37f9, 0x27); + sc2336_write_register(ViPipe, 0x0100, 0x01); + + sc2336_default_reg_init(ViPipe); + + sc2336_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC2336 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc301iot/Makefile b/middleware/v2/component/isp/sensor/cv181x/sms_sc301iot/Makefile new file mode 100644 index 000000000..cf1e22a03 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc301iot/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc301iot.a +TARGET_SO = $(MW_LIB)/libsns_sc301iot.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc301iot/sc301iot_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc301iot/sc301iot_cmos.c new file mode 100644 index 000000000..8be74706c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc301iot/sc301iot_cmos.c @@ -0,0 +1,921 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc301iot_cmos_ex.h" +#include "sc301iot_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC301IOT_ID 35 +#define SENSOR_SC301IOT_WIDTH 2048 +#define SENSOR_SC301IOT_HEIGHT 1536 +#define SC301IOT_I2C_ADDR_1 0x30 +#define SC301IOT_I2C_ADDR_2 0x32 +#define SC301IOT_I2C_ADDR_IS_VALID(addr) ((addr) == SC301IOT_I2C_ADDR_1 || (addr) == SC301IOT_I2C_ADDR_2) +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC301IOT[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC301IOT_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC301IOT[dev]) +#define SC301IOT_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC301IOT[dev] = pstCtx) +#define SC301IOT_SENSOR_RESET_CTX(dev) (g_pastSC301IOT[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC301IOT_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC301IOT_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC301IOT_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC301IOT Lines Range*****/ +#define SC301IOT_FULL_LINES_MAX (0x7FFF) + +/*****SC301IOT Register Address*****/ +#define SC301IOT_SHS1_0_ADDR 0x3E00 +#define SC301IOT_SHS1_1_ADDR 0x3E01 +#define SC301IOT_SHS1_2_ADDR 0x3E02 +#define SC301IOT_SHS2_0_ADDR 0x3E22 +#define SC301IOT_SHS2_1_ADDR 0x3E04 +#define SC301IOT_SHS2_2_ADDR 0x3E05 +#define SC301IOT_AGAIN_ADDR 0x3E09 +#define SC301IOT_DGAIN1_ADDR 0x3E06 +#define SC301IOT_DGAIN2_ADDR 0x3E10 +#define SC301IOT_VMAX_ADDR 0x320E +#define SC301IOT_MAXSEXP_ADDR 0x3E23 +#define SC301IOT_TABLE_END 0xFFFF + +#define SC301IOT_RES_IS_1536P(w, h) ((w) <= SENSOR_SC301IOT_WIDTH && (h) <= SENSOR_SC301IOT_HEIGHT) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC301IOT_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astSC301IOT_mode[SC301IOT_MODE_1536P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC301IOT_mode[SC301IOT_MODE_1536P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = g_astSC301IOT_mode[SC301IOT_MODE_1536P30].stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = g_astSC301IOT_mode[SC301IOT_MODE_1536P30].stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astSC301IOT_mode[SC301IOT_MODE_1536P30].stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = g_astSC301IOT_mode[SC301IOT_MODE_1536P30].stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC301IOT_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC301IOT_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC301IOT_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC301IOT_MODE_1536P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC301IOT_FULL_LINES_MAX) ? SC301IOT_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + CVI_U32 u32TmpIntTime = u32IntTime[0]; + /* linear exposure reg range: + * min : 2 + * max : (vts - 8) + * step : 1 + */ + u32TmpIntTime = (u32TmpIntTime > (pstSnsState->au32FL[0] - 8)) ? + (pstSnsState->au32FL[0] - 8) : u32TmpIntTime; + if (!u32TmpIntTime) + u32TmpIntTime = 2; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = (u32TmpIntTime & 0xF) << 4; + } + + return CVI_SUCCESS; + +} + +struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +}; + +static struct gain_tbl_info_s DgainInfo[5] = { + { + .gainMax = 2016, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 8064, + .idxBase = 64, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 16128, + .idxBase = 96, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 32256, + .idxBase = 128, + .regGain = 0x0f, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, +}; + +static CVI_U32 Dgain_table[160] = { + 1024, 1055, 1088, 1120, 1152, 1183, 1216, 1248, 1280, 1311, 1344, 1376, 1408, + 1439, 1472, 1504, 1536, 1567, 1600, 1632, 1664, 1695, 1728, 1760, 1792, 1823, + 1856, 1888, 1920, 1951, 1984, 2016, 2048, 2112, 2176, 2240, 2304, 2368, 2432, + 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008, 3072, 3136, 3200, 3264, + 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, 3904, 3968, 4032, 4096, + 4224, 4352, 4480, 4608, 4736, 4864, 4992, 5120, 5248, 5376, 5504, 5632, 5760, + 5888, 6016, 6144, 6272, 6400, 6528, 6656, 6784, 6912, 7040, 7168, 7296, 7424, + 7552, 7680, 7808, 7936, 8064, 8192, 8448, 8704, 8960, 9216, 9472, 9728, 9984, + 10240, 10496, 10752, 11008, 11264, 11520, 11776, 12032, 12288, 12544, 12800, 13056, + 13312, 13568, 13824, 14080, 14336, 14592, 14848, 15104, 15360, 15616, 15872, 16128, + 16384, 16896, 17408, 17920, 18432, 18944, 19456, 19968, 20480, 20992, 21504, 22016, + 22528, 23040, 23552, 24064, 24576, 25088, 25600, 26112, 26624, 27136, 27648, 28160, + 28672, 29184, 29696, 30208, 30720, 31232, 31744, 32256 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 again = *pu32AgainLin; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (again < 1606) { + *pu32AgainDb = 0x00; + *pu32AgainLin = 1024; + } else if (again < 3213) { + *pu32AgainDb = 0x40; + *pu32AgainLin = 1606; + } else if (again < 6426) { + *pu32AgainDb = 0x48; + *pu32AgainLin = 3213; + } else if (again < 12853) { + *pu32AgainDb = 0x49; + *pu32AgainLin = 6426; + } else if (again < 25706) { + *pu32AgainDb = 0x4b; + *pu32AgainLin = 12853; + } else if (again < 51412) { + *pu32AgainDb = 0x4f; + *pu32AgainLin = 25706; + } else { + *pu32AgainDb = 0x5f; + *pu32AgainLin = 51412; + } + + return CVI_SUCCESS; +} +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[ARRAY_SIZE(Dgain_table) - 1]) { + *pu32DgainLin = Dgain_table[ARRAY_SIZE(Dgain_table) - 1]; + *pu32DgainDb = ARRAY_SIZE(Dgain_table) - 1; + return CVI_SUCCESS; + } + + for (i = 1; i < ARRAY_SIZE(Dgain_table); i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1_ADDR].u32Data = (u32Dgain & 0xFF); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + // pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + // pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC301IOT_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC301IOT_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == SC301IOT_MODE_1536P30) + pstSnsState->u8ImgMode = SC301IOT_MODE_1536P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC301IOT_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC301IOT_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc301iot_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc301iot_addr_byte; + pstI2c_data[i].u32DataByteNum = sc301iot_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC301IOT_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC301IOT_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC301IOT_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = SC301IOT_AGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC301IOT_DGAIN1_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC301IOT_DGAIN1_ADDR + 1; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC301IOT_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC301IOT_VMAX_ADDR + 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC301IOT_RES_IS_1536P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC301IOT_MODE_1536P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC301IOT_MODE_S *pstMode = CVI_NULL; + + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC301IOT_MODE_1536P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC301IOT_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC301IOT_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc301iot_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC301IOT_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC301IOT_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc301iot_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc301iot_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc301iot_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (SC301IOT_I2C_ADDR_IS_VALID(s32I2cAddr)) + sc301iot_i2c_addr = s32I2cAddr; +} + +static CVI_S32 sc301iot_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC301IOT_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC301IOT_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC301IOT_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC301IOT_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC301IOT_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC301IOT_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC301IOT_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC301IOT_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC301IOT_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC301IOT_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC301IOT_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC301IOT_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc301iot_standby, + .pfnRestart = sc301iot_restart, + .pfnMirrorFlip = sc301iot_mirror_flip, + .pfnWriteReg = sc301iot_write_register, + .pfnReadReg = sc301iot_read_register, + .pfnSetBusInfo = sc301iot_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc301iot_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc301iot/sc301iot_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc301iot/sc301iot_cmos_ex.h new file mode 100644 index 000000000..9a6045682 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc301iot/sc301iot_cmos_ex.h @@ -0,0 +1,78 @@ +#ifndef __SC301IOT_CMOS_EX_H_ +#define __SC301IOT_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc301iot_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_2_ADDR, + LINEAR_AGAIN_ADDR, + LINEAR_DGAIN_0_ADDR, + LINEAR_DGAIN_1_ADDR, + LINEAR_VMAX_0_ADDR, + LINEAR_VMAX_1_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC301IOT_MODE_E { + SC301IOT_MODE_1536P30 = 0, + SC301IOT_MODE_NUM +} SC301IOT_MODE_E; + +typedef struct _SC301IOT_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + char name[64]; +} SC301IOT_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC301IOT[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC301IOT_BusInfo[]; +extern CVI_U16 g_au16SC301IOT_GainMode[]; +extern CVI_U16 g_au16SC301IOT_L2SMode[]; +extern CVI_U8 sc301iot_i2c_addr; +extern const CVI_U32 sc301iot_addr_byte; +extern const CVI_U32 sc301iot_data_byte; +extern void sc301iot_init(VI_PIPE ViPipe); +extern void sc301iot_exit(VI_PIPE ViPipe); +extern void sc301iot_standby(VI_PIPE ViPipe); +extern void sc301iot_restart(VI_PIPE ViPipe); +extern int sc301iot_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc301iot_read_register(VI_PIPE ViPipe, int addr); +extern void sc301iot_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc301iot_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC301IOT_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc301iot/sc301iot_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc301iot/sc301iot_cmos_param.h new file mode 100644 index 000000000..f8a1f284c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc301iot/sc301iot_cmos_param.h @@ -0,0 +1,121 @@ +#ifndef __SC301IOT_CMOS_PARAM_H_ +#define __SC301IOT_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc301iot_cmos_ex.h" + +static const SC301IOT_MODE_S g_astSC301IOT_mode[SC301IOT_MODE_NUM] = { + [SC301IOT_MODE_1536P30] = { + .name = "1536p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2048, + .u32Height = 1536, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2048, + .u32Height = 1536, + }, + .stMaxSize = { + .u32Width = 2048, + .u32Height = 1536, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.46, /* 1600 * 30 / 0x7FFF*/ + .u32HtsDef = 2250, + .u32VtsDef = 1600, + .stExp[0] = { + .u16Min = 2, + .u16Max = 1600 - 8, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 51412, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 32256, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc301iot_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 0, 1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 1, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC301IOT_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc301iot/sc301iot_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc301iot/sc301iot_sensor_ctl.c new file mode 100644 index 000000000..fcb6494c5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc301iot/sc301iot_sensor_ctl.c @@ -0,0 +1,379 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc301iot_cmos_ex.h" + +static void sc301iot_linear_1536p30_init(VI_PIPE ViPipe); + +CVI_U8 sc301iot_i2c_addr = 0x30; /* I2C Address of SC301IOT */ +const CVI_U32 sc301iot_addr_byte = 2; +const CVI_U32 sc301iot_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc301iot_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC301IOT_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc301iot_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc301iot_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc301iot_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + char buf[8]; + int idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc301iot_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc301iot_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc301iot_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc301iot_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc301iot_write_register(VI_PIPE ViPipe, int addr, int data) +{ + int idx = 0; + int ret; + char buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc301iot_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc301iot_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc301iot_addr_byte + sc301iot_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc301iot_standby(VI_PIPE ViPipe) +{ + sc301iot_write_register(ViPipe, 0x0100, 0x00); +} + +void sc301iot_restart(VI_PIPE ViPipe) +{ + sc301iot_write_register(ViPipe, 0x0103, 0x01); + delay_ms(1); +} + +void sc301iot_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC301IOT[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc301iot_write_register(ViPipe, + g_pastSC301IOT[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC301IOT[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC301IOT_CHIP_ID_HI_ADDR 0x3107 +#define SC301IOT_CHIP_ID_LO_ADDR 0x3108 +#define SC301IOT_CHIP_ID 0xcc40 + +void sc301iot_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc301iot_write_register(ViPipe, 0x3221, val); +} + +int sc301iot_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc301iot_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc301iot_read_register(ViPipe, SC301IOT_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc301iot_read_register(ViPipe, SC301IOT_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC301IOT_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc301iot_init(VI_PIPE ViPipe) +{ + sc301iot_i2c_init(ViPipe); + + //linear mode only + sc301iot_linear_1536p30_init(ViPipe); + + g_pastSC301IOT[ViPipe]->bInit = CVI_TRUE; +} + +void sc301iot_exit(VI_PIPE ViPipe) +{ + sc301iot_i2c_exit(ViPipe); +} + +static void sc301iot_linear_1536p30_init(VI_PIPE ViPipe) +{ + sc301iot_write_register(ViPipe, 0x0103, 0x01); + sc301iot_write_register(ViPipe, 0x0100, 0x00); + sc301iot_write_register(ViPipe, 0x36e9, 0x80); + sc301iot_write_register(ViPipe, 0x37f9, 0x80); + sc301iot_write_register(ViPipe, 0x301c, 0x78); + sc301iot_write_register(ViPipe, 0x301f, 0x01); + sc301iot_write_register(ViPipe, 0x30b8, 0x44); + sc301iot_write_register(ViPipe, 0x3208, 0x08); + sc301iot_write_register(ViPipe, 0x3209, 0x00); + sc301iot_write_register(ViPipe, 0x320a, 0x06); + sc301iot_write_register(ViPipe, 0x320b, 0x00); + sc301iot_write_register(ViPipe, 0x320c, 0x04); + sc301iot_write_register(ViPipe, 0x320d, 0x65); + sc301iot_write_register(ViPipe, 0x320e, 0x06); + sc301iot_write_register(ViPipe, 0x320f, 0x40); + sc301iot_write_register(ViPipe, 0x3214, 0x11); + sc301iot_write_register(ViPipe, 0x3215, 0x11); + sc301iot_write_register(ViPipe, 0x3223, 0xd0); + sc301iot_write_register(ViPipe, 0x3231, 0x01); + sc301iot_write_register(ViPipe, 0x3253, 0x0c); + sc301iot_write_register(ViPipe, 0x3274, 0x09); + sc301iot_write_register(ViPipe, 0x3301, 0x08); + sc301iot_write_register(ViPipe, 0x3306, 0x58); + sc301iot_write_register(ViPipe, 0x3308, 0x08); + sc301iot_write_register(ViPipe, 0x330a, 0x00); + sc301iot_write_register(ViPipe, 0x330b, 0xe0); + sc301iot_write_register(ViPipe, 0x330e, 0x10); + sc301iot_write_register(ViPipe, 0x3314, 0x14); + sc301iot_write_register(ViPipe, 0x331e, 0x55); + sc301iot_write_register(ViPipe, 0x331f, 0x7d); + sc301iot_write_register(ViPipe, 0x3333, 0x10); + sc301iot_write_register(ViPipe, 0x3334, 0x40); + sc301iot_write_register(ViPipe, 0x335e, 0x06); + sc301iot_write_register(ViPipe, 0x335f, 0x08); + sc301iot_write_register(ViPipe, 0x3364, 0x5e); + sc301iot_write_register(ViPipe, 0x337c, 0x02); + sc301iot_write_register(ViPipe, 0x337d, 0x0a); + sc301iot_write_register(ViPipe, 0x3390, 0x01); + sc301iot_write_register(ViPipe, 0x3391, 0x03); + sc301iot_write_register(ViPipe, 0x3392, 0x07); + sc301iot_write_register(ViPipe, 0x3393, 0x08); + sc301iot_write_register(ViPipe, 0x3394, 0x08); + sc301iot_write_register(ViPipe, 0x3395, 0x08); + sc301iot_write_register(ViPipe, 0x3396, 0x08); + sc301iot_write_register(ViPipe, 0x3397, 0x09); + sc301iot_write_register(ViPipe, 0x3398, 0x1f); + sc301iot_write_register(ViPipe, 0x3399, 0x08); + sc301iot_write_register(ViPipe, 0x339a, 0x0a); + sc301iot_write_register(ViPipe, 0x339b, 0x40); + sc301iot_write_register(ViPipe, 0x339c, 0x88); + sc301iot_write_register(ViPipe, 0x33a2, 0x04); + sc301iot_write_register(ViPipe, 0x33ad, 0x0c); + sc301iot_write_register(ViPipe, 0x33b1, 0x80); + sc301iot_write_register(ViPipe, 0x33b3, 0x30); + sc301iot_write_register(ViPipe, 0x33f9, 0x68); + sc301iot_write_register(ViPipe, 0x33fb, 0x80); + sc301iot_write_register(ViPipe, 0x33fc, 0x48); + sc301iot_write_register(ViPipe, 0x33fd, 0x5f); + sc301iot_write_register(ViPipe, 0x349f, 0x03); + sc301iot_write_register(ViPipe, 0x34a6, 0x48); + sc301iot_write_register(ViPipe, 0x34a7, 0x5f); + sc301iot_write_register(ViPipe, 0x34a8, 0x30); + sc301iot_write_register(ViPipe, 0x34a9, 0x30); + sc301iot_write_register(ViPipe, 0x34aa, 0x00); + sc301iot_write_register(ViPipe, 0x34ab, 0xf0); + sc301iot_write_register(ViPipe, 0x34ac, 0x01); + sc301iot_write_register(ViPipe, 0x34ad, 0x08); + sc301iot_write_register(ViPipe, 0x34f8, 0x5f); + sc301iot_write_register(ViPipe, 0x34f9, 0x10); + sc301iot_write_register(ViPipe, 0x3630, 0xf0); + sc301iot_write_register(ViPipe, 0x3631, 0x85); + sc301iot_write_register(ViPipe, 0x3632, 0x74); + sc301iot_write_register(ViPipe, 0x3633, 0x22); + sc301iot_write_register(ViPipe, 0x3637, 0x4d); + sc301iot_write_register(ViPipe, 0x3638, 0xcb); + sc301iot_write_register(ViPipe, 0x363a, 0x8b); + sc301iot_write_register(ViPipe, 0x363c, 0x08); + sc301iot_write_register(ViPipe, 0x3640, 0x00); + sc301iot_write_register(ViPipe, 0x3641, 0x38); + sc301iot_write_register(ViPipe, 0x3670, 0x4e); + sc301iot_write_register(ViPipe, 0x3674, 0xc0); + sc301iot_write_register(ViPipe, 0x3675, 0xb0); + sc301iot_write_register(ViPipe, 0x3676, 0xa0); + sc301iot_write_register(ViPipe, 0x3677, 0x83); + sc301iot_write_register(ViPipe, 0x3678, 0x87); + sc301iot_write_register(ViPipe, 0x3679, 0x8a); + sc301iot_write_register(ViPipe, 0x367c, 0x49); + sc301iot_write_register(ViPipe, 0x367d, 0x4f); + sc301iot_write_register(ViPipe, 0x367e, 0x48); + sc301iot_write_register(ViPipe, 0x367f, 0x4b); + sc301iot_write_register(ViPipe, 0x3690, 0x33); + sc301iot_write_register(ViPipe, 0x3691, 0x33); + sc301iot_write_register(ViPipe, 0x3692, 0x44); + sc301iot_write_register(ViPipe, 0x3699, 0x8a); + sc301iot_write_register(ViPipe, 0x369a, 0xa1); + sc301iot_write_register(ViPipe, 0x369b, 0xc2); + sc301iot_write_register(ViPipe, 0x369c, 0x48); + sc301iot_write_register(ViPipe, 0x369d, 0x4f); + sc301iot_write_register(ViPipe, 0x36a2, 0x4b); + sc301iot_write_register(ViPipe, 0x36a3, 0x4f); + sc301iot_write_register(ViPipe, 0x370f, 0x01); + sc301iot_write_register(ViPipe, 0x3714, 0x80); + sc301iot_write_register(ViPipe, 0x3722, 0x09); + sc301iot_write_register(ViPipe, 0x3724, 0x41); + sc301iot_write_register(ViPipe, 0x3725, 0xc1); + sc301iot_write_register(ViPipe, 0x3728, 0x00); + sc301iot_write_register(ViPipe, 0x3771, 0x09); + sc301iot_write_register(ViPipe, 0x3772, 0x05); + sc301iot_write_register(ViPipe, 0x3773, 0x05); + sc301iot_write_register(ViPipe, 0x377a, 0x48); + sc301iot_write_register(ViPipe, 0x377b, 0x49); + sc301iot_write_register(ViPipe, 0x3905, 0x8d); + sc301iot_write_register(ViPipe, 0x391d, 0x08); + sc301iot_write_register(ViPipe, 0x3922, 0x1a); + sc301iot_write_register(ViPipe, 0x3926, 0x21); + sc301iot_write_register(ViPipe, 0x3933, 0x80); + sc301iot_write_register(ViPipe, 0x3934, 0x0d); + sc301iot_write_register(ViPipe, 0x3937, 0x6a); + sc301iot_write_register(ViPipe, 0x3939, 0x00); + sc301iot_write_register(ViPipe, 0x393a, 0x0e); + sc301iot_write_register(ViPipe, 0x39dc, 0x02); + sc301iot_write_register(ViPipe, 0x3e00, 0x00); + sc301iot_write_register(ViPipe, 0x3e01, 0x63); + sc301iot_write_register(ViPipe, 0x3e02, 0x80); + sc301iot_write_register(ViPipe, 0x3e03, 0x0b); + sc301iot_write_register(ViPipe, 0x3e1b, 0x2a); + sc301iot_write_register(ViPipe, 0x4407, 0x34); + sc301iot_write_register(ViPipe, 0x440e, 0x02); + sc301iot_write_register(ViPipe, 0x5001, 0x40); + sc301iot_write_register(ViPipe, 0x5007, 0x80); + sc301iot_write_register(ViPipe, 0x36e9, 0x24); + sc301iot_write_register(ViPipe, 0x37f9, 0x24); + + sc301iot_default_reg_init(ViPipe); + + sc301iot_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC301IOT 1536P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc3332/Makefile b/middleware/v2/component/isp/sensor/cv181x/sms_sc3332/Makefile new file mode 100644 index 000000000..90edabd68 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc3332/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc3332.a +TARGET_SO = $(MW_LIB)/libsns_sc3332.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc3332/sc3332_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc3332/sc3332_cmos.c new file mode 100644 index 000000000..9dd51f537 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc3332/sc3332_cmos.c @@ -0,0 +1,933 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc3332_cmos_ex.h" +#include "sc3332_cmos_param.h" + + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC3332_ID 3336 +#define SC3332_I2C_ADDR_1 0x30 +#define SC3332_I2C_ADDR_2 0x32 +#define SC3332_I2C_ADDR_IS_VALID(addr) ((addr) == SC3332_I2C_ADDR_1 || (addr) == SC3332_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC3332[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC3332_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC3332[dev]) +#define SC3332_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC3332[dev] = pstCtx) +#define SC3332_SENSOR_RESET_CTX(dev) (g_pastSC3332[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC3332_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC3332_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC3332_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc3332_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC3332 Lines Range*****/ +#define SC3332_FULL_LINES_MAX (0xFFFF) + +/*****SC3332 Register Address*****/ +#define SC3332_EXP_H_ADDR (0x3e00) +#define SC3332_EXP_M_ADDR (0x3e01) +#define SC3332_EXP_L_ADDR (0x3e02) + +#define SC3332_AGAIN_ADDR (0x3e09) + +#define SC3332_DGAIN_H_ADDR (0x3e06) +#define SC3332_DGAIN_L_ADDR (0x3e07) + +#define SC3332_VMAX_H_ADDR (0x320e) +#define SC3332_VMAX_L_ADDR (0x320f) + +#define SC3332_RES_IS_1296P(w, h) ((w) == 2304 && (h) == 1296) + +#define SC3332_EXPACCURACY (1) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC3332_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC3332_mode[pstSnsState->u8ImgMode]; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC3332_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC3332_EXPACCURACY; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = pstAeSnsDft->u32MaxIntTime; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC3332_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC3332_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC3332_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC3332_MODE_2304X1296P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC3332_FULL_LINES_MAX) ? SC3332_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 10; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 0 + * max : vts - 10 + * step : 1 + */ + u32MinTime = 0; + u32MaxTime = pstSnsState->au32FL[0] - 10; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_M_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_ADDR].u32Data = ((u32TmpIntTime & 0x000F) << 4); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +typedef struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} gain_tbl_info_s; + +static struct gain_tbl_info_s DgainInfo[4] = { + { + .gainMax = 2016, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 8064, + .idxBase = 64, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 16128, + .idxBase = 96, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, +}; + +static CVI_U32 Dgain_table[128] = { + 1024, 1055, 1088, 1120, 1152, 1183, 1216, 1248, 1280, 1311, 1344, 1376, + 1408, 1439, 1472, 1504, 1536, 1567, 1600, 1632, 1664, 1695, 1728, 1760, + 1792, 1823, 1856, 1888, 1920, 1951, 1984, 2016, 2048, 2112, 2176, 2240, + 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008, + 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, + 3840, 3904, 3968, 4032, 4096, 4224, 4352, 4480, 4608, 4736, 4864, 4992, + 5120, 5248, 5376, 5504, 5632, 5760, 5888, 6016, 6144, 6272, 6400, 6528, + 6656, 6784, 6912, 7040, 7168, 7296, 7424, 7552, 7680, 7808, 7936, 8064, + 8192, 8448, 8704, 8960, 9216, 9472, 9728, 9984, 10240, 10496, 10752, 11008, + 11264, 11520, 11776, 12032, 12288, 12544, 12800, 13056, 13312, 13568, 13824, + 14080, 14336, 14592, 14848, 15104, 15360, 15616, 15872, 16128 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 again = *pu32AgainLin; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (again < 2048) { + *pu32AgainDb = 0x00; + *pu32AgainLin = 1024; + } else if (again < 4096) { + *pu32AgainDb = 0x08; + *pu32AgainLin = 2048; + } else if (again < 8192) { + *pu32AgainDb = 0x09; + *pu32AgainLin = 4096; + } else if (again < 16384) { + *pu32AgainDb = 0x0b; + *pu32AgainLin = 8192; + } else if (again < 32768) { + *pu32AgainDb = 0x0f; + *pu32AgainLin = 16384; + } else { + *pu32AgainDb = 0x1f; + *pu32AgainLin = 32768; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[127]) { + *pu32DgainLin = Dgain_table[127]; + *pu32DgainDb = 127; + return CVI_SUCCESS; + } + + for (i = 1; i < 128; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L_ADDR].u32Data = (u32Dgain & 0xFF); + + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC3332_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC3332_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC3332_MODE_2304X1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC3332_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = ISP_SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC3332_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc3332_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc3332_addr_byte; + pstI2c_data[i].u32DataByteNum = sc3332_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC3332_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_M_ADDR].u32RegAddr = SC3332_EXP_M_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC3332_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = SC3332_AGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC3332_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC3332_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC3332_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC3332_VMAX_L_ADDR; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC3332_RES_IS_1296P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC3332_MODE_2304X1296P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeSc3332_MirrorFip[ViPipe] != eSnsMirrorFlip) { + sc3332_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeSc3332_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC3332_MODE_S *pstMode = CVI_NULL; + + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC3332_MODE_2304X1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC3332_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3332_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc3332_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC3332_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC3332_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc3332_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc3332_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc3332_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (SC3332_I2C_ADDR_IS_VALID(s32I2cAddr)) + sc3332_i2c_addr = s32I2cAddr; +} + +static CVI_S32 sc3332_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC3332_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC3332_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC3332_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC3332_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC3332_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC3332_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC3332_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC3332_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC3332_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC3332_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC3332_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC3332_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc3332_standby, + .pfnRestart = sc3332_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = sc3332_write_register, + .pfnReadReg = sc3332_read_register, + .pfnSetBusInfo = sc3332_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc3332_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc3332/sc3332_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc3332/sc3332_cmos_ex.h new file mode 100644 index 000000000..99f3443a3 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc3332/sc3332_cmos_ex.h @@ -0,0 +1,80 @@ +#ifndef __SC3332_CMOS_EX_H_ +#define __SC3332_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc3332_linear_regs_e { + LINEAR_EXP_H_ADDR, + LINEAR_EXP_M_ADDR, + LINEAR_EXP_L_ADDR, + LINEAR_AGAIN_ADDR, + LINEAR_DGAIN_H_ADDR, + LINEAR_DGAIN_L_ADDR, + LINEAR_VMAX_H_ADDR, + LINEAR_VMAX_L_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC3332_MODE_E { + SC3332_MODE_2304X1296P30 = 0, + SC3332_MODE_LINEAR_NUM, + SC3332_MODE_2304X1296P30_WDR = SC3332_MODE_LINEAR_NUM, + SC3332_MODE_NUM +} SC3332_MODE_E; + +typedef struct _SC3332_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + char name[64]; +} SC3332_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC3332[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC3332_BusInfo[]; +extern CVI_U16 g_au16SC3332_GainMode[]; +extern CVI_U16 g_au16SC3332_L2SMode[]; +extern CVI_U8 sc3332_i2c_addr; +extern const CVI_U32 sc3332_addr_byte; +extern const CVI_U32 sc3332_data_byte; +extern void sc3332_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void sc3332_init(VI_PIPE ViPipe); +extern void sc3332_exit(VI_PIPE ViPipe); +extern void sc3332_standby(VI_PIPE ViPipe); +extern void sc3332_restart(VI_PIPE ViPipe); +extern int sc3332_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc3332_read_register(VI_PIPE ViPipe, int addr); +extern int sc3332_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC3332_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc3332/sc3332_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc3332/sc3332_cmos_param.h new file mode 100644 index 000000000..fb991d11e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc3332/sc3332_cmos_param.h @@ -0,0 +1,121 @@ +#ifndef __SC3332_CMOS_PARAM_H_ +#define __SC3332_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc3332_cmos_ex.h" + +static const SC3332_MODE_S g_astSC3332_mode[SC3332_MODE_NUM] = { + [SC3332_MODE_2304X1296P30] = { + .name = "1296p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2304, + .u32Height = 1296, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2304, + .u32Height = 1296, + }, + .stMaxSize = { + .u32Width = 2304, + .u32Height = 1296, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.61, /* 1350 * 30 / 0xFFFF */ + .u32HtsDef = 4938, + .u32VtsDef = 1344, + .stExp[0] = { + .u16Min = 2, + .u16Max = 1344,//vts - 6 + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 32768, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 16128, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {256, 256, 256, 256, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {256, 256, 256, 256, 256, 256, 256, 256, /*8*/256, 256, 256, 256, 256, 256, 256, 256}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, + {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, + /*8*/1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc3332_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {3, 2, 4, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC3332_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc3332/sc3332_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc3332/sc3332_sensor_ctl.c new file mode 100644 index 000000000..d8b92b8a1 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc3332/sc3332_sensor_ctl.c @@ -0,0 +1,379 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc3332_cmos_ex.h" + +#define SC3332_CHIP_ID_HI_ADDR 0x3107 +#define SC3332_CHIP_ID_LO_ADDR 0x3108 +#define SC3332_CHIP_ID 0xcc44 + +static void sc3332_linear_1296P30_init(VI_PIPE ViPipe); + +CVI_U8 sc3332_i2c_addr = 0x30; /* I2C Address of SC3332 */ +const CVI_U32 sc3332_addr_byte = 2; +const CVI_U32 sc3332_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc3332_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC3332_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc3332_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc3332_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc3332_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc3332_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc3332_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc3332_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc3332_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc3332_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc3332_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc3332_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc3332_addr_byte + sc3332_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc3332_prog(VI_PIPE ViPipe, int *rom) +{ + int i = 0; + + while (1) { + int lookup = rom[i++]; + int addr = (lookup >> 16) & 0xFFFF; + int data = lookup & 0xFFFF; + + if (addr == 0xFFFE) + delay_ms(data); + else if (addr != 0xFFFF) + sc3332_write_register(ViPipe, addr, data); + } +} + +void sc3332_standby(VI_PIPE ViPipe) +{ + sc3332_write_register(ViPipe, 0x0100, 0x00); +} + +void sc3332_restart(VI_PIPE ViPipe) +{ + sc3332_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc3332_write_register(ViPipe, 0x0100, 0x01); +} + +void sc3332_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC3332[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC3332[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc3332_write_register(ViPipe, + g_pastSC3332[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC3332[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc3332_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc3332_write_register(ViPipe, 0x3221, val); +} + +int sc3332_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc3332_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc3332_read_register(ViPipe, SC3332_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc3332_read_register(ViPipe, SC3332_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC3332_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void sc3332_init(VI_PIPE ViPipe) +{ + sc3332_i2c_init(ViPipe); + + //linear mode only + sc3332_linear_1296P30_init(ViPipe); + + g_pastSC3332[ViPipe]->bInit = CVI_TRUE; +} + +void sc3332_exit(VI_PIPE ViPipe) +{ + sc3332_i2c_exit(ViPipe); +} + +/* 1296P30 and 1296P25 */ +static void sc3332_linear_1296P30_init(VI_PIPE ViPipe) +{ + sc3332_write_register(ViPipe, 0x0103, 0x01); + sc3332_write_register(ViPipe, 0x36e9, 0x80); + sc3332_write_register(ViPipe, 0x37f9, 0x80); + sc3332_write_register(ViPipe, 0x301f, 0x01); + sc3332_write_register(ViPipe, 0x30b8, 0x44); + sc3332_write_register(ViPipe, 0x3253, 0x10); + sc3332_write_register(ViPipe, 0x3301, 0x08); + sc3332_write_register(ViPipe, 0x3302, 0xff); + sc3332_write_register(ViPipe, 0x3305, 0x00); + sc3332_write_register(ViPipe, 0x3306, 0x90); + sc3332_write_register(ViPipe, 0x3308, 0x18); + sc3332_write_register(ViPipe, 0x330a, 0x01); + sc3332_write_register(ViPipe, 0x330b, 0xc0); + sc3332_write_register(ViPipe, 0x330d, 0x70); + sc3332_write_register(ViPipe, 0x330e, 0x30); + sc3332_write_register(ViPipe, 0x3314, 0x15); + sc3332_write_register(ViPipe, 0x3333, 0x10); + sc3332_write_register(ViPipe, 0x3334, 0x40); + sc3332_write_register(ViPipe, 0x335e, 0x06); + sc3332_write_register(ViPipe, 0x335f, 0x0a); + sc3332_write_register(ViPipe, 0x3364, 0x5e); + sc3332_write_register(ViPipe, 0x337d, 0x0e); + sc3332_write_register(ViPipe, 0x3390, 0x08); + sc3332_write_register(ViPipe, 0x3391, 0x09); + sc3332_write_register(ViPipe, 0x3392, 0x0f); + sc3332_write_register(ViPipe, 0x3393, 0x10); + sc3332_write_register(ViPipe, 0x3394, 0x80); + sc3332_write_register(ViPipe, 0x3395, 0xff); + sc3332_write_register(ViPipe, 0x33a2, 0x04); + sc3332_write_register(ViPipe, 0x33ad, 0x2c); + sc3332_write_register(ViPipe, 0x33b3, 0x48); + sc3332_write_register(ViPipe, 0x33f8, 0x00); + sc3332_write_register(ViPipe, 0x33f9, 0xc0); + sc3332_write_register(ViPipe, 0x33fa, 0x00); + sc3332_write_register(ViPipe, 0x33fb, 0xf0); + sc3332_write_register(ViPipe, 0x33fc, 0x0b); + sc3332_write_register(ViPipe, 0x33fd, 0x0f); + sc3332_write_register(ViPipe, 0x349f, 0x03); + sc3332_write_register(ViPipe, 0x34a6, 0x0b); + sc3332_write_register(ViPipe, 0x34a7, 0x0f); + sc3332_write_register(ViPipe, 0x34a8, 0x40); + sc3332_write_register(ViPipe, 0x34a9, 0x30); + sc3332_write_register(ViPipe, 0x34aa, 0x01); + sc3332_write_register(ViPipe, 0x34ab, 0xf0); + sc3332_write_register(ViPipe, 0x34ac, 0x02); + sc3332_write_register(ViPipe, 0x34ad, 0x10); + sc3332_write_register(ViPipe, 0x34f8, 0x1f); + sc3332_write_register(ViPipe, 0x34f9, 0x30); + sc3332_write_register(ViPipe, 0x3630, 0xf0); + sc3332_write_register(ViPipe, 0x3631, 0x8c); + sc3332_write_register(ViPipe, 0x3632, 0x78); + sc3332_write_register(ViPipe, 0x3633, 0x33); + sc3332_write_register(ViPipe, 0x363a, 0xcc); + sc3332_write_register(ViPipe, 0x363c, 0x0f); + sc3332_write_register(ViPipe, 0x363f, 0xc0); + sc3332_write_register(ViPipe, 0x3641, 0x00); + sc3332_write_register(ViPipe, 0x3650, 0x33); // LP 0x33 + sc3332_write_register(ViPipe, 0x3670, 0x5e); + sc3332_write_register(ViPipe, 0x3674, 0xf0); + sc3332_write_register(ViPipe, 0x3675, 0xf0); + sc3332_write_register(ViPipe, 0x3676, 0xd0); + sc3332_write_register(ViPipe, 0x3677, 0x87); + sc3332_write_register(ViPipe, 0x3678, 0x8a); + sc3332_write_register(ViPipe, 0x3679, 0x8d); + sc3332_write_register(ViPipe, 0x367c, 0x08); + sc3332_write_register(ViPipe, 0x367d, 0x0f); + sc3332_write_register(ViPipe, 0x367e, 0x08); + sc3332_write_register(ViPipe, 0x367f, 0x0f); + sc3332_write_register(ViPipe, 0x3690, 0x74); + sc3332_write_register(ViPipe, 0x3691, 0x78); + sc3332_write_register(ViPipe, 0x3692, 0x78); + sc3332_write_register(ViPipe, 0x3696, 0x33); + sc3332_write_register(ViPipe, 0x3697, 0x33); + sc3332_write_register(ViPipe, 0x3698, 0x45); + sc3332_write_register(ViPipe, 0x369c, 0x0b); + sc3332_write_register(ViPipe, 0x369d, 0x0f); + sc3332_write_register(ViPipe, 0x36a0, 0x09); + sc3332_write_register(ViPipe, 0x36a1, 0x0f); + sc3332_write_register(ViPipe, 0x36b0, 0x88); + sc3332_write_register(ViPipe, 0x36b1, 0x91); + sc3332_write_register(ViPipe, 0x36b2, 0xa4); + sc3332_write_register(ViPipe, 0x36b3, 0xcf); + sc3332_write_register(ViPipe, 0x36b4, 0x09); + sc3332_write_register(ViPipe, 0x36b5, 0x0b); + sc3332_write_register(ViPipe, 0x36b6, 0x0f); + sc3332_write_register(ViPipe, 0x370f, 0x01); + sc3332_write_register(ViPipe, 0x3722, 0x05); + sc3332_write_register(ViPipe, 0x3724, 0x31); + sc3332_write_register(ViPipe, 0x3771, 0x09); + sc3332_write_register(ViPipe, 0x3772, 0x05); + sc3332_write_register(ViPipe, 0x3773, 0x05); + sc3332_write_register(ViPipe, 0x377a, 0x0b); + sc3332_write_register(ViPipe, 0x377b, 0x0f); + sc3332_write_register(ViPipe, 0x3904, 0x04); + sc3332_write_register(ViPipe, 0x3905, 0x8c); + sc3332_write_register(ViPipe, 0x391d, 0x01); + sc3332_write_register(ViPipe, 0x3922, 0x1f); + sc3332_write_register(ViPipe, 0x3925, 0x0f); + sc3332_write_register(ViPipe, 0x3926, 0x21); + sc3332_write_register(ViPipe, 0x3933, 0x80); + sc3332_write_register(ViPipe, 0x3934, 0x03); + sc3332_write_register(ViPipe, 0x3937, 0x6f); + sc3332_write_register(ViPipe, 0x39dc, 0x02); + sc3332_write_register(ViPipe, 0x3e00, 0x00); + sc3332_write_register(ViPipe, 0x3e01, 0x54); + sc3332_write_register(ViPipe, 0x3e02, 0x00); + sc3332_write_register(ViPipe, 0x440e, 0x02); + sc3332_write_register(ViPipe, 0x4509, 0x28); + sc3332_write_register(ViPipe, 0x450d, 0x32); + sc3332_write_register(ViPipe, 0x5780, 0x66); + sc3332_write_register(ViPipe, 0x578d, 0x40); + sc3332_write_register(ViPipe, 0x36e9, 0x54); + sc3332_write_register(ViPipe, 0x37f9, 0x27); + + sc3332_default_reg_init(ViPipe); + + sc3332_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC3332 1296P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc3335/Makefile b/middleware/v2/component/isp/sensor/cv181x/sms_sc3335/Makefile new file mode 100644 index 000000000..3275dbe5c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc3335/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc3335.a +TARGET_SO = $(MW_LIB)/libsns_sc3335.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc3335/sc3335_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc3335/sc3335_cmos.c new file mode 100644 index 000000000..ef346714b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc3335/sc3335_cmos.c @@ -0,0 +1,1080 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc3335_cmos_ex.h" +#include "sc3335_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC3335_ID 3335 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC3335[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC3335_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC3335[dev]) +#define SC3335_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC3335[dev] = pstCtx) +#define SC3335_SENSOR_RESET_CTX(dev) (g_pastSC3335[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC3335_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC3335_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC3335_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc3335_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC3335 Lines Range*****/ +#define SC3335_FULL_LINES_MAX (0x7FFF) + +/*****SC3335 Register Address*****/ +#define SC3335_EXP_H_ADDR (0x3e00) +#define SC3335_EXP_M_ADDR (0x3e01) +#define SC3335_EXP_L_ADDR (0x3e02) + +#define SC3335_AGAIN_H_ADDR (0x3e08) +#define SC3335_AGAIN_L_ADDR (0x3e09) + +#define SC3335_DGAIN_H_ADDR (0x3e06) +#define SC3335_DGAIN_L_ADDR (0x3e07) + +#define SC3335_VMAX_H_ADDR (0x320e) +#define SC3335_VMAX_L_ADDR (0x320f) + +#define SC3335_GAIN_LOGIC_H_ADDR (0x363c) +#define SC3335_GAIN_LOGIC_L_ADDR (0x330e) + +#define SC3335_GAIN_DPC_ADDR (0x5799) +#define SC3335_HOLD_ADDR (0x3812) + +#define SC3335_RES_IS_1296P(w, h) ((w) <= 2304 && (h) <= 1296) + +#define SC3335_EXPACCURACY (0.5) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC3335_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC3335_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC3335_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC3335_EXPACCURACY; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = pstAeSnsDft->u32MaxIntTime; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC3335_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC3335_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC3335_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC3335_MODE_2304X1296P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC3335_FULL_LINES_MAX) ? SC3335_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = 2 * pstSnsState->u32FLStd - 10; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 3 + * max : 2 * vts - 10 + * step : 1 + */ + u32MinTime = 3; + u32MaxTime = 2 * pstSnsState->au32FL[0] - 10; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_M_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_ADDR].u32Data = ((u32TmpIntTime & 0x000F) << 4); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +typedef struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} gain_tbl_info_s; + +static struct gain_tbl_info_s AgainInfo[4] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x03, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x07, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 8128, + .idxBase = 128, + .regGain = 0x0F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 16256, + .idxBase = 192, + .regGain = 0x1F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, +}; +static CVI_U32 Again_table[256] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, 1248, 1263, 1280, + 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, 1472, 1487, 1504, 1519, 1536, 1552, + 1567, 1584, 1600, 1615, 1632, 1647, 1664, 1680, 1695, 1712, 1728, 1743, 1760, 1775, 1792, 1808, 1823, + 1840, 1856, 1871, 1888, 1903, 1920, 1936, 1951, 1968, 1984, 1999, 2016, 2031, 2048, 2079, 2112, 2144, + 2176, 2207, 2240, 2272, 2304, 2335, 2368, 2400, 2432, 2463, 2496, 2528, 2560, 2591, 2624, 2656, 2688, + 2719, 2752, 2784, 2816, 2847, 2880, 2912, 2944, 2975, 3008, 3040, 3072, 3103, 3136, 3168, 3200, 3231, + 3264, 3296, 3328, 3359, 3392, 3424, 3456, 3487, 3520, 3552, 3584, 3615, 3648, 3680, 3712, 3743, 3776, + 3808, 3840, 3871, 3904, 3936, 3968, 3999, 4032, 4064, 4096, 4160, 4224, 4288, 4352, 4416, 4480, 4544, + 4608, 4672, 4736, 4800, 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, 5504, 5568, 5632, + 5696, 5760, 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, 6464, 6528, 6592, 6656, 6720, + 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, 7424, 7488, 7552, 7616, 7680, 7744, 7808, + 7872, 7936, 8000, 8064, 8128, 8192, 8320, 8448, 8576, 8704, 8832, 8960, 9088, 9216, 9344, 9472, 9600, + 9728, 9856, 9984, 10112, 10240, 10368, 10496, 10624, 10752, 10880, 11008, 11136, 11264, 11392, 11520, + 11648, 11776, 11904, 12032, 12160, 12288, 12416, 12544, 12672, 12800, 12928, 13056, 13184, 13312, 13440, + 13568, 13696, 13824, 13952, 14080, 14208, 14336, 14464, 14592, 14720, 14848, 14976, 15104, 15232, 15360, + 15488, 15616, 15744, 15872, 16000, 16128, 16256 +}; + +static struct gain_tbl_info_s DgainInfo[5] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 8128, + .idxBase = 128, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 16256, + .idxBase = 192, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 32512, + .idxBase = 256, + .regGain = 0x0F, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, +}; + +static CVI_U32 Dgain_table[320] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, 1248, + 1263, 1280, 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, 1472, 1487, + 1504, 1519, 1536, 1552, 1567, 1584, 1600, 1615, 1632, 1647, 1664, 1680, 1695, 1712, 1728, + 1743, 1760, 1775, 1792, 1808, 1823, 1840, 1856, 1871, 1888, 1903, 1920, 1936, 1951, 1968, + 1984, 1999, 2016, 2031, 2048, 2079, 2112, 2144, 2176, 2207, 2240, 2272, 2304, 2335, 2368, + 2400, 2432, 2463, 2496, 2528, 2560, 2591, 2624, 2656, 2688, 2719, 2752, 2784, 2816, 2847, + 2880, 2912, 2944, 2975, 3008, 3040, 3072, 3103, 3136, 3168, 3200, 3231, 3264, 3296, 3328, + 3359, 3392, 3424, 3456, 3487, 3520, 3552, 3584, 3615, 3648, 3680, 3712, 3743, 3776, 3808, + 3840, 3871, 3904, 3936, 3968, 3999, 4032, 4064, 4096, 4160, 4224, 4288, 4352, 4416, 4480, + 4544, 4608, 4672, 4736, 4800, 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, + 5504, 5568, 5632, 5696, 5760, 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, + 6464, 6528, 6592, 6656, 6720, 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, + 7424, 7488, 7552, 7616, 7680, 7744, 7808, 7872, 7936, 8000, 8064, 8128, 8192, 8320, 8448, + 8576, 8704, 8832, 8960, 9088, 9216, 9344, 9472, 9600, 9728, 9856, 9984, 10112, 10240, 10368, + 10496, 10624, 10752, 10880, 11008, 11136, 11264, 11392, 11520, 11648, 11776, 11904, 12032, + 12160, 12288, 12416, 12544, 12672, 12800, 12928, 13056, 13184, 13312, 13440, 13568, 13696, + 13824, 13952, 14080, 14208, 14336, 14464, 14592, 14720, 14848, 14976, 15104, 15232, 15360, + 15488, 15616, 15744, 15872, 16000, 16128, 16256, 16384, 16640, 16896, 17152, 17408, 17664, + 17920, 18176, 18432, 18688, 18944, 19200, 19456, 19712, 19968, 20224, 20480, 20736, 20992, + 21248, 21504, 21760, 22016, 22272, 22528, 22784, 23040, 23296, 23552, 23808, 24064, 24320, + 24576, 24832, 25088, 25344, 25600, 25856, 26112, 26368, 26624, 26880, 27136, 27392, 27648, + 27904, 28160, 28416, 28672, 28928, 29184, 29440, 29696, 29952, 30208, 30464, 30720, 30976, + 31232, 31488, 31744, 32000, 32256, 32512 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[255]) { + *pu32AgainLin = Again_table[255]; + *pu32AgainDb = 255; + return CVI_SUCCESS; + } + + for (i = 1; i < 256; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[319]) { + *pu32DgainLin = Dgain_table[319]; + *pu32DgainDb = 319; + return CVI_SUCCESS; + } + + for (i = 1; i < 320; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L_ADDR].u32Data = (u32Again & 0xFF); + + /* gain logic setting. */ + if (sc3335_read_register(ViPipe, 0x3109) == 1) { + if (info->regGain < 0x07) { //gain < 2x + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_H_ADDR].u32Data = 0x05; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_L_ADDR].u32Data = 0x29; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } else if (info->regGain < 0x1F) { //2x <= gain < 8x + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_H_ADDR].u32Data = 0x07; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_L_ADDR].u32Data = 0x25; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } else { //gain > 8x + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_H_ADDR].u32Data = 0x07; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_L_ADDR].u32Data = 0x18; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } + } else { //2 == i2c_read(0x3109) || 3 == i2c_read(0x3109) + if (info->regGain < 0x07) { //gain < 2x + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_H_ADDR].u32Data = 0x06; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_L_ADDR].u32Data = 0x29; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } else if (info->regGain < 0x1F) { //2x <= gain < 8x + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_H_ADDR].u32Data = 0x08; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_L_ADDR].u32Data = 0x25; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } else { //gain > 8x + pstSnsRegsInfo->astI2cData[LINEAR_HOLD].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_H_ADDR].u32Data = 0x08; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_LOGIC_L_ADDR].u32Data = 0x18; + pstSnsRegsInfo->astI2cData[LINEAR_REL].u32Data = 0x30; + } + } + + /* gain DPC setting. */ + if ((info->regGain > 0x0F) || (info->regGain == 0x0F && u32Again >= 0x60)) { //gain >= 6x + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_DPC_ADDR].u32Data = 0x07; + } else if ((info->regGain < 0x0F) || (info->regGain == 0x0F && u32Again == 0x40)) { //gain <= 4x + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_DPC_ADDR].u32Data = 0x00; + } + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L_ADDR].u32Data = (u32Dgain & 0xFF); + + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC3335_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC3335_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC3335_MODE_2304X1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC3335_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC3335_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc3335_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc3335_addr_byte; + pstI2c_data[i].u32DataByteNum = sc3335_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC3335_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_M_ADDR].u32RegAddr = SC3335_EXP_M_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC3335_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H_ADDR].u32RegAddr = SC3335_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L_ADDR].u32RegAddr = SC3335_AGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC3335_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC3335_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC3335_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC3335_VMAX_L_ADDR; + pstI2c_data[LINEAR_GAIN_DPC_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_DPC_ADDR].u32RegAddr = SC3335_GAIN_DPC_ADDR; + pstI2c_data[LINEAR_HOLD].u32RegAddr = SC3335_HOLD_ADDR; + pstI2c_data[LINEAR_GAIN_LOGIC_H_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_LOGIC_H_ADDR].u32RegAddr = SC3335_GAIN_LOGIC_H_ADDR; + pstI2c_data[LINEAR_GAIN_LOGIC_L_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_LOGIC_L_ADDR].u32RegAddr = SC3335_GAIN_LOGIC_L_ADDR; + pstI2c_data[LINEAR_REL].u32RegAddr = SC3335_HOLD_ADDR; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update group hold or not*/ + if ((pstCfg0->snsCfg.astI2cData[LINEAR_GAIN_LOGIC_H_ADDR].bUpdate == CVI_TRUE) + || (pstCfg0->snsCfg.astI2cData[LINEAR_GAIN_LOGIC_L_ADDR].bUpdate == CVI_TRUE)) { + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + + /* DPC updata when A/Dgain change */ + if ((pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H_ADDR].bUpdate == CVI_TRUE) + || (pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L_ADDR].bUpdate == CVI_TRUE) + || (pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H_ADDR].bUpdate == CVI_TRUE) + || (pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L_ADDR].bUpdate == CVI_TRUE)) { + pstI2c_data[LINEAR_GAIN_DPC_ADDR].bUpdate = CVI_TRUE; + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC3335_RES_IS_1296P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC3335_MODE_2304X1296P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeSc3335_MirrorFip[ViPipe] != eSnsMirrorFlip) { + sc3335_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeSc3335_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC3335_MODE_S *pstMode = CVI_NULL; + + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC3335_MODE_2304X1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC3335_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc3335_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC3335_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC3335_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc3335_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc3335_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc3335_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc3335_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC3335_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC3335_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC3335_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC3335_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC3335_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC3335_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC3335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC3335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC3335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC3335_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC3335_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC3335_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc3335_standby, + .pfnRestart = sc3335_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = sc3335_write_register, + .pfnReadReg = sc3335_read_register, + .pfnSetBusInfo = sc3335_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc3335_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc3335/sc3335_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc3335/sc3335_cmos_ex.h new file mode 100644 index 000000000..8dc546b12 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc3335/sc3335_cmos_ex.h @@ -0,0 +1,86 @@ +#ifndef __SC3335_CMOS_EX_H_ +#define __SC3335_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc3335_linear_regs_e { + LINEAR_EXP_H_ADDR, + LINEAR_EXP_M_ADDR, + LINEAR_EXP_L_ADDR, + LINEAR_AGAIN_H_ADDR, + LINEAR_AGAIN_L_ADDR, + LINEAR_DGAIN_H_ADDR, + LINEAR_DGAIN_L_ADDR, + LINEAR_VMAX_H_ADDR, + LINEAR_VMAX_L_ADDR, + LINEAR_GAIN_DPC_ADDR, + LINEAR_HOLD, + LINEAR_GAIN_LOGIC_H_ADDR, + LINEAR_GAIN_LOGIC_L_ADDR, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +typedef enum _SC3335_MODE_E { + SC3335_MODE_2304X1296P30 = 0, + SC3335_MODE_LINEAR_NUM, + SC3335_MODE_2304X1296P30_WDR = SC3335_MODE_LINEAR_NUM, + SC3335_MODE_NUM +} SC3335_MODE_E; + +typedef struct _SC3335_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + char name[64]; +} SC3335_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC3335[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC3335_BusInfo[]; +extern CVI_U16 g_au16SC3335_GainMode[]; +extern CVI_U16 g_au16SC3335_L2SMode[]; +extern const CVI_U8 sc3335_i2c_addr; +extern const CVI_U32 sc3335_addr_byte; +extern const CVI_U32 sc3335_data_byte; +extern void sc3335_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void sc3335_init(VI_PIPE ViPipe); +extern void sc3335_exit(VI_PIPE ViPipe); +extern void sc3335_standby(VI_PIPE ViPipe); +extern void sc3335_restart(VI_PIPE ViPipe); +extern int sc3335_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc3335_read_register(VI_PIPE ViPipe, int addr); +extern int sc3335_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC3335_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc3335/sc3335_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc3335/sc3335_cmos_param.h new file mode 100644 index 000000000..138b6085a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc3335/sc3335_cmos_param.h @@ -0,0 +1,125 @@ +#ifndef __SC3335_CMOS_PARAM_H_ +#define __SC3335_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc3335_cmos_ex.h" + +static const SC3335_MODE_S g_astSC3335_mode[SC3335_MODE_NUM] = { + [SC3335_MODE_2304X1296P30] = { + .name = "1296p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2304, + .u32Height = 1296, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2304, + .u32Height = 1296, + }, + .stMaxSize = { + .u32Width = 2304, + .u32Height = 1296, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.24, /* 1350 * 30 / 0x7FFF */ + .u32HtsDef = 2500, + .u32VtsDef = 1350, + .stExp[0] = { + .u16Min = 3,//3 + .u16Max = 1350 * 2 - 10,//2 * vts - 10 + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 16256, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 32512, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc3335_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {1, 3, 0, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 8, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC3335_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc3335/sc3335_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc3335/sc3335_sensor_ctl.c new file mode 100644 index 000000000..a30ee1218 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc3335/sc3335_sensor_ctl.c @@ -0,0 +1,336 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc3335_cmos_ex.h" + +#define SC3335_CHIP_ID_HI_ADDR 0x3107 +#define SC3335_CHIP_ID_LO_ADDR 0x3108 +#define SC3335_CHIP_ID 0xcc1a + +static void sc3335_linear_1296P30_init(VI_PIPE ViPipe); + +const CVI_U8 sc3335_i2c_addr = 0x30; /* I2C Address of SC3335 */ +const CVI_U32 sc3335_addr_byte = 2; +const CVI_U32 sc3335_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc3335_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC3335_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc3335_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc3335_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc3335_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc3335_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc3335_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc3335_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc3335_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc3335_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc3335_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc3335_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc3335_addr_byte + sc3335_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc3335_standby(VI_PIPE ViPipe) +{ + sc3335_write_register(ViPipe, 0x0100, 0x00); +} + +void sc3335_restart(VI_PIPE ViPipe) +{ + sc3335_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc3335_write_register(ViPipe, 0x0100, 0x01); +} + +void sc3335_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC3335[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC3335[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc3335_write_register(ViPipe, + g_pastSC3335[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC3335[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc3335_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc3335_write_register(ViPipe, 0x3221, val); +} + + +int sc3335_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + delay_ms(4); + if (sc3335_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc3335_read_register(ViPipe, SC3335_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc3335_read_register(ViPipe, SC3335_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC3335_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void sc3335_init(VI_PIPE ViPipe) +{ + sc3335_i2c_init(ViPipe); + + //linear mode only + sc3335_linear_1296P30_init(ViPipe); + + g_pastSC3335[ViPipe]->bInit = CVI_TRUE; +} + +void sc3335_exit(VI_PIPE ViPipe) +{ + sc3335_i2c_exit(ViPipe); +} + +/* 1296P30 and 1296P25 */ +static void sc3335_linear_1296P30_init(VI_PIPE ViPipe) +{ + sc3335_write_register(ViPipe, 0x0103, 0x01); + delay_ms(33); + sc3335_write_register(ViPipe, 0x0100, 0x00); + sc3335_write_register(ViPipe, 0x36e9, 0x80); + sc3335_write_register(ViPipe, 0x36f9, 0x80); + sc3335_write_register(ViPipe, 0x301f, 0x01); + sc3335_write_register(ViPipe, 0x3253, 0x04); + sc3335_write_register(ViPipe, 0x3301, 0x04); + sc3335_write_register(ViPipe, 0x3302, 0x10); + sc3335_write_register(ViPipe, 0x3304, 0x40); + sc3335_write_register(ViPipe, 0x3306, 0x40); + sc3335_write_register(ViPipe, 0x3309, 0x50); + sc3335_write_register(ViPipe, 0x330b, 0xb6); + sc3335_write_register(ViPipe, 0x330e, 0x29); + sc3335_write_register(ViPipe, 0x3310, 0x06); + sc3335_write_register(ViPipe, 0x3314, 0x96); + sc3335_write_register(ViPipe, 0x331e, 0x39); + sc3335_write_register(ViPipe, 0x331f, 0x49); + sc3335_write_register(ViPipe, 0x3320, 0x09); + sc3335_write_register(ViPipe, 0x3333, 0x10); + sc3335_write_register(ViPipe, 0x334c, 0x01); + sc3335_write_register(ViPipe, 0x3364, 0x17); + sc3335_write_register(ViPipe, 0x3367, 0x01); + sc3335_write_register(ViPipe, 0x3390, 0x04); + sc3335_write_register(ViPipe, 0x3391, 0x08); + sc3335_write_register(ViPipe, 0x3392, 0x38); + sc3335_write_register(ViPipe, 0x3393, 0x05); + sc3335_write_register(ViPipe, 0x3394, 0x09); + sc3335_write_register(ViPipe, 0x3395, 0x16); + sc3335_write_register(ViPipe, 0x33ac, 0x0c); + sc3335_write_register(ViPipe, 0x33ae, 0x1c); + sc3335_write_register(ViPipe, 0x3622, 0x16); + sc3335_write_register(ViPipe, 0x3637, 0x22); + sc3335_write_register(ViPipe, 0x363a, 0x1f); + sc3335_write_register(ViPipe, 0x363c, 0x05); + sc3335_write_register(ViPipe, 0x3670, 0x0e); + sc3335_write_register(ViPipe, 0x3674, 0xb0); + sc3335_write_register(ViPipe, 0x3675, 0x88); + sc3335_write_register(ViPipe, 0x3676, 0x68); + sc3335_write_register(ViPipe, 0x3677, 0x84); + sc3335_write_register(ViPipe, 0x3678, 0x85); + sc3335_write_register(ViPipe, 0x3679, 0x86); + sc3335_write_register(ViPipe, 0x367c, 0x18); + sc3335_write_register(ViPipe, 0x367d, 0x38); + sc3335_write_register(ViPipe, 0x367e, 0x08); + sc3335_write_register(ViPipe, 0x367f, 0x18); + sc3335_write_register(ViPipe, 0x3690, 0x43); + sc3335_write_register(ViPipe, 0x3691, 0x43); + sc3335_write_register(ViPipe, 0x3692, 0x44); + sc3335_write_register(ViPipe, 0x369c, 0x18); + sc3335_write_register(ViPipe, 0x369d, 0x38); + sc3335_write_register(ViPipe, 0x36ea, 0x3b); + sc3335_write_register(ViPipe, 0x36eb, 0x0d); + sc3335_write_register(ViPipe, 0x36ec, 0x1c); + sc3335_write_register(ViPipe, 0x36ed, 0x24); + sc3335_write_register(ViPipe, 0x36fa, 0x3b); + sc3335_write_register(ViPipe, 0x36fb, 0x00); + sc3335_write_register(ViPipe, 0x36fc, 0x10); + sc3335_write_register(ViPipe, 0x36fd, 0x24); + sc3335_write_register(ViPipe, 0x3908, 0x82); + sc3335_write_register(ViPipe, 0x391f, 0x18); + sc3335_write_register(ViPipe, 0x3e01, 0xa8); + sc3335_write_register(ViPipe, 0x3e02, 0x20); + sc3335_write_register(ViPipe, 0x3f09, 0x48); + sc3335_write_register(ViPipe, 0x4505, 0x08); + sc3335_write_register(ViPipe, 0x4509, 0x20); + sc3335_write_register(ViPipe, 0x5799, 0x00); + sc3335_write_register(ViPipe, 0x59e0, 0x60); + sc3335_write_register(ViPipe, 0x59e1, 0x08); + sc3335_write_register(ViPipe, 0x59e2, 0x3f); + sc3335_write_register(ViPipe, 0x59e3, 0x18); + sc3335_write_register(ViPipe, 0x59e4, 0x18); + sc3335_write_register(ViPipe, 0x59e5, 0x3f); + sc3335_write_register(ViPipe, 0x59e6, 0x06); + sc3335_write_register(ViPipe, 0x59e7, 0x02); + sc3335_write_register(ViPipe, 0x59e8, 0x38); + sc3335_write_register(ViPipe, 0x59e9, 0x10); + sc3335_write_register(ViPipe, 0x59ea, 0x0c); + sc3335_write_register(ViPipe, 0x59eb, 0x10); + sc3335_write_register(ViPipe, 0x59ec, 0x04); + sc3335_write_register(ViPipe, 0x59ed, 0x02); + sc3335_write_register(ViPipe, 0x36e9, 0x23); + sc3335_write_register(ViPipe, 0x36f9, 0x23); + + sc3335_default_reg_init(ViPipe); + + sc3335_write_register(ViPipe, 0x0100, 0x01); + + delay_ms(100); + + printf("ViPipe:%d,===SC3335 1296P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc3336/Makefile b/middleware/v2/component/isp/sensor/cv181x/sms_sc3336/Makefile new file mode 100644 index 000000000..b6eacab4c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc3336/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc3336.a +TARGET_SO = $(MW_LIB)/libsns_sc3336.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc3336/sc3336_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc3336/sc3336_cmos.c new file mode 100644 index 000000000..73a73b14f --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc3336/sc3336_cmos.c @@ -0,0 +1,946 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc3336_cmos_ex.h" +#include "sc3336_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC3336_ID 3336 +#define SC3336_I2C_ADDR_1 0x30 +#define SC3336_I2C_ADDR_2 0x32 +#define SC3336_I2C_ADDR_IS_VALID(addr) ((addr) == SC3336_I2C_ADDR_1 || (addr) == SC3336_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC3336[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC3336_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC3336[dev]) +#define SC3336_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC3336[dev] = pstCtx) +#define SC3336_SENSOR_RESET_CTX(dev) (g_pastSC3336[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC3336_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC3336_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC3336_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc3336_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC3336 Lines Range*****/ +#define SC3336_FULL_LINES_MAX (0x7FFF) + +/*****SC3336 Register Address*****/ +#define SC3336_EXP_H_ADDR (0x3e00) +#define SC3336_EXP_M_ADDR (0x3e01) +#define SC3336_EXP_L_ADDR (0x3e02) + +#define SC3336_AGAIN_ADDR (0x3e09) + +#define SC3336_DGAIN_H_ADDR (0x3e06) +#define SC3336_DGAIN_L_ADDR (0x3e07) + +#define SC3336_VMAX_H_ADDR (0x320e) +#define SC3336_VMAX_L_ADDR (0x320f) + +#define SC3336_RES_IS_1296P(w, h) ((w) == 2304 && (h) == 1296) + +#define SC3336_EXPACCURACY (1) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC3336_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC3336_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC3336_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC3336_EXPACCURACY; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = pstMode->stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = pstAeSnsDft->u32MaxIntTime; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC3336_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC3336_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC3336_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC3336_MODE_2304X1296P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC3336_FULL_LINES_MAX) ? SC3336_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 10; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear exposure reg range: + * min : 0 + * max : vts - 10 + * step : 1 + */ + u32MinTime = 0; + u32MaxTime = pstSnsState->au32FL[0] - 10; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_M_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_ADDR].u32Data = ((u32TmpIntTime & 0x000F) << 4); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +typedef struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +} gain_tbl_info_s; + +static struct gain_tbl_info_s DgainInfo[4] = { + { + .gainMax = 2016, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 8064, + .idxBase = 64, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 16128, + .idxBase = 96, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, +}; + +static CVI_U32 Dgain_table[128] = { + 1024, 1055, 1088, 1120, 1152, 1183, 1216, 1248, 1280, 1311, 1344, 1376, + 1408, 1439, 1472, 1504, 1536, 1567, 1600, 1632, 1664, 1695, 1728, 1760, + 1792, 1823, 1856, 1888, 1920, 1951, 1984, 2016, 2048, 2112, 2176, 2240, + 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008, + 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, + 3840, 3904, 3968, 4032, 4096, 4224, 4352, 4480, 4608, 4736, 4864, 4992, + 5120, 5248, 5376, 5504, 5632, 5760, 5888, 6016, 6144, 6272, 6400, 6528, + 6656, 6784, 6912, 7040, 7168, 7296, 7424, 7552, 7680, 7808, 7936, 8064, + 8192, 8448, 8704, 8960, 9216, 9472, 9728, 9984, 10240, 10496, 10752, 11008, + 11264, 11520, 11776, 12032, 12288, 12544, 12800, 13056, 13312, 13568, 13824, + 14080, 14336, 14592, 14848, 15104, 15360, 15616, 15872, 16128 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 again = *pu32AgainLin; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (again < 1556) { + *pu32AgainDb = 0x00; + *pu32AgainLin = 1024; + } else if (again < 3122) { + *pu32AgainDb = 0x40; + *pu32AgainLin = 1556; + } else if (again < 6225) { + *pu32AgainDb = 0x48; + *pu32AgainLin = 3122; + } else if (again < 12451) { + *pu32AgainDb = 0x49; + *pu32AgainLin = 6225; + } else if (again < 24903) { + *pu32AgainDb = 0x4b; + *pu32AgainLin = 12451; + } else if (again < 49807) { + *pu32AgainDb = 0x4f; + *pu32AgainLin = 24903; + } else { + *pu32AgainDb = 0x5f; + *pu32AgainLin = 49807; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[127]) { + *pu32DgainLin = Dgain_table[127]; + *pu32DgainDb = 127; + return CVI_SUCCESS; + } + + for (i = 1; i < 128; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L_ADDR].u32Data = (u32Dgain & 0xFF); + + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC3336_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC3336_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC3336_MODE_2304X1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC3336_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC3336_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc3336_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc3336_addr_byte; + pstI2c_data[i].u32DataByteNum = sc3336_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC3336_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_M_ADDR].u32RegAddr = SC3336_EXP_M_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC3336_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = SC3336_AGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC3336_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC3336_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC3336_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC3336_VMAX_L_ADDR; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC3336_RES_IS_1296P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC3336_MODE_2304X1296P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeSc3336_MirrorFip[ViPipe] != eSnsMirrorFlip) { + sc3336_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeSc3336_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC3336_MODE_S *pstMode = CVI_NULL; + + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC3336_MODE_2304X1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC3336_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc3336_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC3336_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC3336_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc3336_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc3336_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc3336_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (SC3336_I2C_ADDR_IS_VALID(s32I2cAddr)) + sc3336_i2c_addr = s32I2cAddr; +} + +static CVI_S32 sc3336_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC3336_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC3336_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC3336_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC3336_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC3336_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC3336_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC3336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC3336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC3336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC3336_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC3336_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC3336_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc3336_standby, + .pfnRestart = sc3336_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = sc3336_write_register, + .pfnReadReg = sc3336_read_register, + .pfnSetBusInfo = sc3336_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc3336_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc3336/sc3336_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc3336/sc3336_cmos_ex.h new file mode 100644 index 000000000..9f0557466 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc3336/sc3336_cmos_ex.h @@ -0,0 +1,80 @@ +#ifndef __SC3336_CMOS_EX_H_ +#define __SC3336_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc3336_linear_regs_e { + LINEAR_EXP_H_ADDR, + LINEAR_EXP_M_ADDR, + LINEAR_EXP_L_ADDR, + LINEAR_AGAIN_ADDR, + LINEAR_DGAIN_H_ADDR, + LINEAR_DGAIN_L_ADDR, + LINEAR_VMAX_H_ADDR, + LINEAR_VMAX_L_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC3336_MODE_E { + SC3336_MODE_2304X1296P30 = 0, + SC3336_MODE_LINEAR_NUM, + SC3336_MODE_2304X1296P30_WDR = SC3336_MODE_LINEAR_NUM, + SC3336_MODE_NUM +} SC3336_MODE_E; + +typedef struct _SC3336_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + char name[64]; +} SC3336_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC3336[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC3336_BusInfo[]; +extern CVI_U16 g_au16SC3336_GainMode[]; +extern CVI_U16 g_au16SC3336_L2SMode[]; +extern CVI_U8 sc3336_i2c_addr; +extern const CVI_U32 sc3336_addr_byte; +extern const CVI_U32 sc3336_data_byte; +extern void sc3336_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void sc3336_init(VI_PIPE ViPipe); +extern void sc3336_exit(VI_PIPE ViPipe); +extern void sc3336_standby(VI_PIPE ViPipe); +extern void sc3336_restart(VI_PIPE ViPipe); +extern int sc3336_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc3336_read_register(VI_PIPE ViPipe, int addr); +extern int sc3336_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC3336_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc3336/sc3336_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc3336/sc3336_cmos_param.h new file mode 100644 index 000000000..f3d2a4623 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc3336/sc3336_cmos_param.h @@ -0,0 +1,121 @@ +#ifndef __SC3336_CMOS_PARAM_H_ +#define __SC3336_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc3336_cmos_ex.h" + +static const SC3336_MODE_S g_astSC3336_mode[SC3336_MODE_NUM] = { + [SC3336_MODE_2304X1296P30] = { + .name = "1296p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2304, + .u32Height = 1296, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2304, + .u32Height = 1296, + }, + .stMaxSize = { + .u32Width = 2304, + .u32Height = 1296, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.24, /* 1350 * 30 / 0x7FFF */ + .u32HtsDef = 4938, + .u32VtsDef = 1350, + .stExp[0] = { + .u16Min = 0, + .u16Max = 1340,//vts - 10 + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 49807, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 16128, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc3336_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {0, 1, 2, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC3336_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc3336/sc3336_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc3336/sc3336_sensor_ctl.c new file mode 100644 index 000000000..8baf914e7 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc3336/sc3336_sensor_ctl.c @@ -0,0 +1,377 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc3336_cmos_ex.h" + +#define SC3336_CHIP_ID_HI_ADDR 0x3107 +#define SC3336_CHIP_ID_LO_ADDR 0x3108 +#define SC3336_CHIP_ID 0xcc41 + +static void sc3336_linear_1296P30_init(VI_PIPE ViPipe); + +CVI_U8 sc3336_i2c_addr = 0x30; /* I2C Address of SC3336 */ +const CVI_U32 sc3336_addr_byte = 2; +const CVI_U32 sc3336_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc3336_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC3336_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc3336_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc3336_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc3336_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc3336_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc3336_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc3336_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc3336_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc3336_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc3336_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc3336_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc3336_addr_byte + sc3336_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc3336_standby(VI_PIPE ViPipe) +{ + sc3336_write_register(ViPipe, 0x0100, 0x00); +} + +void sc3336_restart(VI_PIPE ViPipe) +{ + sc3336_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc3336_write_register(ViPipe, 0x0100, 0x01); +} + +void sc3336_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC3336[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC3336[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc3336_write_register(ViPipe, + g_pastSC3336[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC3336[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc3336_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc3336_write_register(ViPipe, 0x3221, val); +} + +int sc3336_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + delay_ms(4); + if (sc3336_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc3336_read_register(ViPipe, SC3336_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc3336_read_register(ViPipe, SC3336_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC3336_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void sc3336_init(VI_PIPE ViPipe) +{ + sc3336_i2c_init(ViPipe); + + //linear mode only + sc3336_linear_1296P30_init(ViPipe); + + g_pastSC3336[ViPipe]->bInit = CVI_TRUE; +} + +void sc3336_exit(VI_PIPE ViPipe) +{ + sc3336_i2c_exit(ViPipe); +} + +/* 1296P30 and 1296P25 */ +static void sc3336_linear_1296P30_init(VI_PIPE ViPipe) +{ + sc3336_write_register(ViPipe, 0x0103, 0x01); + sc3336_write_register(ViPipe, 0x36e9, 0x80); + sc3336_write_register(ViPipe, 0x37f9, 0x80); + sc3336_write_register(ViPipe, 0x301f, 0x01); + sc3336_write_register(ViPipe, 0x30b8, 0x33); + sc3336_write_register(ViPipe, 0x3253, 0x10); + sc3336_write_register(ViPipe, 0x325f, 0x20); + sc3336_write_register(ViPipe, 0x3301, 0x04); + sc3336_write_register(ViPipe, 0x3306, 0x50); + sc3336_write_register(ViPipe, 0x3309, 0xa8); + sc3336_write_register(ViPipe, 0x330a, 0x00); + sc3336_write_register(ViPipe, 0x330b, 0xd8); + sc3336_write_register(ViPipe, 0x3314, 0x13); + sc3336_write_register(ViPipe, 0x331f, 0x99); + sc3336_write_register(ViPipe, 0x3333, 0x10); + sc3336_write_register(ViPipe, 0x3334, 0x40); + sc3336_write_register(ViPipe, 0x335e, 0x06); + sc3336_write_register(ViPipe, 0x335f, 0x0a); + sc3336_write_register(ViPipe, 0x3364, 0x5e); + sc3336_write_register(ViPipe, 0x337c, 0x02); + sc3336_write_register(ViPipe, 0x337d, 0x0e); + sc3336_write_register(ViPipe, 0x3390, 0x01); + sc3336_write_register(ViPipe, 0x3391, 0x03); + sc3336_write_register(ViPipe, 0x3392, 0x07); + sc3336_write_register(ViPipe, 0x3393, 0x04); + sc3336_write_register(ViPipe, 0x3394, 0x04); + sc3336_write_register(ViPipe, 0x3395, 0x04); + sc3336_write_register(ViPipe, 0x3396, 0x08); + sc3336_write_register(ViPipe, 0x3397, 0x0b); + sc3336_write_register(ViPipe, 0x3398, 0x1f); + sc3336_write_register(ViPipe, 0x3399, 0x04); + sc3336_write_register(ViPipe, 0x339a, 0x0a); + sc3336_write_register(ViPipe, 0x339b, 0x3a); + sc3336_write_register(ViPipe, 0x339c, 0xa0); + sc3336_write_register(ViPipe, 0x33a2, 0x04); + sc3336_write_register(ViPipe, 0x33ac, 0x08); + sc3336_write_register(ViPipe, 0x33ad, 0x1c); + sc3336_write_register(ViPipe, 0x33ae, 0x10); + sc3336_write_register(ViPipe, 0x33af, 0x30); + sc3336_write_register(ViPipe, 0x33b1, 0x80); + sc3336_write_register(ViPipe, 0x33b3, 0x48); + sc3336_write_register(ViPipe, 0x33f9, 0x60); + sc3336_write_register(ViPipe, 0x33fb, 0x74); + sc3336_write_register(ViPipe, 0x33fc, 0x4b); + sc3336_write_register(ViPipe, 0x33fd, 0x5f); + sc3336_write_register(ViPipe, 0x349f, 0x03); + sc3336_write_register(ViPipe, 0x34a6, 0x4b); + sc3336_write_register(ViPipe, 0x34a7, 0x5f); + sc3336_write_register(ViPipe, 0x34a8, 0x20); + sc3336_write_register(ViPipe, 0x34a9, 0x18); + sc3336_write_register(ViPipe, 0x34ab, 0xe8); + sc3336_write_register(ViPipe, 0x34ac, 0x01); + sc3336_write_register(ViPipe, 0x34ad, 0x00); + sc3336_write_register(ViPipe, 0x34f8, 0x5f); + sc3336_write_register(ViPipe, 0x34f9, 0x18); + sc3336_write_register(ViPipe, 0x3630, 0xc0); + sc3336_write_register(ViPipe, 0x3631, 0x84); + sc3336_write_register(ViPipe, 0x3632, 0x64); + sc3336_write_register(ViPipe, 0x3633, 0x32); + sc3336_write_register(ViPipe, 0x363b, 0x03); + sc3336_write_register(ViPipe, 0x363c, 0x08); + sc3336_write_register(ViPipe, 0x3641, 0x38); + sc3336_write_register(ViPipe, 0x3670, 0x4e); + sc3336_write_register(ViPipe, 0x3674, 0xc0); + sc3336_write_register(ViPipe, 0x3675, 0xc0); + sc3336_write_register(ViPipe, 0x3676, 0xc0); + sc3336_write_register(ViPipe, 0x3677, 0x86); + sc3336_write_register(ViPipe, 0x3678, 0x86); + sc3336_write_register(ViPipe, 0x3679, 0x86); + sc3336_write_register(ViPipe, 0x367c, 0x48); + sc3336_write_register(ViPipe, 0x367d, 0x49); + sc3336_write_register(ViPipe, 0x367e, 0x4b); + sc3336_write_register(ViPipe, 0x367f, 0x5f); + sc3336_write_register(ViPipe, 0x3690, 0x32); + sc3336_write_register(ViPipe, 0x3691, 0x32); + sc3336_write_register(ViPipe, 0x3692, 0x42); + sc3336_write_register(ViPipe, 0x369c, 0x4b); + sc3336_write_register(ViPipe, 0x369d, 0x5f); + sc3336_write_register(ViPipe, 0x36b0, 0x87); + sc3336_write_register(ViPipe, 0x36b1, 0x90); + sc3336_write_register(ViPipe, 0x36b2, 0xa1); + sc3336_write_register(ViPipe, 0x36b3, 0xd8); + sc3336_write_register(ViPipe, 0x36b4, 0x49); + sc3336_write_register(ViPipe, 0x36b5, 0x4b); + sc3336_write_register(ViPipe, 0x36b6, 0x4f); + sc3336_write_register(ViPipe, 0x370f, 0x01); + sc3336_write_register(ViPipe, 0x3722, 0x09); + sc3336_write_register(ViPipe, 0x3724, 0x41); + sc3336_write_register(ViPipe, 0x3725, 0xc1); + sc3336_write_register(ViPipe, 0x3771, 0x09); + sc3336_write_register(ViPipe, 0x3772, 0x09); + sc3336_write_register(ViPipe, 0x3773, 0x05); + sc3336_write_register(ViPipe, 0x377a, 0x48); + sc3336_write_register(ViPipe, 0x377b, 0x5f); + sc3336_write_register(ViPipe, 0x3904, 0x04); + sc3336_write_register(ViPipe, 0x3905, 0x8c); + sc3336_write_register(ViPipe, 0x391d, 0x04); + sc3336_write_register(ViPipe, 0x3921, 0x20); + sc3336_write_register(ViPipe, 0x3926, 0x21); + sc3336_write_register(ViPipe, 0x3933, 0x80); + sc3336_write_register(ViPipe, 0x3934, 0x0a); + sc3336_write_register(ViPipe, 0x3935, 0x00); + sc3336_write_register(ViPipe, 0x3936, 0x2a); + sc3336_write_register(ViPipe, 0x3937, 0x6a); + sc3336_write_register(ViPipe, 0x3938, 0x6a); + sc3336_write_register(ViPipe, 0x39dc, 0x02); + sc3336_write_register(ViPipe, 0x3e01, 0x53); + sc3336_write_register(ViPipe, 0x3e02, 0xe0); + sc3336_write_register(ViPipe, 0x3e09, 0x00); + sc3336_write_register(ViPipe, 0x440e, 0x02); + sc3336_write_register(ViPipe, 0x4509, 0x20); + sc3336_write_register(ViPipe, 0x5ae0, 0xfe); + sc3336_write_register(ViPipe, 0x5ae1, 0x40); + sc3336_write_register(ViPipe, 0x5ae2, 0x38); + sc3336_write_register(ViPipe, 0x5ae3, 0x30); + sc3336_write_register(ViPipe, 0x5ae4, 0x28); + sc3336_write_register(ViPipe, 0x5ae5, 0x38); + sc3336_write_register(ViPipe, 0x5ae6, 0x30); + sc3336_write_register(ViPipe, 0x5ae7, 0x28); + sc3336_write_register(ViPipe, 0x5ae8, 0x3f); + sc3336_write_register(ViPipe, 0x5ae9, 0x34); + sc3336_write_register(ViPipe, 0x5aea, 0x2c); + sc3336_write_register(ViPipe, 0x5aeb, 0x3f); + sc3336_write_register(ViPipe, 0x5aec, 0x34); + sc3336_write_register(ViPipe, 0x5aed, 0x2c); + sc3336_write_register(ViPipe, 0x36e9, 0x54); + sc3336_write_register(ViPipe, 0x37f9, 0x27); + + sc3336_default_reg_init(ViPipe); + + sc3336_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC3336 1296P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc401ai/Makefile b/middleware/v2/component/isp/sensor/cv181x/sms_sc401ai/Makefile new file mode 100644 index 000000000..8a86adaba --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc401ai/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc401ai.a +TARGET_SO = $(MW_LIB)/libsns_sc401ai.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc401ai/sc401ai_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc401ai/sc401ai_cmos.c new file mode 100644 index 000000000..b75871c9d --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc401ai/sc401ai_cmos.c @@ -0,0 +1,1035 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc401ai_cmos_ex.h" +#include "sc401ai_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC401AI_ID 401 +#define SC401AI_I2C_ADDR_1 0x30 +#define SC401AI_I2C_ADDR_2 0x32 +#define SC401AI_I2C_ADDR_IS_VALID(addr) ((addr) == SC401AI_I2C_ADDR_1 || (addr) == SC401AI_I2C_ADDR_2) + +#define SENSOR_SC401AI_WIDTH 2560 +#define SENSOR_SC401AI_HEIGHT 1440 + +#define SC401AI_EXPACCURACY (0.5) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC401AI[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC401AI_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC401AI[dev]) +#define SC401AI_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC401AI[dev] = pstCtx) +#define SC401AI_SENSOR_RESET_CTX(dev) (g_pastSC401AI[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC401AI_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC401AI_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC401AI_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC401AI Lines Range*****/ +#define SC401AI_FULL_LINES_MAX (0x7FFF) + +/*****SC401AI Register Address*****/ +#define SC401AI_SHS1_0_ADDR 0x3E00 //bit[3:0] H +#define SC401AI_SHS1_1_ADDR 0x3E01 //bit[7:0] M +#define SC401AI_SHS1_2_ADDR 0x3E02 //bit[7:4] L + +#define SC401AI_AGAIN_ADDR 0x3E08 +#define SC401AI_A_FINEGAIN_ADDR 0x3E09 +#define SC401AI_DGAIN_ADDR 0x3E06 +#define SC401AI_D_FINEGAIN_ADDR 0x3E07 + +#define SC401AI_VMAX_ADDR 0x320E //(0x320e[6:0],0x320f) + +#define SC401AI_RES_IS_1440P(w, h) ((w) == 2560 && (h) == 1440) +#define SC401AI_RES_IS_1296P(w, h) ((w) == 2304 && (h) == 1296) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC401AI_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC401AI_EXPACCURACY; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astSC401AI_mode[pstSnsState->u8ImgMode].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC401AI_mode[pstSnsState->u8ImgMode].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = g_astSC401AI_mode[pstSnsState->u8ImgMode].stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = g_astSC401AI_mode[pstSnsState->u8ImgMode].stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astSC401AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = g_astSC401AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = g_astSC401AI_mode[pstSnsState->u8ImgMode].stExp[0].u32Max; + pstAeSnsDft->u32MinIntTime = g_astSC401AI_mode[pstSnsState->u8ImgMode].stExp[0].u32Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC401AI_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC401AI_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC401AI_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC401AI_MODE_1440P30: + case SC401AI_MODE_1296P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC401AI_FULL_LINES_MAX) ? SC401AI_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0x7F00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = (pstSnsState->u32FLStd << 1) - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + CVI_U32 u32TmpIntTime = u32IntTime[0]; + /* linear exposure reg range: + * min : 3 + * max : 2 * (vts - 8) + * step : 1(1 means step is 0.5 line) + */ + u32TmpIntTime = (u32TmpIntTime > ((pstSnsState->au32FL[0] << 1) - 8)) ? + ((pstSnsState->au32FL[0] << 1) - 8) : u32TmpIntTime; + if (!u32TmpIntTime) + u32TmpIntTime = 3; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); //bit[15:12] + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); //bit[11:4] + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = ((u32TmpIntTime & 0x000F) << 4); //bit[7:4] + + return CVI_SUCCESS; + +} + +struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +}; + +static struct gain_tbl_info_s AgainInfo[5] = { + { + .gainMax = 1487, + .idxBase = 0, + .regGain = 0x03, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 2984, + .idxBase = 30, + .regGain = 0x23, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 5969, + .idxBase = 94, + .regGain = 0x27, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 11939, + .idxBase = 158, + .regGain = 0x2F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 23879, + .idxBase = 222, + .regGain = 0x3F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, +}; + +static CVI_U32 Again_table[286] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, 1248, 1263, 1280, + 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, 1472, 1487, 1504, 1527, 1551, 1574, + 1598, 1622, 1645, 1669, 1692, 1716, 1739, 1762, 1785, 1809, 1832, 1856, 1880, 1903, 1927, 1950, 1974, + 1997, 2021, 2044, 2068, 2092, 2115, 2139, 2162, 2186, 2209, 2233, 2256, 2279, 2302, 2326, 2350, 2373, + 2397, 2420, 2444, 2467, 2491, 2514, 2538, 2562, 2585, 2609, 2632, 2656, 2679, 2703, 2726, 2750, 2772, + 2796, 2820, 2843, 2867, 2890, 2914, 2937, 2961, 2984, 3008, 3055, 3102, 3149, 3196, 3244, 3290, 3337, + 3384, 3431, 3478, 3525, 3572, 3619, 3666, 3714, 3761, 3807, 3854, 3901, 3948, 3995, 4042, 4089, 4136, + 4184, 4231, 4277, 4324, 4371, 4418, 4465, 4512, 4559, 4606, 4654, 4701, 4748, 4794, 4841, 4888, 4935, + 4982, 5029, 5076, 5124, 5171, 5218, 5265, 5311, 5358, 5405, 5452, 5499, 5547, 5594, 5641, 5688, 5735, + 5781, 5828, 5875, 5922, 5969, 6017, 6111, 6205, 6298, 6392, 6487, 6581, 6675, 6769, 6862, 6957, 7051, + 7145, 7239, 7332, 7427, 7521, 7615, 7709, 7802, 7897, 7991, 8085, 8179, 8273, 8367, 8461, 8555, 8649, + 8743, 8837, 8931, 9025, 9119, 9213, 9307, 9401, 9495, 9589, 9683, 9778, 9871, 9965, 10059, 10153, 10248, + 10341, 10435, 10529, 10624, 10718, 10811, 10905, 10999, 11094, 11188, 11282, 11375, 11469, 11564, 11658, + 11752, 11845, 11939, 12034, 12222, 12409, 12598, 12786, 12974, 13162, 13349, 13538, 13726, 13914, 14102, + 14290, 14478, 14666, 14854, 15042, 15230, 15418, 15606, 15795, 15982, 16171, 16358, 16546, 16735, 16922, + 17111, 17299, 17486, 17675, 17862, 18051, 18239, 18426, 18615, 18803, 18991, 19179, 19366, 19555, 19743, + 19931, 20119, 20307, 20495, 20683, 20871, 21059, 21248, 21435, 21623, 21812, 21999, 22188, 22375, 22563, + 22752, 22939, 23128, 23316, 23503, 23692, 23879 +}; + +static struct gain_tbl_info_s DgainInfo[5] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 8128, + .idxBase = 128, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 16256, + .idxBase = 192, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 32512, + .idxBase = 256, + .regGain = 0x0f, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, +}; + +static CVI_U32 Dgain_table[320] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, 1248, + 1263, 1280, 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, 1472, 1487, + 1504, 1519, 1536, 1552, 1567, 1584, 1600, 1615, 1632, 1647, 1664, 1680, 1695, 1712, 1728, + 1743, 1760, 1775, 1792, 1808, 1823, 1840, 1856, 1871, 1888, 1903, 1920, 1936, 1951, 1968, + 1984, 1999, 2016, 2031, 2048, 2079, 2112, 2144, 2176, 2207, 2240, 2272, 2304, 2335, 2368, + 2400, 2432, 2463, 2496, 2528, 2560, 2591, 2624, 2656, 2688, 2719, 2752, 2784, 2816, 2847, + 2880, 2912, 2944, 2975, 3008, 3040, 3072, 3103, 3136, 3168, 3200, 3231, 3264, 3296, 3328, + 3359, 3392, 3424, 3456, 3487, 3520, 3552, 3584, 3615, 3648, 3680, 3712, 3743, 3776, 3808, + 3840, 3871, 3904, 3936, 3968, 3999, 4032, 4064, 4096, 4160, 4224, 4288, 4352, 4416, 4480, + 4544, 4608, 4672, 4736, 4800, 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, + 5504, 5568, 5632, 5696, 5760, 5824, 5888, 5952, 6016, 6080, 6144, 6208, 6272, 6336, 6400, + 6464, 6528, 6592, 6656, 6720, 6784, 6848, 6912, 6976, 7040, 7104, 7168, 7232, 7296, 7360, + 7424, 7488, 7552, 7616, 7680, 7744, 7808, 7872, 7936, 8000, 8064, 8128, 8192, 8320, 8448, + 8576, 8704, 8832, 8960, 9088, 9216, 9344, 9472, 9600, 9728, 9856, 9984, 10112, 10240, 10368, + 10496, 10624, 10752, 10880, 11008, 11136, 11264, 11392, 11520, 11648, 11776, 11904, 12032, + 12160, 12288, 12416, 12544, 12672, 12800, 12928, 13056, 13184, 13312, 13440, 13568, 13696, + 13824, 13952, 14080, 14208, 14336, 14464, 14592, 14720, 14848, 14976, 15104, 15232, 15360, + 15488, 15616, 15744, 15872, 16000, 16128, 16256, 16384, 16640, 16896, 17152, 17408, 17664, + 17920, 18176, 18432, 18688, 18944, 19200, 19456, 19712, 19968, 20224, 20480, 20736, 20992, + 21248, 21504, 21760, 22016, 22272, 22528, 22784, 23040, 23296, 23552, 23808, 24064, 24320, + 24576, 24832, 25088, 25344, 25600, 25856, 26112, 26368, 26624, 26880, 27136, 27392, 27648, + 27904, 28160, 28416, 28672, 28928, 29184, 29440, 29696, 29952, 30208, 30464, 30720, 30976, + 31232, 31488, 31744, 32000, 32256, 32512 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[285]) { + *pu32AgainLin = Again_table[285]; + *pu32AgainDb = 285; + return CVI_SUCCESS; + } + + for (i = 1; i < 286; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[319]) { + *pu32DgainLin = Dgain_table[319]; + *pu32DgainDb = 319; + return CVI_SUCCESS; + } + + for (i = 1; i < 320; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_A_FINEGAIN_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_D_FINEGAIN_ADDR].u32Data = (u32Dgain & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + (void) u16ManRatioEnable; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC401AI_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC401AI_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == SC401AI_MODE_1440P30) + pstSnsState->u8ImgMode = SC401AI_MODE_1440P30; + else if (pstSnsState->u8ImgMode == SC401AI_MODE_1296P30) + pstSnsState->u8ImgMode = SC401AI_MODE_1296P30; + + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC401AI_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC401AI_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc401ai_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc401ai_addr_byte; + pstI2c_data[i].u32DataByteNum = sc401ai_data_byte; + } + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC401AI_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC401AI_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC401AI_SHS1_2_ADDR; + + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = SC401AI_AGAIN_ADDR; + pstI2c_data[LINEAR_A_FINEGAIN_ADDR].u32RegAddr = SC401AI_A_FINEGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_ADDR].u32RegAddr = SC401AI_DGAIN_ADDR; + pstI2c_data[LINEAR_D_FINEGAIN_ADDR].u32RegAddr = SC401AI_D_FINEGAIN_ADDR; + + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC401AI_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC401AI_VMAX_ADDR + 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC401AI_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = SC401AI_MODE_1440P30; + else if (SC401AI_RES_IS_1296P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = SC401AI_MODE_1296P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC401AI_MODE_S *pstMode = CVI_NULL; + + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC401AI_MODE_1440P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC401AI_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC401AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc401ai_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC401AI_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC401AI_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc401ai_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc401ai_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc401ai_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (SC401AI_I2C_ADDR_IS_VALID(s32I2cAddr)) + sc401ai_i2c_addr = s32I2cAddr; +} + +static CVI_S32 sc401ai_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC401AI_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC401AI_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC401AI_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC401AI_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC401AI_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC401AI_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC401AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC401AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC401AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC401AI_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC401AI_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC401AI_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc401ai_standby, + .pfnRestart = sc401ai_restart, + .pfnMirrorFlip = sc401ai_mirror_flip, + .pfnWriteReg = sc401ai_write_register, + .pfnReadReg = sc401ai_read_register, + .pfnSetBusInfo = sc401ai_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc401ai_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc401ai/sc401ai_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc401ai/sc401ai_cmos_ex.h new file mode 100644 index 000000000..c7c3d3339 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc401ai/sc401ai_cmos_ex.h @@ -0,0 +1,80 @@ +#ifndef __SC401AI_CMOS_EX_H_ +#define __SC401AI_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc401ai_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_2_ADDR, + LINEAR_AGAIN_ADDR, + LINEAR_A_FINEGAIN_ADDR, + LINEAR_DGAIN_ADDR, + LINEAR_D_FINEGAIN_ADDR, + LINEAR_VMAX_0_ADDR, + LINEAR_VMAX_1_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC401AI_MODE_E { + SC401AI_MODE_1440P30 = 0, + SC401AI_MODE_1296P30, + SC401AI_MODE_NUM +} SC401AI_MODE_E; + +typedef struct _SC401AI_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_LARGE_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} SC401AI_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC401AI[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC401AI_BusInfo[]; +extern CVI_U16 g_au16SC401AI_GainMode[]; +extern CVI_U16 g_au16SC401AI_L2SMode[]; +extern CVI_U8 sc401ai_i2c_addr; +extern const CVI_U32 sc401ai_addr_byte; +extern const CVI_U32 sc401ai_data_byte; +extern void sc401ai_init(VI_PIPE ViPipe); +extern void sc401ai_exit(VI_PIPE ViPipe); +extern void sc401ai_standby(VI_PIPE ViPipe); +extern void sc401ai_restart(VI_PIPE ViPipe); +extern int sc401ai_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc401ai_read_register(VI_PIPE ViPipe, int addr); +extern void sc401ai_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc401ai_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC401AI_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc401ai/sc401ai_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc401ai/sc401ai_cmos_param.h new file mode 100644 index 000000000..a5603f355 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc401ai/sc401ai_cmos_param.h @@ -0,0 +1,262 @@ +#ifndef __SC401AI_CMOS_PARAM_H_ +#define __SC401AI_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc401ai_cmos_ex.h" + +static const SC401AI_MODE_S g_astSC401AI_mode[SC401AI_MODE_NUM] = { + [SC401AI_MODE_1440P30] = { + .name = "1440p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.37, /* 1500 * 30 / 0x7FFF*/ + .u32HtsDef = 2800, + .u32VtsDef = 1500, + .stExp[0] = { + .u32Min = 3, + .u32Max = 2992, //2*vts - 8 + .u32Def = 1500, //30fps + .u32Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 23879, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 32512, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [SC401AI_MODE_1296P30] = { + .name = "1296p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2304, + .u32Height = 1296, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2304, + .u32Height = 1296, + }, + .stMaxSize = { + .u32Width = 2304, + .u32Height = 1296, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.65, /* 1800 * 30 / 0x7FFF*/ + .u32HtsDef = 2333, + .u32VtsDef = 1800, + .stExp[0] = { + .u32Min = 3, + .u32Max = 3592, //2*vts - 8 + .u32Def = 1800, //30fps + .u32Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 23879, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 32512, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.02792946062982082367, 3.36534714698791503906}, //B: slope, intercept + {0.02071751467883586884, 5.34583568572998046875}, //Gb: slope, intercept + {0.02110148966312408447, 5.02954530715942382813}, //Gr: slope, intercept + {0.02168512716889381409, 4.89776754379272460938}, //R: slope, intercept + }, + { //iso 200 + {0.03194080293178558350, 5.61192893981933593750}, //B: slope, intercept + {0.02428408525884151459, 7.94834280014038085938}, //Gb: slope, intercept + {0.02499442733824253082, 7.72430133819580078125}, //Gr: slope, intercept + {0.02584112435579299927, 7.20574426651000976563}, //R: slope, intercept + }, + { //iso 400 + {0.04612467437982559204, 6.88752269744873046875}, //B: slope, intercept + {0.03022909909486770630, 11.05101776123046875000}, //Gb: slope, intercept + {0.03175539523363113403, 10.60332489013671875000}, //Gr: slope, intercept + {0.03522306308150291443, 9.36425399780273437500}, //R: slope, intercept + }, + { //iso 800 + {0.06092500314116477966, 9.79670524597167968750}, //B: slope, intercept + {0.03984217345714569092, 15.30182266235351562500}, //Gb: slope, intercept + {0.04019560664892196655, 14.93132972717285156250}, //Gr: slope, intercept + {0.04470816254615783691, 13.26843166351318359375}, //R: slope, intercept + }, + { //iso 1600 + {0.08295634388923645020, 14.20334625244140625000}, //B: slope, intercept + {0.05075264349579811096, 20.99221038818359375000}, //Gb: slope, intercept + {0.05426201224327087402, 20.08068656921386718750}, //Gr: slope, intercept + {0.05945669487118721008, 19.02898788452148437500}, //R: slope, intercept + }, + { //iso 3200 + {0.09782519936561584473, 21.84967994689941406250}, //B: slope, intercept + {0.06690908223390579224, 26.53993988037109375000}, //Gb: slope, intercept + {0.06954573839902877808, 25.74129104614257812500}, //Gr: slope, intercept + {0.09061723947525024414, 22.98998260498046875000}, //R: slope, intercept + }, + { //iso 6400 + {0.14311420917510986328, 28.96467971801757812500}, //B: slope, intercept + {0.08148498833179473877, 37.93062591552734375000}, //Gb: slope, intercept + {0.08273542672395706177, 38.37096405029296875000}, //Gr: slope, intercept + {0.12093253433704376221, 33.31475067138671875000}, //R: slope, intercept + }, + { //iso 12800 + {0.17958122491836547852, 43.49506759643554687500}, //B: slope, intercept + {0.09839969873428344727, 55.43268966674804687500}, //Gb: slope, intercept + {0.10201884806156158447, 52.97607040405273437500}, //Gr: slope, intercept + {0.15302789211273193359, 47.54779434204101562500}, //R: slope, intercept + }, + { //iso 25600 + {0.25833165645599365234, 56.96470642089843750000}, //B: slope, intercept + {0.13260601460933685303, 74.69016265869140625000}, //Gb: slope, intercept + {0.14035490155220031738, 75.44366455078125000000}, //Gr: slope, intercept + {0.23465165495872497559, 60.52228164672851562500}, //R: slope, intercept + }, + { //iso 51200 + {0.37595292925834655762, 78.54853057861328125000}, //B: slope, intercept + {0.21475413441658020020, 102.12300872802734375000}, //Gb: slope, intercept + {0.20840260386466979980, 103.65763854980468750000}, //Gr: slope, intercept + {0.34428051114082336426, 87.83551025390625000000}, //R: slope, intercept + }, + { //iso 102400 + {0.51122575998306274414, 113.49224090576171875000}, //B: slope, intercept + {0.29245173931121826172, 154.26939392089843750000}, //Gb: slope, intercept + {0.31501635909080505371, 148.29017639160156250000}, //Gr: slope, intercept + {0.47034618258476257324, 124.06208038330078125000}, //R: slope, intercept + }, + { //iso 204800 + {0.67213481664657592773, 134.71751403808593750000}, //B: slope, intercept + {0.40368056297302246094, 189.80801391601562500000}, //Gb: slope, intercept + {0.43581819534301757813, 186.44682312011718750000}, //Gr: slope, intercept + {0.60127359628677368164, 160.66384887695312500000}, //R: slope, intercept + }, + { //iso 409600 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 819200 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc401ai_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {0, 1, 2, -1, -1}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC401AI_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc401ai/sc401ai_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc401ai/sc401ai_sensor_ctl.c new file mode 100644 index 000000000..d13239be9 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc401ai/sc401ai_sensor_ctl.c @@ -0,0 +1,493 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc401ai_cmos_ex.h" + +static void sc401ai_linear_1440p30_init(VI_PIPE ViPipe); +static void sc401ai_linear_1296p30_init(VI_PIPE ViPipe); + +CVI_U8 sc401ai_i2c_addr = 0x30; /* I2C Address of SC401AI */ +const CVI_U32 sc401ai_addr_byte = 2; +const CVI_U32 sc401ai_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc401ai_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC401AI_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc401ai_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc401ai_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc401ai_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc401ai_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc401ai_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc401ai_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc401ai_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc401ai_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc401ai_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc401ai_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc401ai_addr_byte + sc401ai_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc401ai_standby(VI_PIPE ViPipe) +{ + sc401ai_write_register(ViPipe, 0x0100, 0x00); +} + +void sc401ai_restart(VI_PIPE ViPipe) +{ + sc401ai_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc401ai_write_register(ViPipe, 0x0100, 0x01); +} + +void sc401ai_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC401AI[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc401ai_write_register(ViPipe, + g_pastSC401AI[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC401AI[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC401AI_CHIP_ID_HI_ADDR 0x3107 +#define SC401AI_CHIP_ID_LO_ADDR 0x3108 +#define SC401AI_CHIP_ID 0xcd2e + +void sc401ai_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc401ai_write_register(ViPipe, 0x3221, val); +} + +int sc401ai_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + delay_ms(4); + if (sc401ai_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc401ai_read_register(ViPipe, SC401AI_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc401ai_read_register(ViPipe, SC401AI_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC401AI_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc401ai_init(VI_PIPE ViPipe) +{ + CVI_U8 u8ImgMode = g_pastSC401AI[ViPipe]->u8ImgMode; + + sc401ai_i2c_init(ViPipe); + + if (u8ImgMode == SC401AI_MODE_1440P30) + sc401ai_linear_1440p30_init(ViPipe); + else if (u8ImgMode == SC401AI_MODE_1296P30) + sc401ai_linear_1296p30_init(ViPipe); + + g_pastSC401AI[ViPipe]->bInit = CVI_TRUE; +} + +void sc401ai_exit(VI_PIPE ViPipe) +{ + sc401ai_i2c_exit(ViPipe); +} + +/* 1440P30 and 1440P25 */ +static void sc401ai_linear_1440p30_init(VI_PIPE ViPipe) +{ + sc401ai_write_register(ViPipe, 0x0103, 0x01); + sc401ai_write_register(ViPipe, 0x0100, 0x00); + sc401ai_write_register(ViPipe, 0x36e9, 0x80); + sc401ai_write_register(ViPipe, 0x36f9, 0x80); + sc401ai_write_register(ViPipe, 0x3018, 0x3a); + sc401ai_write_register(ViPipe, 0x3019, 0x0c); + sc401ai_write_register(ViPipe, 0x301c, 0x78); + sc401ai_write_register(ViPipe, 0x301f, 0x05); + sc401ai_write_register(ViPipe, 0x3208, 0x0a); + sc401ai_write_register(ViPipe, 0x3209, 0x00); + sc401ai_write_register(ViPipe, 0x320a, 0x05); + sc401ai_write_register(ViPipe, 0x320b, 0xa0); + sc401ai_write_register(ViPipe, 0x320e, 0x05);//vts + sc401ai_write_register(ViPipe, 0x320f, 0xdc); + sc401ai_write_register(ViPipe, 0x3214, 0x11); + sc401ai_write_register(ViPipe, 0x3215, 0x11); + sc401ai_write_register(ViPipe, 0x3223, 0x80); + sc401ai_write_register(ViPipe, 0x3250, 0x00); + sc401ai_write_register(ViPipe, 0x3253, 0x08); + sc401ai_write_register(ViPipe, 0x3274, 0x01); + sc401ai_write_register(ViPipe, 0x3301, 0x20); + sc401ai_write_register(ViPipe, 0x3302, 0x18); + sc401ai_write_register(ViPipe, 0x3303, 0x10); + sc401ai_write_register(ViPipe, 0x3304, 0x50); + sc401ai_write_register(ViPipe, 0x3306, 0x38); + sc401ai_write_register(ViPipe, 0x3308, 0x18); + sc401ai_write_register(ViPipe, 0x3309, 0x60); + sc401ai_write_register(ViPipe, 0x330b, 0xc0); + sc401ai_write_register(ViPipe, 0x330d, 0x10); + sc401ai_write_register(ViPipe, 0x330e, 0x18); + sc401ai_write_register(ViPipe, 0x330f, 0x04); + sc401ai_write_register(ViPipe, 0x3310, 0x02); + sc401ai_write_register(ViPipe, 0x331c, 0x04); + sc401ai_write_register(ViPipe, 0x331e, 0x41); + sc401ai_write_register(ViPipe, 0x331f, 0x51); + sc401ai_write_register(ViPipe, 0x3320, 0x09); + sc401ai_write_register(ViPipe, 0x3333, 0x10); + sc401ai_write_register(ViPipe, 0x334c, 0x08); + sc401ai_write_register(ViPipe, 0x3356, 0x09); + sc401ai_write_register(ViPipe, 0x3364, 0x17); + sc401ai_write_register(ViPipe, 0x338e, 0xfd); + sc401ai_write_register(ViPipe, 0x3390, 0x08); + sc401ai_write_register(ViPipe, 0x3391, 0x18); + sc401ai_write_register(ViPipe, 0x3392, 0x38); + sc401ai_write_register(ViPipe, 0x3393, 0x20); + sc401ai_write_register(ViPipe, 0x3394, 0x20); + sc401ai_write_register(ViPipe, 0x3395, 0x20); + sc401ai_write_register(ViPipe, 0x3396, 0x08); + sc401ai_write_register(ViPipe, 0x3397, 0x18); + sc401ai_write_register(ViPipe, 0x3398, 0x38); + sc401ai_write_register(ViPipe, 0x3399, 0x20); + sc401ai_write_register(ViPipe, 0x339a, 0x20); + sc401ai_write_register(ViPipe, 0x339b, 0x20); + sc401ai_write_register(ViPipe, 0x339c, 0x20); + sc401ai_write_register(ViPipe, 0x33ac, 0x10); + sc401ai_write_register(ViPipe, 0x33ae, 0x18); + sc401ai_write_register(ViPipe, 0x33af, 0x19); + sc401ai_write_register(ViPipe, 0x360f, 0x01); + sc401ai_write_register(ViPipe, 0x3620, 0x08); + sc401ai_write_register(ViPipe, 0x3637, 0x25); + sc401ai_write_register(ViPipe, 0x363a, 0x12); + sc401ai_write_register(ViPipe, 0x3670, 0x0a); + sc401ai_write_register(ViPipe, 0x3671, 0x07); + sc401ai_write_register(ViPipe, 0x3672, 0x57); + sc401ai_write_register(ViPipe, 0x3673, 0x5e); + sc401ai_write_register(ViPipe, 0x3674, 0x84); + sc401ai_write_register(ViPipe, 0x3675, 0x88); + sc401ai_write_register(ViPipe, 0x3676, 0x8a); + sc401ai_write_register(ViPipe, 0x367a, 0x58); + sc401ai_write_register(ViPipe, 0x367b, 0x78); + sc401ai_write_register(ViPipe, 0x367c, 0x58); + sc401ai_write_register(ViPipe, 0x367d, 0x78); + sc401ai_write_register(ViPipe, 0x3690, 0x33); + sc401ai_write_register(ViPipe, 0x3691, 0x43); + sc401ai_write_register(ViPipe, 0x3692, 0x34); + sc401ai_write_register(ViPipe, 0x369c, 0x40); + sc401ai_write_register(ViPipe, 0x369d, 0x78); + sc401ai_write_register(ViPipe, 0x36ea, 0x39); + sc401ai_write_register(ViPipe, 0x36eb, 0x0d); + sc401ai_write_register(ViPipe, 0x36ec, 0x1c); + sc401ai_write_register(ViPipe, 0x36ed, 0x24); + sc401ai_write_register(ViPipe, 0x36fa, 0x39); + sc401ai_write_register(ViPipe, 0x36fb, 0x33); + sc401ai_write_register(ViPipe, 0x36fc, 0x10); + sc401ai_write_register(ViPipe, 0x36fd, 0x14); + sc401ai_write_register(ViPipe, 0x3908, 0x41); + sc401ai_write_register(ViPipe, 0x396c, 0x0e); + sc401ai_write_register(ViPipe, 0x3e00, 0x00); + sc401ai_write_register(ViPipe, 0x3e01, 0xb6); + sc401ai_write_register(ViPipe, 0x3e02, 0x00); + sc401ai_write_register(ViPipe, 0x3e03, 0x0b); + sc401ai_write_register(ViPipe, 0x3e08, 0x03); + sc401ai_write_register(ViPipe, 0x3e09, 0x40); + sc401ai_write_register(ViPipe, 0x3e1b, 0x2a); + sc401ai_write_register(ViPipe, 0x4509, 0x30); + sc401ai_write_register(ViPipe, 0x4819, 0x08); + sc401ai_write_register(ViPipe, 0x481b, 0x05); + sc401ai_write_register(ViPipe, 0x481d, 0x11); + sc401ai_write_register(ViPipe, 0x481f, 0x04); + sc401ai_write_register(ViPipe, 0x4821, 0x09); + sc401ai_write_register(ViPipe, 0x4823, 0x04); + sc401ai_write_register(ViPipe, 0x4825, 0x04); + sc401ai_write_register(ViPipe, 0x4827, 0x04); + sc401ai_write_register(ViPipe, 0x4829, 0x07); + sc401ai_write_register(ViPipe, 0x57a8, 0xd0); + sc401ai_write_register(ViPipe, 0x36e9, 0x14); + sc401ai_write_register(ViPipe, 0x36f9, 0x14); + sc401ai_write_register(ViPipe, 0x5001, 0x44); //Support sid pull up + + sc401ai_default_reg_init(ViPipe); + + sc401ai_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC401AI 1440P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +/* 1440P30 and 1440P25 */ +static void sc401ai_linear_1296p30_init(VI_PIPE ViPipe) +{ + sc401ai_write_register(ViPipe, 0x0103, 0x01); + sc401ai_write_register(ViPipe, 0x0100, 0x00); + sc401ai_write_register(ViPipe, 0x36e9, 0x80); + sc401ai_write_register(ViPipe, 0x36f9, 0x80); + sc401ai_write_register(ViPipe, 0x3018, 0x3a); + sc401ai_write_register(ViPipe, 0x3019, 0x0c); + sc401ai_write_register(ViPipe, 0x301c, 0x78); + sc401ai_write_register(ViPipe, 0x301f, 0x05); + sc401ai_write_register(ViPipe, 0x3200, 0x00); + sc401ai_write_register(ViPipe, 0x3201, 0x80); + sc401ai_write_register(ViPipe, 0x3202, 0x00); + sc401ai_write_register(ViPipe, 0x3203, 0x48); + sc401ai_write_register(ViPipe, 0x3204, 0x09); + sc401ai_write_register(ViPipe, 0x3205, 0x87); + sc401ai_write_register(ViPipe, 0x3206, 0x05); + sc401ai_write_register(ViPipe, 0x3207, 0x5f); + sc401ai_write_register(ViPipe, 0x3208, 0x09); + sc401ai_write_register(ViPipe, 0x3209, 0x00); + sc401ai_write_register(ViPipe, 0x320a, 0x05); + sc401ai_write_register(ViPipe, 0x320b, 0x10); + sc401ai_write_register(ViPipe, 0x320e, 0x07); + sc401ai_write_register(ViPipe, 0x320f, 0x08); + sc401ai_write_register(ViPipe, 0x3210, 0x00); + sc401ai_write_register(ViPipe, 0x3211, 0x04); + sc401ai_write_register(ViPipe, 0x3212, 0x00); + sc401ai_write_register(ViPipe, 0x3213, 0x04); + sc401ai_write_register(ViPipe, 0x3214, 0x11); + sc401ai_write_register(ViPipe, 0x3215, 0x11); + sc401ai_write_register(ViPipe, 0x3223, 0x80); + sc401ai_write_register(ViPipe, 0x3250, 0x00); + sc401ai_write_register(ViPipe, 0x3253, 0x08); + sc401ai_write_register(ViPipe, 0x3274, 0x01); + sc401ai_write_register(ViPipe, 0x3301, 0x20); + sc401ai_write_register(ViPipe, 0x3302, 0x18); + sc401ai_write_register(ViPipe, 0x3303, 0x10); + sc401ai_write_register(ViPipe, 0x3304, 0x50); + sc401ai_write_register(ViPipe, 0x3306, 0x38); + sc401ai_write_register(ViPipe, 0x3308, 0x18); + sc401ai_write_register(ViPipe, 0x3309, 0x60); + sc401ai_write_register(ViPipe, 0x330b, 0xc0); + sc401ai_write_register(ViPipe, 0x330d, 0x10); + sc401ai_write_register(ViPipe, 0x330e, 0x18); + sc401ai_write_register(ViPipe, 0x330f, 0x04); + sc401ai_write_register(ViPipe, 0x3310, 0x02); + sc401ai_write_register(ViPipe, 0x331c, 0x04); + sc401ai_write_register(ViPipe, 0x331e, 0x41); + sc401ai_write_register(ViPipe, 0x331f, 0x51); + sc401ai_write_register(ViPipe, 0x3320, 0x09); + sc401ai_write_register(ViPipe, 0x3333, 0x10); + sc401ai_write_register(ViPipe, 0x334c, 0x08); + sc401ai_write_register(ViPipe, 0x3356, 0x09); + sc401ai_write_register(ViPipe, 0x3364, 0x17); + sc401ai_write_register(ViPipe, 0x338e, 0xfd); + sc401ai_write_register(ViPipe, 0x3390, 0x08); + sc401ai_write_register(ViPipe, 0x3391, 0x18); + sc401ai_write_register(ViPipe, 0x3392, 0x38); + sc401ai_write_register(ViPipe, 0x3393, 0x20); + sc401ai_write_register(ViPipe, 0x3394, 0x20); + sc401ai_write_register(ViPipe, 0x3395, 0x20); + sc401ai_write_register(ViPipe, 0x3396, 0x08); + sc401ai_write_register(ViPipe, 0x3397, 0x18); + sc401ai_write_register(ViPipe, 0x3398, 0x38); + sc401ai_write_register(ViPipe, 0x3399, 0x20); + sc401ai_write_register(ViPipe, 0x339a, 0x20); + sc401ai_write_register(ViPipe, 0x339b, 0x20); + sc401ai_write_register(ViPipe, 0x339c, 0x20); + sc401ai_write_register(ViPipe, 0x33ac, 0x10); + sc401ai_write_register(ViPipe, 0x33ae, 0x18); + sc401ai_write_register(ViPipe, 0x33af, 0x19); + sc401ai_write_register(ViPipe, 0x360f, 0x01); + sc401ai_write_register(ViPipe, 0x3620, 0x08); + sc401ai_write_register(ViPipe, 0x3637, 0x25); + sc401ai_write_register(ViPipe, 0x363a, 0x12); + sc401ai_write_register(ViPipe, 0x3670, 0x0a); + sc401ai_write_register(ViPipe, 0x3671, 0x07); + sc401ai_write_register(ViPipe, 0x3672, 0x57); + sc401ai_write_register(ViPipe, 0x3673, 0x5e); + sc401ai_write_register(ViPipe, 0x3674, 0x84); + sc401ai_write_register(ViPipe, 0x3675, 0x88); + sc401ai_write_register(ViPipe, 0x3676, 0x8a); + sc401ai_write_register(ViPipe, 0x367a, 0x58); + sc401ai_write_register(ViPipe, 0x367b, 0x78); + sc401ai_write_register(ViPipe, 0x367c, 0x58); + sc401ai_write_register(ViPipe, 0x367d, 0x78); + sc401ai_write_register(ViPipe, 0x3690, 0x33); + sc401ai_write_register(ViPipe, 0x3691, 0x43); + sc401ai_write_register(ViPipe, 0x3692, 0x34); + sc401ai_write_register(ViPipe, 0x369c, 0x40); + sc401ai_write_register(ViPipe, 0x369d, 0x78); + sc401ai_write_register(ViPipe, 0x36ea, 0x39); + sc401ai_write_register(ViPipe, 0x36eb, 0x0d); + sc401ai_write_register(ViPipe, 0x36ec, 0x1c); + sc401ai_write_register(ViPipe, 0x36ed, 0x24); + sc401ai_write_register(ViPipe, 0x36fa, 0x39); + sc401ai_write_register(ViPipe, 0x36fb, 0x33); + sc401ai_write_register(ViPipe, 0x36fc, 0x10); + sc401ai_write_register(ViPipe, 0x36fd, 0x14); + sc401ai_write_register(ViPipe, 0x3908, 0x41); + sc401ai_write_register(ViPipe, 0x396c, 0x0e); + sc401ai_write_register(ViPipe, 0x3e00, 0x00); + sc401ai_write_register(ViPipe, 0x3e01, 0xb6); + sc401ai_write_register(ViPipe, 0x3e02, 0x00); + sc401ai_write_register(ViPipe, 0x3e03, 0x0b); + sc401ai_write_register(ViPipe, 0x3e08, 0x03); + sc401ai_write_register(ViPipe, 0x3e09, 0x40); + sc401ai_write_register(ViPipe, 0x3e1b, 0x2a); + sc401ai_write_register(ViPipe, 0x4509, 0x30); + sc401ai_write_register(ViPipe, 0x4819, 0x08); + sc401ai_write_register(ViPipe, 0x481b, 0x05); + sc401ai_write_register(ViPipe, 0x481d, 0x11); + sc401ai_write_register(ViPipe, 0x481f, 0x04); + sc401ai_write_register(ViPipe, 0x4821, 0x09); + sc401ai_write_register(ViPipe, 0x4823, 0x04); + sc401ai_write_register(ViPipe, 0x4825, 0x04); + sc401ai_write_register(ViPipe, 0x4827, 0x04); + sc401ai_write_register(ViPipe, 0x4829, 0x07); + sc401ai_write_register(ViPipe, 0x57a8, 0xd0); + sc401ai_write_register(ViPipe, 0x36e9, 0x14); + sc401ai_write_register(ViPipe, 0x36f9, 0x14); + sc401ai_write_register(ViPipe, 0x5001, 0x44); //Support sid pull up + + sc401ai_default_reg_init(ViPipe); + + sc401ai_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC401AI 1296P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc4336/Makefile b/middleware/v2/component/isp/sensor/cv181x/sms_sc4336/Makefile new file mode 100644 index 000000000..3190f8c09 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc4336/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc4336.a +TARGET_SO = $(MW_LIB)/libsns_sc4336.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc4336/sc4336_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc4336/sc4336_cmos.c new file mode 100644 index 000000000..59545137e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc4336/sc4336_cmos.c @@ -0,0 +1,916 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc4336_cmos_ex.h" +#include "sc4336_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC4336_ID 4336 +#define SENSOR_SC4336_WIDTH 2560 +#define SENSOR_SC4336_HEIGHT 1440 +#define SC4336_I2C_ADDR_1 0x30 +#define SC4336_I2C_ADDR_2 0x32 +#define SC4336_I2C_ADDR_IS_VALID(addr) ((addr) == SC4336_I2C_ADDR_1 || (addr) == SC4336_I2C_ADDR_2) + +#define SC4336_EXPACCURACY (1) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC4336[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC4336_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC4336[dev]) +#define SC4336_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC4336[dev] = pstCtx) +#define SC4336_SENSOR_RESET_CTX(dev) (g_pastSC4336[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC4336_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC4336_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC4336_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc4336_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC4336 Lines Range*****/ +#define SC4336_FULL_LINES_MAX (0x7FFF) + +/*****SC4336 Register Address*****/ +#define SC4336_EXP_ADDR 0x3E00 +#define SC4336_AGAIN_ADDR 0x3E09 +#define SC4336_DGAIN_ADDR 0x3E06 +#define SC4336_VMAX_ADDR 0x320E + +#define SC4336_RES_IS_1440P(w, h) ((w) == 2560 && (h) == 1440) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC4336_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC4336_EXPACCURACY; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stAgainAccu.f32Accuracy = 6; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astSC4336_mode[pstSnsState->u8ImgMode].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC4336_mode[pstSnsState->u8ImgMode].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = g_astSC4336_mode[pstSnsState->u8ImgMode].stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = g_astSC4336_mode[pstSnsState->u8ImgMode].stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astSC4336_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = g_astSC4336_mode[pstSnsState->u8ImgMode].stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = g_astSC4336_mode[pstSnsState->u8ImgMode].stExp[0].u32Max; + pstAeSnsDft->u32MinIntTime = g_astSC4336_mode[pstSnsState->u8ImgMode].stExp[0].u32Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC4336_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC4336_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC4336_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC4336_MODE_1440P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC4336_FULL_LINES_MAX) ? SC4336_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0x7F00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = (pstSnsState->u32FLStd << 1) - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* linear exposure reg range: + * min : 0 + * max : vts - 8 + * step : 1 + */ + u32MinTime = 0; + u32MaxTime = pstSnsState->au32FL[0] - 8; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); //bit[15:12] + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); //bit[11:4] + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = ((u32TmpIntTime & 0x000F) << 4); //bit[3:0] + + return CVI_SUCCESS; +} + +struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +}; + +static struct gain_tbl_info_s DgainInfo[] = { + { + .gainMax = 2016, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 8064, + .idxBase = 64, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 16128, + .idxBase = 96, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, +}; + +static CVI_U32 Dgain_table[] = { + 1024, 1055, 1088, 1120, 1152, 1183, 1216, 1248, 1280, 1311, 1344, 1376, 1408, 1439, 1472, + 1504, 1536, 1567, 1600, 1632, 1664, 1695, 1728, 1760, 1792, 1823, 1856, 1888, 1920, 1951, + 1984, 2016, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, + 2816, 2880, 2944, 3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, + 3840, 3904, 3968, 4032, 4096, 4224, 4352, 4480, 4608, 4736, 4864, 4992, 5120, 5248, 5376, + 5504, 5632, 5760, 5888, 6016, 6144, 6272, 6400, 6528, 6656, 6784, 6912, 7040, 7168, 7296, + 7424, 7552, 7680, 7808, 7936, 8064, 8192, 8448, 8704, 8960, 9216, 9472, 9728, 9984, 10240, + 10496, 10752, 11008, 11264, 11520, 11776, 12032, 12288, 12544, 12800, 13056, 13312, + 13568, 13824, 14080, 14336, 14592, 14848, 15104, 15360, 15616, 15872, 16128 +}; + +static const CVI_U32 dgain_table_size = ARRAY_SIZE(Dgain_table); + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 again = *pu32AgainLin; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (again < 2048) { + *pu32AgainDb = 0x00; + *pu32AgainLin = 1024; + } else if (again < 4096) { + *pu32AgainDb = 0x08; + *pu32AgainLin = 2048; + } else if (again < 8192) { + *pu32AgainDb = 0x09; + *pu32AgainLin = 4096; + } else if (again < 16384) { + *pu32AgainDb = 0x0B; + *pu32AgainLin = 8192; + } else if (again < 32768) { + *pu32AgainDb = 0x0F; + *pu32AgainLin = 16384; + } else { + *pu32AgainDb = 0x1F; + *pu32AgainLin = 32768; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 i; + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[dgain_table_size - 1]) { + *pu32DgainLin = Dgain_table[dgain_table_size - 1]; + *pu32DgainDb = dgain_table_size - 1; + return CVI_SUCCESS; + } + + for (i = 1; i < dgain_table_size; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + /* find Again register setting. */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_D_FINEGAIN_ADDR].u32Data = (u32Dgain & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC4336_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC4336_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC4336_MODE_1440P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC4336_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC4336_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc4336_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc4336_addr_byte; + pstI2c_data[i].u32DataByteNum = sc4336_data_byte; + } + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC4336_EXP_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC4336_EXP_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC4336_EXP_ADDR + 2; + + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = SC4336_AGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_ADDR].u32RegAddr = SC4336_DGAIN_ADDR; + pstI2c_data[LINEAR_D_FINEGAIN_ADDR].u32RegAddr = SC4336_DGAIN_ADDR + 1; + + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC4336_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC4336_VMAX_ADDR + 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC4336_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC4336_MODE_1440P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeSc4336_MirrorFip[ViPipe] != eSnsMirrorFlip) { + sc4336_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeSc4336_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC4336_MODE_S *pstMode = CVI_NULL; + + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC4336_MODE_1440P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC4336_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC4336_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc4336_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC4336_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC4336_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc4336_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc4336_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc4336_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (SC4336_I2C_ADDR_IS_VALID(s32I2cAddr)) + sc4336_i2c_addr = s32I2cAddr; +} + +static CVI_S32 sc4336_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC4336_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC4336_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC4336_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC4336_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC4336_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC4336_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC4336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC4336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC4336_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC4336_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC4336_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC4336_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc4336_standby, + .pfnRestart = sc4336_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = sc4336_write_register, + .pfnReadReg = sc4336_read_register, + .pfnSetBusInfo = sc4336_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc4336_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc4336/sc4336_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc4336/sc4336_cmos_ex.h new file mode 100644 index 000000000..fdf3ae46a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc4336/sc4336_cmos_ex.h @@ -0,0 +1,78 @@ +#ifndef __SC4336_CMOS_EX_H_ +#define __SC4336_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc4336_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_2_ADDR, + LINEAR_AGAIN_ADDR, + LINEAR_DGAIN_ADDR, + LINEAR_D_FINEGAIN_ADDR, + LINEAR_VMAX_0_ADDR, + LINEAR_VMAX_1_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC4336_MODE_E { + SC4336_MODE_1440P30 = 0, + SC4336_MODE_NUM +} SC4336_MODE_E; + +typedef struct _SC4336_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_LARGE_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} SC4336_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC4336[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC4336_BusInfo[]; +extern CVI_U16 g_au16SC4336_GainMode[]; +extern CVI_U16 g_au16SC4336_L2SMode[]; +extern CVI_U8 sc4336_i2c_addr; +extern const CVI_U32 sc4336_addr_byte; +extern const CVI_U32 sc4336_data_byte; +extern void sc4336_init(VI_PIPE ViPipe); +extern void sc4336_exit(VI_PIPE ViPipe); +extern void sc4336_standby(VI_PIPE ViPipe); +extern void sc4336_restart(VI_PIPE ViPipe); +extern int sc4336_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc4336_read_register(VI_PIPE ViPipe, int addr); +extern void sc4336_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc4336_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC4336_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc4336/sc4336_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc4336/sc4336_cmos_param.h new file mode 100644 index 000000000..84fb617d0 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc4336/sc4336_cmos_param.h @@ -0,0 +1,121 @@ +#ifndef __SC4336_CMOS_PARAM_H_ +#define __SC4336_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc4336_cmos_ex.h" + +static const SC4336_MODE_S g_astSC4336_mode[SC4336_MODE_NUM] = { + [SC4336_MODE_1440P30] = { + .name = "1440p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.37, /* 1500 * 30 / 0x7FFF*/ + .u32HtsDef = 2800, + .u32VtsDef = 1500, + .stExp[0] = { + .u32Min = 0, + .u32Max = 1500 - 8, //vts - 8 + .u32Def = 400, + .u32Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 32768, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16128, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc4336_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 1, 3, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC4336_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc4336/sc4336_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc4336/sc4336_sensor_ctl.c new file mode 100644 index 000000000..838a363a4 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc4336/sc4336_sensor_ctl.c @@ -0,0 +1,382 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc4336_cmos_ex.h" + +static void sc4336_linear_1440p30_init(VI_PIPE ViPipe); + +CVI_U8 sc4336_i2c_addr = 0x30; /* I2C Address of SC4336 */ +const CVI_U32 sc4336_addr_byte = 2; +const CVI_U32 sc4336_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc4336_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC4336_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc4336_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc4336_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc4336_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc4336_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc4336_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc4336_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc4336_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc4336_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc4336_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc4336_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc4336_addr_byte + sc4336_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc4336_standby(VI_PIPE ViPipe) +{ + sc4336_write_register(ViPipe, 0x0100, 0x00); +} + +void sc4336_restart(VI_PIPE ViPipe) +{ + sc4336_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc4336_write_register(ViPipe, 0x0100, 0x01); +} + +void sc4336_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC4336[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc4336_write_register(ViPipe, + g_pastSC4336[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC4336[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void sc4336_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc4336_write_register(ViPipe, 0x3221, val); +} + +#define SC4336_CHIP_ID_HI_ADDR 0x3107 +#define SC4336_CHIP_ID_LO_ADDR 0x3108 +#define SC4336_CHIP_ID 0xdc42 + +int sc4336_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + if (sc4336_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + delay_ms(5); + + nVal = sc4336_read_register(ViPipe, SC4336_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc4336_read_register(ViPipe, SC4336_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC4336_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc4336_init(VI_PIPE ViPipe) +{ + sc4336_i2c_init(ViPipe); + + sc4336_linear_1440p30_init(ViPipe); + + g_pastSC4336[ViPipe]->bInit = CVI_TRUE; +} + +void sc4336_exit(VI_PIPE ViPipe) +{ + sc4336_i2c_exit(ViPipe); +} + +/* 1440P30 and 1440P25 */ +static void sc4336_linear_1440p30_init(VI_PIPE ViPipe) +{ + sc4336_write_register(ViPipe, 0x0103, 0x01); + sc4336_write_register(ViPipe, 0x36e9, 0x80); + sc4336_write_register(ViPipe, 0x37f9, 0x80); + sc4336_write_register(ViPipe, 0x301f, 0x01); + sc4336_write_register(ViPipe, 0x30b8, 0x44); + sc4336_write_register(ViPipe, 0x3253, 0x10); + sc4336_write_register(ViPipe, 0x3301, 0x0a); + sc4336_write_register(ViPipe, 0x3302, 0xff); + sc4336_write_register(ViPipe, 0x3305, 0x00); + sc4336_write_register(ViPipe, 0x3306, 0x90); + sc4336_write_register(ViPipe, 0x3308, 0x08); + sc4336_write_register(ViPipe, 0x330a, 0x01); + sc4336_write_register(ViPipe, 0x330b, 0xb0); + sc4336_write_register(ViPipe, 0x330d, 0xf0); + sc4336_write_register(ViPipe, 0x3333, 0x10); + sc4336_write_register(ViPipe, 0x335e, 0x06); + sc4336_write_register(ViPipe, 0x335f, 0x0a); + sc4336_write_register(ViPipe, 0x3364, 0x5e); + sc4336_write_register(ViPipe, 0x337d, 0x0e); + sc4336_write_register(ViPipe, 0x338f, 0x20); + sc4336_write_register(ViPipe, 0x3390, 0x08); + sc4336_write_register(ViPipe, 0x3391, 0x09); + sc4336_write_register(ViPipe, 0x3392, 0x0f); + sc4336_write_register(ViPipe, 0x3393, 0x18); + sc4336_write_register(ViPipe, 0x3394, 0x60); + sc4336_write_register(ViPipe, 0x3395, 0xff); + sc4336_write_register(ViPipe, 0x3396, 0x08); + sc4336_write_register(ViPipe, 0x3397, 0x09); + sc4336_write_register(ViPipe, 0x3398, 0x0f); + sc4336_write_register(ViPipe, 0x3399, 0x0a); + sc4336_write_register(ViPipe, 0x339a, 0x18); + sc4336_write_register(ViPipe, 0x339b, 0x60); + sc4336_write_register(ViPipe, 0x339c, 0xff); + sc4336_write_register(ViPipe, 0x33a2, 0x04); + sc4336_write_register(ViPipe, 0x33ad, 0x0c); + sc4336_write_register(ViPipe, 0x33b2, 0x40); + sc4336_write_register(ViPipe, 0x33b3, 0x30); + sc4336_write_register(ViPipe, 0x33f8, 0x00); + sc4336_write_register(ViPipe, 0x33f9, 0xa0); + sc4336_write_register(ViPipe, 0x33fa, 0x00); + sc4336_write_register(ViPipe, 0x33fb, 0xe0); + sc4336_write_register(ViPipe, 0x33fc, 0x09); + sc4336_write_register(ViPipe, 0x33fd, 0x1f); + sc4336_write_register(ViPipe, 0x349f, 0x03); + sc4336_write_register(ViPipe, 0x34a6, 0x09); + sc4336_write_register(ViPipe, 0x34a7, 0x1f); + sc4336_write_register(ViPipe, 0x34a8, 0x28); + sc4336_write_register(ViPipe, 0x34a9, 0x28); + sc4336_write_register(ViPipe, 0x34aa, 0x01); + sc4336_write_register(ViPipe, 0x34ab, 0xd0); + sc4336_write_register(ViPipe, 0x34ac, 0x02); + sc4336_write_register(ViPipe, 0x34ad, 0x10); + sc4336_write_register(ViPipe, 0x34f8, 0x1f); + sc4336_write_register(ViPipe, 0x34f9, 0x20); + sc4336_write_register(ViPipe, 0x3630, 0xc0); + sc4336_write_register(ViPipe, 0x3631, 0x84); + sc4336_write_register(ViPipe, 0x3633, 0x44); + sc4336_write_register(ViPipe, 0x3637, 0x4c); + sc4336_write_register(ViPipe, 0x3641, 0x38); + sc4336_write_register(ViPipe, 0x3650, 0x33); + sc4336_write_register(ViPipe, 0x3670, 0x56); + sc4336_write_register(ViPipe, 0x3674, 0xc0); + sc4336_write_register(ViPipe, 0x3675, 0xa0); + sc4336_write_register(ViPipe, 0x3676, 0xa0); + sc4336_write_register(ViPipe, 0x3677, 0x84); + sc4336_write_register(ViPipe, 0x3678, 0x88); + sc4336_write_register(ViPipe, 0x3679, 0x8d); + sc4336_write_register(ViPipe, 0x367c, 0x09); + sc4336_write_register(ViPipe, 0x367d, 0x0b); + sc4336_write_register(ViPipe, 0x367e, 0x08); + sc4336_write_register(ViPipe, 0x367f, 0x0f); + sc4336_write_register(ViPipe, 0x3696, 0x44); + sc4336_write_register(ViPipe, 0x3697, 0x54); + sc4336_write_register(ViPipe, 0x3698, 0x54); + sc4336_write_register(ViPipe, 0x36a0, 0x0f); + sc4336_write_register(ViPipe, 0x36a1, 0x1f); + sc4336_write_register(ViPipe, 0x36b0, 0x81); + sc4336_write_register(ViPipe, 0x36b1, 0x83); + sc4336_write_register(ViPipe, 0x36b2, 0x85); + sc4336_write_register(ViPipe, 0x36b3, 0x8b); + sc4336_write_register(ViPipe, 0x36b4, 0x09); + sc4336_write_register(ViPipe, 0x36b5, 0x0b); + sc4336_write_register(ViPipe, 0x36b6, 0x0f); + sc4336_write_register(ViPipe, 0x370f, 0x01); + sc4336_write_register(ViPipe, 0x3722, 0x09); + sc4336_write_register(ViPipe, 0x3724, 0x21); + sc4336_write_register(ViPipe, 0x3771, 0x09); + sc4336_write_register(ViPipe, 0x3772, 0x05); + sc4336_write_register(ViPipe, 0x3773, 0x05); + sc4336_write_register(ViPipe, 0x377a, 0x0f); + sc4336_write_register(ViPipe, 0x377b, 0x1f); + sc4336_write_register(ViPipe, 0x3905, 0x8c); + sc4336_write_register(ViPipe, 0x391d, 0x04); + sc4336_write_register(ViPipe, 0x3926, 0x21); + sc4336_write_register(ViPipe, 0x3933, 0x80); + sc4336_write_register(ViPipe, 0x3934, 0x03); + sc4336_write_register(ViPipe, 0x3935, 0x00); + sc4336_write_register(ViPipe, 0x3936, 0x08); + sc4336_write_register(ViPipe, 0x3937, 0x74); + sc4336_write_register(ViPipe, 0x3938, 0x6f); + sc4336_write_register(ViPipe, 0x3939, 0x00); + sc4336_write_register(ViPipe, 0x393a, 0x00); + sc4336_write_register(ViPipe, 0x39dc, 0x02); + sc4336_write_register(ViPipe, 0x3e00, 0x00); + sc4336_write_register(ViPipe, 0x3e01, 0x5d); + sc4336_write_register(ViPipe, 0x3e02, 0x40); + sc4336_write_register(ViPipe, 0x440e, 0x02); + sc4336_write_register(ViPipe, 0x4509, 0x28); + sc4336_write_register(ViPipe, 0x450d, 0x32); + sc4336_write_register(ViPipe, 0x5000, 0x06); + sc4336_write_register(ViPipe, 0x5799, 0x46); + sc4336_write_register(ViPipe, 0x579a, 0x77); + sc4336_write_register(ViPipe, 0x57d9, 0x46); + sc4336_write_register(ViPipe, 0x57da, 0x77); + sc4336_write_register(ViPipe, 0x5ae0, 0xfe); + sc4336_write_register(ViPipe, 0x5ae1, 0x40); + sc4336_write_register(ViPipe, 0x5ae2, 0x38); + sc4336_write_register(ViPipe, 0x5ae3, 0x30); + sc4336_write_register(ViPipe, 0x5ae4, 0x28); + sc4336_write_register(ViPipe, 0x5ae5, 0x38); + sc4336_write_register(ViPipe, 0x5ae6, 0x30); + sc4336_write_register(ViPipe, 0x5ae7, 0x28); + sc4336_write_register(ViPipe, 0x5ae8, 0x3f); + sc4336_write_register(ViPipe, 0x5ae9, 0x34); + sc4336_write_register(ViPipe, 0x5aea, 0x2c); + sc4336_write_register(ViPipe, 0x5aeb, 0x3f); + sc4336_write_register(ViPipe, 0x5aec, 0x34); + sc4336_write_register(ViPipe, 0x5aed, 0x2c); + sc4336_write_register(ViPipe, 0x36e9, 0x44); + sc4336_write_register(ViPipe, 0x37f9, 0x44); + + sc4336_default_reg_init(ViPipe); + + sc4336_write_register(ViPipe, 0x0100, 0x01); + + delay_ms(100); + + printf("ViPipe:%d,===SC4336 1440P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc500ai/Makefile b/middleware/v2/component/isp/sensor/cv181x/sms_sc500ai/Makefile new file mode 100644 index 000000000..997724472 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc500ai/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc500ai.a +TARGET_SO = $(MW_LIB)/libsns_sc500ai.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc500ai/sc500ai_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc500ai/sc500ai_cmos.c new file mode 100644 index 000000000..c552e3b45 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc500ai/sc500ai_cmos.c @@ -0,0 +1,1341 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc500ai_cmos_ex.h" +#include "sc500ai_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC500AI_ID 500 +#define SENSOR_SC500AI_WIDTH 2880 +#define SENSOR_SC500AI_HEIGHT 1620 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC500AI[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC500AI_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC500AI[dev]) +#define SC500AI_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC500AI[dev] = pstCtx) +#define SC500AI_SENSOR_RESET_CTX(dev) (g_pastSC500AI[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC500AI_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC500AI_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC500AI_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC500AI_STATE_S g_astSC500AI_State[VI_MAX_PIPE_NUM] = {{0} }; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC500AI Lines Range*****/ +#define SC500AI_FULL_LINES_MAX (0x7FFF) +#define SC500AI_FULL_LINES_MAX_2TO1_WDR (0x7FFF) + +/*****SC500AI Register Address*****/ +#define SC500AI_SHS1_0_ADDR 0x3E00 +#define SC500AI_SHS1_1_ADDR 0x3E01 +#define SC500AI_SHS1_2_ADDR 0x3E02 +#define SC500AI_SHS2_0_ADDR 0x3E22 +#define SC500AI_SHS2_1_ADDR 0x3E04 +#define SC500AI_SHS2_2_ADDR 0x3E05 +#define SC500AI_AGAIN1_ADDR 0x3E08 +#define SC500AI_DGAIN1_ADDR 0x3E06 +#define SC500AI_AGAIN2_ADDR 0x3E12 +#define SC500AI_DGAIN2_ADDR 0x3E10 +#define SC500AI_VMAX_ADDR 0x320E +#define SC500AI_MAXSEXP_ADDR 0x3E23 +#define SC500AI_TABLE_END 0xFFFF + +#define SC500AI_RES_IS_1620P(w, h) ((w) <= 2880 && (h) <= 1620) +#define SC500AI_RES_IS_1440P(w, h) ((w) <= 2560 && (h) <= 1440) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC500AI_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 0.5; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astSC500AI_mode[SC500AI_MODE_1620P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC500AI_mode[SC500AI_MODE_1620P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = g_astSC500AI_mode[SC500AI_MODE_1620P30].stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = g_astSC500AI_mode[SC500AI_MODE_1620P30].stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astSC500AI_mode[SC500AI_MODE_1620P30].stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = g_astSC500AI_mode[SC500AI_MODE_1620P30].stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = 2 * (pstSnsState->u32FLStd - 5); + pstAeSnsDft->u32MinIntTime = 3; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astSC500AI_mode[SC500AI_MODE_1620P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC500AI_mode[SC500AI_MODE_1620P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = 2 * (pstSnsState->u32FLStd - 16); + pstAeSnsDft->u32MinIntTime = 5; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = g_astSC500AI_mode[SC500AI_MODE_1620P30_WDR].stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = g_astSC500AI_mode[SC500AI_MODE_1620P30_WDR].stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astSC500AI_mode[SC500AI_MODE_1620P30_WDR].stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = g_astSC500AI_mode[SC500AI_MODE_1620P30_WDR].stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + CVI_U16 u16MaxSexpReg; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC500AI_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC500AI_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC500AI_mode[pstSnsState->u8ImgMode].f32MinFps; + u16MaxSexpReg = g_astSC500AI_mode[pstSnsState->u8ImgMode].u16SexpMaxReg; + + switch (pstSnsState->u8ImgMode) { + case SC500AI_MODE_1620P30_WDR: + case SC500AI_MODE_1440P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + u16MaxSexpReg = u16MaxSexpReg * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC500AI_FULL_LINES_MAX_2TO1_WDR) ? SC500AI_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case SC500AI_MODE_1620P30: + case SC500AI_MODE_1440P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC500AI_FULL_LINES_MAX) ? SC500AI_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + g_astSC500AI_State[ViPipe].u32Sexp_MAX = u16MaxSexpReg; + } + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + } else { + pstSnsRegsInfo->astI2cData[WDR2_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_MAXSEXP_0_ADDR].u32Data = ((u16MaxSexpReg & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_MAXSEXP_1_ADDR].u32Data = u16MaxSexpReg & 0xFF; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = 2 * (pstSnsState->u32FLStd - 5); + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + CVI_U16 u16SexpReg, u16LexpReg; + CVI_U32 u32MaxLExp; + CVI_U32 u32MaxSexp = 2 * g_astSC500AI_State[ViPipe].u32Sexp_MAX - 14; + + /* short exposure reg range: + * min : 5 + * max : 2 * reg_sexp_max - 14 + * step : 4 + */ + pstSnsState->au32WDRIntTime[0] = (u32ShortIntTime > u32MaxSexp) ? u32MaxSexp : u32ShortIntTime; + if (pstSnsState->au32WDRIntTime[0] < 5) + pstSnsState->au32WDRIntTime[0] = 5; + u16SexpReg = ((CVI_U16)pstSnsState->au32WDRIntTime[0] & ~0x3) + 1; + pstSnsState->au32WDRIntTime[0] = u16SexpReg; + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + + /* long exposure reg range: + * min : 5 + * max : 2 * (vts - max sexp) - 18 + * step : 4 + */ + u32MaxLExp = 2 * (pstSnsState->au32FL[0] - g_astSC500AI_State[ViPipe].u32Sexp_MAX) - 18; + pstSnsState->au32WDRIntTime[1] = (u32LongIntTime > u32MaxLExp) ? u32MaxLExp : u32LongIntTime; + if (pstSnsState->au32WDRIntTime[1] < 5) + pstSnsState->au32WDRIntTime[1] = 5; + u16LexpReg = ((CVI_U16)pstSnsState->au32WDRIntTime[1] & ~0x3) + 1; + pstSnsState->au32WDRIntTime[1] = u16LexpReg; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + pstSnsRegsInfo->astI2cData[WDR2_SHS1_0_ADDR].u32Data = ((u16LexpReg & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[WDR2_SHS1_1_ADDR].u32Data = ((u16LexpReg & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[WDR2_SHS1_2_ADDR].u32Data = (u16LexpReg & 0xF) << 4; + + pstSnsRegsInfo->astI2cData[WDR2_SHS2_0_ADDR].u32Data = ((u16SexpReg & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[WDR2_SHS2_1_ADDR].u32Data = ((u16SexpReg & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[WDR2_SHS2_2_ADDR].u32Data = (u16SexpReg & 0xF) << 4; + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + CVI_U32 u32TmpIntTime = u32IntTime[0]; + CVI_U32 maxExp = 2 * pstSnsState->au32FL[0] - 10; + + /* linear exposure reg range: + * min : 3 + * max : 2 * vts - 10 + * step : 1 + */ + u32TmpIntTime = (u32TmpIntTime > maxExp) ? maxExp : u32TmpIntTime; + if (u32TmpIntTime < 3) + u32TmpIntTime = 3; + u32IntTime[0] = u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = (u32TmpIntTime & 0xF) << 4; + } + + return CVI_SUCCESS; + +} + +struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +}; + +static struct gain_tbl_info_s AgainInfo[5] = { + { + .gainMax = 1536, + .idxBase = 0, + .regGain = 0x03, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 3080, + .idxBase = 33, + .regGain = 0x23, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 6161, + .idxBase = 97, + .regGain = 0x27, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 12321, + .idxBase = 161, + .regGain = 0x2F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 24644, + .idxBase = 225, + .regGain = 0x3F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, +}; + +static CVI_U32 Again_table[289] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, + 1248, 1263, 1280, 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, + 1472, 1487, 1504, 1519, 1536, 1552, 1576, 1600, 1625, 1649, 1673, 1697, 1722, 1746, + 1770, 1795, 1819, 1843, 1867, 1892, 1915, 1940, 1965, 1988, 2013, 2037, 2061, 2085, + 2110, 2135, 2158, 2183, 2207, 2231, 2255, 2280, 2304, 2328, 2353, 2376, 2401, 2425, + 2449, 2473, 2498, 2523, 2546, 2571, 2595, 2619, 2643, 2668, 2692, 2716, 2741, 2764, + 2789, 2813, 2837, 2862, 2886, 2911, 2934, 2959, 2983, 3007, 3032, 3056, 3080, 3104, + 3152, 3202, 3250, 3299, 3347, 3395, 3444, 3492, 3540, 3590, 3638, 3687, 3735, 3783, + 3832, 3880, 3929, 3978, 4026, 4075, 4123, 4171, 4220, 4269, 4317, 4366, 4414, 4463, + 4511, 4559, 4609, 4657, 4705, 4754, 4802, 4851, 4899, 4947, 4997, 5045, 5093, 5142, + 5190, 5239, 5287, 5336, 5385, 5433, 5481, 5530, 5578, 5627, 5676, 5724, 5773, 5821, + 5869, 5918, 5966, 6016, 6064, 6112, 6161, 6209, 6306, 6404, 6500, 6597, 6694, 6792, + 6888, 6985, 7083, 7180, 7276, 7373, 7471, 7568, 7664, 7761, 7859, 7956, 8052, 8150, + 8247, 8344, 8440, 8538, 8635, 8732, 8828, 8926, 9023, 9120, 9217, 9314, 9411, 9508, + 9605, 9702, 9799, 9896, 9993, 10090, 10187, 10285, 10381, 10478, 10575, 10673, 10769, + 10866, 10963, 11061, 11157, 11254, 11352, 11449, 11545, 11642, 11740, 11837, 11933, + 12030, 12128, 12225, 12321, 12419, 12613, 12807, 13001, 13195, 13389, 13583, 13777, + 13971, 14166, 14359, 14554, 14747, 14942, 15135, 15330, 15523, 15718, 15911, 16106, + 16300, 16494, 16688, 16882, 17076, 17270, 17464, 17658, 17852, 18046, 18240, 18435, + 18628, 18823, 19016, 19211, 19404, 19599, 19792, 19987, 20180, 20375, 20569, 20763, + 20957, 21151, 21345, 21539, 21733, 21927, 22121, 22316, 22509, 22704, 22897, 23092, + 23285, 23480, 23673, 23868, 24061, 24256, 24450, 24644, +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[288]) { + *pu32AgainLin = Again_table[288]; + *pu32AgainDb = 288; + return CVI_SUCCESS; + } + + for (i = 1; i < 289; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 dgain = *pu32DgainLin; + CVI_U32 dgainBase; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + + /* range check */ + if (dgain > g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max) { + *pu32DgainLin = g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + *pu32DgainDb = g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + return CVI_SUCCESS; + } + if (dgain < 1024) { + *pu32DgainLin = 1024; + *pu32DgainDb = 1024; + return CVI_SUCCESS; + } + /* find the base then use 1/128 as step */ + if (dgain < 2048) + dgainBase = 1024; + else if (dgain < 4096) + dgainBase = 2048; + else if (dgain < 8192) + dgainBase = 4096; + else if (dgain < 16384) + dgainBase = 8192; + else + dgainBase = 16384; + dgain = dgain * 128 / dgainBase; + *pu32DgainLin = dgainBase * dgain / 128; + *pu32DgainDb = *pu32DgainLin; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + CVI_U32 dgainReg; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u16Mode = g_au16SC500AI_GainMode[ViPipe]; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + static bool bGainLogicChanged[VI_MAX_PIPE_NUM] = {true}; + CVI_U32 dgainBase; + + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + // control sensor DPC to fix high-gain noise + if (Again_table[u32Again] >= 30720 && bGainLogicChanged[ViPipe]) { + sc500ai_write_register(ViPipe, 0x5799, 0x7); + bGainLogicChanged[ViPipe] = false; + } else if (Again_table[u32Again] <= 20480 && !bGainLogicChanged[ViPipe]) { + sc500ai_write_register(ViPipe, 0x5799, 0x0); + bGainLogicChanged[ViPipe] = true; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + if (u32Dgain > g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max) + u32Dgain = g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + if (u32Dgain < 1024) + u32Dgain = 1024; + /* find the base then use 1/128 as step */ + if (u32Dgain < 2048) { + dgainBase = 1024; + dgainReg = 0x0; + } else if (u32Dgain < 4096) { + dgainBase = 2048; + dgainReg = 0x1; + } else if (u32Dgain < 8192) { + dgainBase = 4096; + dgainReg = 0x3; + } else if (u32Dgain < 16384) { + dgainBase = 8192; + dgainReg = 0x7; + } else { + dgainBase = 16384; + dgainReg = 0xf; + } + u32Dgain = u32Dgain * 128 / dgainBase; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0_ADDR].u32Data = (dgainReg & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1_ADDR].u32Data = (u32Dgain & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + /* find SEF Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find SEF Dgain register setting. */ + if (u32Dgain > g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max) + u32Dgain = g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + if (u32Dgain < 1024) + u32Dgain = 1024; + /* find the base then use 1/128 as step */ + if (u32Dgain < 2048) { + dgainBase = 1024; + dgainReg = 0x0; + } else if (u32Dgain < 4096) { + dgainBase = 2048; + dgainReg = 0x1; + } else if (u32Dgain < 8192) { + dgainBase = 4096; + dgainReg = 0x3; + } else if (u32Dgain < 16384) { + dgainBase = 8192; + dgainReg = 0x7; + } else { + dgainBase = 16384; + dgainReg = 0xf; + } + u32Dgain = u32Dgain * 128 / dgainBase; + + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_0_ADDR].u32Data = (dgainReg & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_1_ADDR].u32Data = (u32Dgain & 0xFF); + + u32Again = pu32Again[1]; + u32Dgain = pu32Dgain[1]; + + /* find LEF Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find LEF Dgain register setting. */ + if (u32Dgain > g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max) + u32Dgain = g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + if (u32Dgain < 1024) + u32Dgain = 1024; + /* find the base then use 1/128 as step */ + if (u32Dgain < 2048) { + dgainBase = 1024; + dgainReg = 0x0; + } else if (u32Dgain < 4096) { + dgainBase = 2048; + dgainReg = 0x1; + } else if (u32Dgain < 8192) { + dgainBase = 4096; + dgainReg = 0x3; + } else if (u32Dgain < 16384) { + dgainBase = 8192; + dgainReg = 0x7; + } else { + dgainBase = 16384; + dgainReg = 0xf; + } + u32Dgain = u32Dgain * 128 / dgainBase; + + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_0_ADDR].u32Data = (dgainReg & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_1_ADDR].u32Data = (u32Dgain & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_0_ADDR].u32Data = (info->regGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1_1_ADDR].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + if (u32Dgain > g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max) + u32Dgain = g_astSC500AI_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + if (u32Dgain < 1024) + u32Dgain = 1024; + /* find the base then use 1/128 as step */ + if (u32Dgain < 2048) { + dgainBase = 1024; + dgainReg = 0x0; + } else if (u32Dgain < 4096) { + dgainBase = 2048; + dgainReg = 0x1; + } else if (u32Dgain < 8192) { + dgainBase = 4096; + dgainReg = 0x3; + } else if (u32Dgain < 16384) { + dgainBase = 8192; + dgainReg = 0x7; + } else { + dgainBase = 16384; + dgainReg = 0xf; + } + u32Dgain = u32Dgain * 128 / dgainBase; + + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_0_ADDR].u32Data = (dgainReg & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_0_ADDR].u32Data = (dgainReg & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_1_ADDR].u32Data = (u32Dgain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_1_ADDR].u32Data = (u32Dgain & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0; + CVI_U32 u32ShortTimeMinLimit = 5; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32MaxSexp = 2 * g_astSC500AI_State[ViPipe].u32Sexp_MAX - 14; + + (void) u16ManRatioEnable; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + /* short exposure reg range: + * min : 5 + * max : 2 * (max sexp - 7) + * step : 4 + * long exposure reg range: + * min : 5 + * max : 2 * (vts - max sexp - 9) + * step : 4 + */ + u32IntTimeMaxTmp = ((2 * pstSnsState->au32FL[0] - 16) * 0x40) / (au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32MaxSexp) ? u32MaxSexp : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp < u32ShortTimeMinLimit) ? u32ShortTimeMinLimit : u32IntTimeMaxTmp; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + syslog(LOG_DEBUG, "ViPipe = %d ratio = %d, (%d, %d)\n", ViPipe, au32Ratio[0], + u32IntTimeMaxTmp, u32ShortTimeMinLimit); + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC500AI_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC500AI_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == SC500AI_MODE_1620P30_WDR) + pstSnsState->u8ImgMode = SC500AI_MODE_1620P30; + else if (pstSnsState->u8ImgMode == SC500AI_MODE_1440P30_WDR) + pstSnsState->u8ImgMode = SC500AI_MODE_1440P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC500AI_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == SC500AI_MODE_1620P30) + pstSnsState->u8ImgMode = SC500AI_MODE_1620P30_WDR; + else if (pstSnsState->u8ImgMode == SC500AI_MODE_1440P30) + pstSnsState->u8ImgMode = SC500AI_MODE_1440P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astSC500AI_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "2to1 line WDR 1080p mode(60fps->30fps)\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC500AI_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc500ai_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc500ai_addr_byte; + pstI2c_data[i].u32DataByteNum = sc500ai_data_byte; + } + + //DOL 2t1 Mode Regs + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + //WDR Mode Regs + pstI2c_data[WDR2_SHS1_0_ADDR].u32RegAddr = SC500AI_SHS1_0_ADDR; + pstI2c_data[WDR2_SHS1_1_ADDR].u32RegAddr = SC500AI_SHS1_1_ADDR; + pstI2c_data[WDR2_SHS1_2_ADDR].u32RegAddr = SC500AI_SHS1_2_ADDR; + pstI2c_data[WDR2_SHS2_0_ADDR].u32RegAddr = SC500AI_SHS2_0_ADDR; + pstI2c_data[WDR2_SHS2_1_ADDR].u32RegAddr = SC500AI_SHS2_1_ADDR; + pstI2c_data[WDR2_SHS2_2_ADDR].u32RegAddr = SC500AI_SHS2_2_ADDR; + pstI2c_data[WDR2_AGAIN1_0_ADDR].u32RegAddr = SC500AI_AGAIN1_ADDR; + pstI2c_data[WDR2_AGAIN1_1_ADDR].u32RegAddr = SC500AI_AGAIN1_ADDR + 1; + pstI2c_data[WDR2_DGAIN1_0_ADDR].u32RegAddr = SC500AI_DGAIN1_ADDR; + pstI2c_data[WDR2_DGAIN1_1_ADDR].u32RegAddr = SC500AI_DGAIN1_ADDR + 1; + pstI2c_data[WDR2_AGAIN2_0_ADDR].u32RegAddr = SC500AI_AGAIN2_ADDR; + pstI2c_data[WDR2_AGAIN2_1_ADDR].u32RegAddr = SC500AI_AGAIN2_ADDR + 1; + pstI2c_data[WDR2_DGAIN2_0_ADDR].u32RegAddr = SC500AI_DGAIN2_ADDR; + pstI2c_data[WDR2_DGAIN2_1_ADDR].u32RegAddr = SC500AI_DGAIN2_ADDR + 1; + pstI2c_data[WDR2_VMAX_0_ADDR].u32RegAddr = SC500AI_VMAX_ADDR; + pstI2c_data[WDR2_VMAX_1_ADDR].u32RegAddr = SC500AI_VMAX_ADDR + 1; + pstI2c_data[WDR2_MAXSEXP_0_ADDR].u32RegAddr = SC500AI_MAXSEXP_ADDR; + pstI2c_data[WDR2_MAXSEXP_1_ADDR].u32RegAddr = SC500AI_MAXSEXP_ADDR + 1; + + break; + default: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC500AI_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC500AI_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC500AI_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC500AI_AGAIN1_ADDR; + pstI2c_data[LINEAR_AGAIN_1_ADDR].u32RegAddr = SC500AI_AGAIN1_ADDR + 1; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC500AI_DGAIN1_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC500AI_DGAIN1_ADDR + 1; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC500AI_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC500AI_VMAX_ADDR + 1; + + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC500AI_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC500AI_MODE_1440P30; + } else if (SC500AI_RES_IS_1620P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC500AI_MODE_1620P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (SC500AI_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC500AI_MODE_1440P30_WDR; + } else if (SC500AI_RES_IS_1620P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC500AI_MODE_1620P30_WDR; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC500AI_MODE_S *pstMode = CVI_NULL; + + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC500AI_MODE_1620P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC500AI_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC500AI_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc500ai_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC500AI_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC500AI_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } else { + pstRxAttr->mac_clk = RX_MAC_CLK_400M; + } + if (pstSnsState->u8ImgMode == SC500AI_MODE_1440P30) + pstRxAttr->mipi_attr.dphy.hs_settle = 8; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc500ai_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc500ai_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc500ai_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc500ai_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC500AI_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC500AI_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC500AI_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC500AI_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC500AI_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC500AI_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC500AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC500AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC500AI_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC500AI_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC500AI_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC500AI_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc500ai_standby, + .pfnRestart = sc500ai_restart, + .pfnMirrorFlip = sc500ai_mirror_flip, + .pfnWriteReg = sc500ai_write_register, + .pfnReadReg = sc500ai_read_register, + .pfnSetBusInfo = sc500ai_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc500ai_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc500ai/sc500ai_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc500ai/sc500ai_cmos_ex.h new file mode 100644 index 000000000..7438fd9c5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc500ai/sc500ai_cmos_ex.h @@ -0,0 +1,110 @@ +#ifndef __SC500AI_CMOS_EX_H_ +#define __SC500AI_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc500ai_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_2_ADDR, + LINEAR_AGAIN_0_ADDR, + LINEAR_AGAIN_1_ADDR, + LINEAR_DGAIN_0_ADDR, + LINEAR_DGAIN_1_ADDR, + LINEAR_VMAX_0_ADDR, + LINEAR_VMAX_1_ADDR, + LINEAR_REGS_NUM +}; + +enum sc500ai_dol2_regs_e { + WDR2_SHS1_0_ADDR, + WDR2_SHS1_1_ADDR, + WDR2_SHS1_2_ADDR, + WDR2_SHS2_0_ADDR, + WDR2_SHS2_1_ADDR, + WDR2_SHS2_2_ADDR, + WDR2_AGAIN1_0_ADDR, + WDR2_AGAIN1_1_ADDR, + WDR2_DGAIN1_0_ADDR, + WDR2_DGAIN1_1_ADDR, + WDR2_AGAIN2_0_ADDR, + WDR2_AGAIN2_1_ADDR, + WDR2_DGAIN2_0_ADDR, + WDR2_DGAIN2_1_ADDR, + WDR2_VMAX_0_ADDR, + WDR2_VMAX_1_ADDR, + WDR2_MAXSEXP_0_ADDR, + WDR2_MAXSEXP_1_ADDR, + WDR2_REGS_NUM +}; + +typedef enum _SC500AI_MODE_E { + SC500AI_MODE_1620P30 = 0, + SC500AI_MODE_1440P30, + SC500AI_MODE_LINEAR_NUM, + SC500AI_MODE_1620P30_WDR = SC500AI_MODE_LINEAR_NUM, + SC500AI_MODE_1440P30_WDR, + SC500AI_MODE_NUM +} SC500AI_MODE_E; + +typedef struct _SC500AI_STATE_S { + CVI_U32 u32Sexp_MAX; /* (2*{16’h3e23,16’h3e24} – 'd10)/2 */ +} SC500AI_STATE_S; + +typedef struct _SC500AI_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + CVI_U16 u16SexpMaxReg; /* {16’h3e23,16’h3e24} */ + char name[64]; +} SC500AI_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC500AI[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC500AI_BusInfo[]; +extern CVI_U16 g_au16SC500AI_GainMode[]; +extern CVI_U16 g_au16SC500AI_L2SMode[]; +extern const CVI_U8 sc500ai_i2c_addr; +extern const CVI_U32 sc500ai_addr_byte; +extern const CVI_U32 sc500ai_data_byte; +extern void sc500ai_init(VI_PIPE ViPipe); +extern void sc500ai_exit(VI_PIPE ViPipe); +extern void sc500ai_standby(VI_PIPE ViPipe); +extern void sc500ai_restart(VI_PIPE ViPipe); +extern int sc500ai_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc500ai_read_register(VI_PIPE ViPipe, int addr); +extern void sc500ai_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc500ai_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC500AI_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc500ai/sc500ai_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc500ai/sc500ai_cmos_param.h new file mode 100644 index 000000000..794712a2a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc500ai/sc500ai_cmos_param.h @@ -0,0 +1,394 @@ +#ifndef __SC500AI_CMOS_PARAM_H_ +#define __SC500AI_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc500ai_cmos_ex.h" + +static const SC500AI_MODE_S g_astSC500AI_mode[SC500AI_MODE_NUM] = { + [SC500AI_MODE_1620P30] = { + .name = "1620p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2880, + .u32Height = 1620, + }, + .stMaxSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.52, /* 1650 * 30 / 0x7FFF*/ + .u32HtsDef = 2560, /* NA */ + .u32VtsDef = 1650, + .stExp[0] = { + .u16Min = 3, + .u16Max = 3290, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 24644, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 32640, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [SC500AI_MODE_1620P30_WDR] = { + .name = "1620p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2880, + .u32Height = 1620, + }, + .stMaxSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2880, + .u32Height = 1620, + }, + .stMaxSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 3.03, /* 2250 * 30 / 0x7FFF*/ + .u32HtsDef = 640, /* NA */ + .u32VtsDef = 3300, + .u16SexpMaxReg = 0xc6, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 24644, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 32640, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 24644, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 32640, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [SC500AI_MODE_1440P30] = { + .name = "1440p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.38, /* 1650 * 30 / 0x7FFF*/ + .u32HtsDef = 3360, /* NA */ + .u32VtsDef = 1500, + .stExp[0] = { + .u16Min = 3, + .u16Max = 3290, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 24644, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 32640, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [SC500AI_MODE_1440P30_WDR] = { + .name = "1440p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.75, /* 3000 * 30 / 0x7FFF*/ + .u32HtsDef = 3000, /* NA */ + .u32VtsDef = 3000, + .u16SexpMaxReg = 0xb4, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 24644, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 32640, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 24644, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 32640, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.02792946062982082367, 3.36534714698791503906}, //B: slope, intercept + {0.02071751467883586884, 5.34583568572998046875}, //Gb: slope, intercept + {0.02110148966312408447, 5.02954530715942382813}, //Gr: slope, intercept + {0.02168512716889381409, 4.89776754379272460938}, //R: slope, intercept + }, + { //iso 200 + {0.03194080293178558350, 5.61192893981933593750}, //B: slope, intercept + {0.02428408525884151459, 7.94834280014038085938}, //Gb: slope, intercept + {0.02499442733824253082, 7.72430133819580078125}, //Gr: slope, intercept + {0.02584112435579299927, 7.20574426651000976563}, //R: slope, intercept + }, + { //iso 400 + {0.04612467437982559204, 6.88752269744873046875}, //B: slope, intercept + {0.03022909909486770630, 11.05101776123046875000}, //Gb: slope, intercept + {0.03175539523363113403, 10.60332489013671875000}, //Gr: slope, intercept + {0.03522306308150291443, 9.36425399780273437500}, //R: slope, intercept + }, + { //iso 800 + {0.06092500314116477966, 9.79670524597167968750}, //B: slope, intercept + {0.03984217345714569092, 15.30182266235351562500}, //Gb: slope, intercept + {0.04019560664892196655, 14.93132972717285156250}, //Gr: slope, intercept + {0.04470816254615783691, 13.26843166351318359375}, //R: slope, intercept + }, + { //iso 1600 + {0.08295634388923645020, 14.20334625244140625000}, //B: slope, intercept + {0.05075264349579811096, 20.99221038818359375000}, //Gb: slope, intercept + {0.05426201224327087402, 20.08068656921386718750}, //Gr: slope, intercept + {0.05945669487118721008, 19.02898788452148437500}, //R: slope, intercept + }, + { //iso 3200 + {0.09782519936561584473, 21.84967994689941406250}, //B: slope, intercept + {0.06690908223390579224, 26.53993988037109375000}, //Gb: slope, intercept + {0.06954573839902877808, 25.74129104614257812500}, //Gr: slope, intercept + {0.09061723947525024414, 22.98998260498046875000}, //R: slope, intercept + }, + { //iso 6400 + {0.14311420917510986328, 28.96467971801757812500}, //B: slope, intercept + {0.08148498833179473877, 37.93062591552734375000}, //Gb: slope, intercept + {0.08273542672395706177, 38.37096405029296875000}, //Gr: slope, intercept + {0.12093253433704376221, 33.31475067138671875000}, //R: slope, intercept + }, + { //iso 12800 + {0.17958122491836547852, 43.49506759643554687500}, //B: slope, intercept + {0.09839969873428344727, 55.43268966674804687500}, //Gb: slope, intercept + {0.10201884806156158447, 52.97607040405273437500}, //Gr: slope, intercept + {0.15302789211273193359, 47.54779434204101562500}, //R: slope, intercept + }, + { //iso 25600 + {0.25833165645599365234, 56.96470642089843750000}, //B: slope, intercept + {0.13260601460933685303, 74.69016265869140625000}, //Gb: slope, intercept + {0.14035490155220031738, 75.44366455078125000000}, //Gr: slope, intercept + {0.23465165495872497559, 60.52228164672851562500}, //R: slope, intercept + }, + { //iso 51200 + {0.37595292925834655762, 78.54853057861328125000}, //B: slope, intercept + {0.21475413441658020020, 102.12300872802734375000}, //Gb: slope, intercept + {0.20840260386466979980, 103.65763854980468750000}, //Gr: slope, intercept + {0.34428051114082336426, 87.83551025390625000000}, //R: slope, intercept + }, + { //iso 102400 + {0.51122575998306274414, 113.49224090576171875000}, //B: slope, intercept + {0.29245173931121826172, 154.26939392089843750000}, //Gb: slope, intercept + {0.31501635909080505371, 148.29017639160156250000}, //Gr: slope, intercept + {0.47034618258476257324, 124.06208038330078125000}, //R: slope, intercept + }, + { //iso 204800 + {0.67213481664657592773, 134.71751403808593750000}, //B: slope, intercept + {0.40368056297302246094, 189.80801391601562500000}, //Gb: slope, intercept + {0.43581819534301757813, 186.44682312011718750000}, //Gr: slope, intercept + {0.60127359628677368164, 160.66384887695312500000}, //R: slope, intercept + }, + { //iso 409600 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 819200 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {257, 260, 260, 260, 260, 261, 259, 258, /*8*/255, 248, 264, 300, 291, 310, 310, 311}, + {257, 260, 260, 260, 260, 261, 259, 257, /*8*/254, 247, 261, 296, 287, 309, 309, 306}, + {257, 260, 260, 260, 260, 261, 259, 257, /*8*/255, 248, 262, 298, 289, 308, 308, 308}, + {257, 260, 260, 260, 260, 261, 259, 258, /*8*/255, 247, 261, 301, 293, 310, 308, 314}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1095, 1105, 1102, 1108, 1108, 1108}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1104, 1101, 1108, 1108, 1107}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1104, 1102, 1107, 1107, 1107}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1105, 1103, 1108, 1107, 1109}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc500ai_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {1, 2, 0, 3, 4}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + .dphy = { + .enable = 1, + .hs_settle = 14, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC500AI_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc500ai/sc500ai_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc500ai/sc500ai_sensor_ctl.c new file mode 100644 index 000000000..cd783e392 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc500ai/sc500ai_sensor_ctl.c @@ -0,0 +1,846 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc500ai_cmos_ex.h" + +static void sc500ai_wdr_1620p30_2to1_init(VI_PIPE ViPipe); +static void sc500ai_linear_1620p30_init(VI_PIPE ViPipe); +static void sc500ai_wdr_1440p30_2to1_init(VI_PIPE ViPipe); +static void sc500ai_linear_1440p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc500ai_i2c_addr = 0x30; /* I2C Address of SC500AI */ +const CVI_U32 sc500ai_addr_byte = 2; +const CVI_U32 sc500ai_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc500ai_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC500AI_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc500ai_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc500ai_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc500ai_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc500ai_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc500ai_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc500ai_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc500ai_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc500ai_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc500ai_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc500ai_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc500ai_addr_byte + sc500ai_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc500ai_standby(VI_PIPE ViPipe) +{ + sc500ai_write_register(ViPipe, 0x0100, 0x00); +} + +void sc500ai_restart(VI_PIPE ViPipe) +{ + sc500ai_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc500ai_write_register(ViPipe, 0x0100, 0x01); +} + +void sc500ai_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC500AI[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc500ai_write_register(ViPipe, + g_pastSC500AI[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC500AI[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC500AI_CHIP_ID_HI_ADDR 0x3107 +#define SC500AI_CHIP_ID_LO_ADDR 0x3108 +#define SC500AI_CHIP_ID 0xce1f + +void sc500ai_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc500ai_write_register(ViPipe, 0x3221, val); +} + +static int sc500ai_init_ex(VI_PIPE ViPipe) +{ + CVI_U32 debounce = 0; + int nVal, cnt = 0; + CVI_U16 tmp = 0, tmpPrev = 0; + + while (debounce++ < 5) { + nVal = sc500ai_read_register(ViPipe, 0x3109); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "debounce read fail.\n"); + return nVal; + } + tmp = (nVal & 0xFF) << 8; + if (tmp != tmpPrev) + debounce = 0; + tmpPrev = tmp; + if (cnt++ > 20) { + CVI_TRACE_SNS(CVI_DBG_ERR, "debounce fail.\n"); + return nVal; + } + } + if (tmp == 1) { + sc500ai_write_register(ViPipe, 0x336d, 0x23); + } else { + sc500ai_write_register(ViPipe, 0x336d, 0x03); + } + + debounce = 0; + cnt = 0; + while (debounce++ < 5) { + nVal = sc500ai_read_register(ViPipe, 0x3040); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "debounce read fail.\n"); + return nVal; + } + tmp = (nVal & 0xFF) << 8; + if (tmp != tmpPrev) + debounce = 0; + tmpPrev = tmp; + if (cnt++ > 20) { + CVI_TRACE_SNS(CVI_DBG_ERR, "debounce fail.\n"); + return nVal; + } + } + if (tmp == 0) { + sc500ai_write_register(ViPipe, 0x363c, 0x42); + } else { + sc500ai_write_register(ViPipe, 0x363c, 0x40); + } + + return CVI_SUCCESS; +} + +int sc500ai_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + delay_ms(4); + if (sc500ai_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc500ai_read_register(ViPipe, SC500AI_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc500ai_read_register(ViPipe, SC500AI_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC500AI_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc500ai_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + CVI_U8 u8ImgMode; + + bInit = g_pastSC500AI[ViPipe]->bInit; + enWDRMode = g_pastSC500AI[ViPipe]->enWDRMode; + u8ImgMode = g_pastSC500AI[ViPipe]->u8ImgMode; + + sc500ai_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == SC500AI_MODE_1620P30_WDR) { + /* SC500AI_MODE_1620P30_WDR */ + sc500ai_wdr_1620p30_2to1_init(ViPipe); + } else if (u8ImgMode == SC500AI_MODE_1440P30_WDR) { + /* SC500AI_MODE_1620P30_WDR */ + sc500ai_wdr_1440p30_2to1_init(ViPipe); + } else { + } + } else { + if (u8ImgMode == SC500AI_MODE_1620P30) { + sc500ai_linear_1620p30_init(ViPipe); + } else if (u8ImgMode == SC500AI_MODE_1440P30) { + /* SC500AI_MODE_1440P30 */ + sc500ai_linear_1440p30_init(ViPipe); + } else { + } + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == SC500AI_MODE_1620P30_WDR) { + /* SC500AI_MODE_1620P30_WDR */ + sc500ai_wdr_1620p30_2to1_init(ViPipe); + } else if (u8ImgMode == SC500AI_MODE_1440P30_WDR) { + /* SC500AI_MODE_1620P30_WDR */ + sc500ai_wdr_1440p30_2to1_init(ViPipe); + } else { + } + } else { + if (u8ImgMode == SC500AI_MODE_1620P30) { + sc500ai_linear_1620p30_init(ViPipe); + } else if (u8ImgMode == SC500AI_MODE_1440P30) { + /* SC500AI_MODE_1440P30 */ + sc500ai_linear_1440p30_init(ViPipe); + } else { + } + } + } + g_pastSC500AI[ViPipe]->bInit = CVI_TRUE; +} + +void sc500ai_exit(VI_PIPE ViPipe) +{ + sc500ai_i2c_exit(ViPipe); +} + +/* 1620P30 and 1620P25 */ +static void sc500ai_linear_1620p30_init(VI_PIPE ViPipe) +{ + sc500ai_write_register(ViPipe, 0x0103, 0x01); + sc500ai_write_register(ViPipe, 0x0100, 0x00); + sc500ai_write_register(ViPipe, 0x36e9, 0x80); + sc500ai_write_register(ViPipe, 0x36f9, 0x80); + sc500ai_write_register(ViPipe, 0x301f, 0x01); + sc500ai_write_register(ViPipe, 0x3253, 0x0a); + sc500ai_write_register(ViPipe, 0x3301, 0x0a); + sc500ai_write_register(ViPipe, 0x3302, 0x18); + sc500ai_write_register(ViPipe, 0x3303, 0x10); + sc500ai_write_register(ViPipe, 0x3304, 0x60); + sc500ai_write_register(ViPipe, 0x3306, 0x60); + sc500ai_write_register(ViPipe, 0x3308, 0x10); + sc500ai_write_register(ViPipe, 0x3309, 0x70); + sc500ai_write_register(ViPipe, 0x330a, 0x00); + sc500ai_write_register(ViPipe, 0x330b, 0xf0); + sc500ai_write_register(ViPipe, 0x330d, 0x18); + sc500ai_write_register(ViPipe, 0x330e, 0x20); + sc500ai_write_register(ViPipe, 0x330f, 0x02); + sc500ai_write_register(ViPipe, 0x3310, 0x02); + sc500ai_write_register(ViPipe, 0x331c, 0x04); + sc500ai_write_register(ViPipe, 0x331e, 0x51); + sc500ai_write_register(ViPipe, 0x331f, 0x61); + sc500ai_write_register(ViPipe, 0x3320, 0x09); + sc500ai_write_register(ViPipe, 0x3333, 0x10); + sc500ai_write_register(ViPipe, 0x334c, 0x08); + sc500ai_write_register(ViPipe, 0x3356, 0x09); + sc500ai_write_register(ViPipe, 0x3364, 0x17); + sc500ai_write_register(ViPipe, 0x336d, 0x03); + sc500ai_write_register(ViPipe, 0x3390, 0x08); + sc500ai_write_register(ViPipe, 0x3391, 0x18); + sc500ai_write_register(ViPipe, 0x3392, 0x38); + sc500ai_write_register(ViPipe, 0x3393, 0x0a); + sc500ai_write_register(ViPipe, 0x3394, 0x20); + sc500ai_write_register(ViPipe, 0x3395, 0x20); + sc500ai_write_register(ViPipe, 0x3396, 0x08); + sc500ai_write_register(ViPipe, 0x3397, 0x18); + sc500ai_write_register(ViPipe, 0x3398, 0x38); + sc500ai_write_register(ViPipe, 0x3399, 0x0a); + sc500ai_write_register(ViPipe, 0x339a, 0x20); + sc500ai_write_register(ViPipe, 0x339b, 0x20); + sc500ai_write_register(ViPipe, 0x339c, 0x20); + sc500ai_write_register(ViPipe, 0x33ac, 0x10); + sc500ai_write_register(ViPipe, 0x33ae, 0x10); + sc500ai_write_register(ViPipe, 0x33af, 0x19); + sc500ai_write_register(ViPipe, 0x360f, 0x01); + sc500ai_write_register(ViPipe, 0x3622, 0x03); + sc500ai_write_register(ViPipe, 0x363a, 0x1f); + sc500ai_write_register(ViPipe, 0x363c, 0x40); + sc500ai_write_register(ViPipe, 0x3651, 0x7d); + sc500ai_write_register(ViPipe, 0x3670, 0x0a); + sc500ai_write_register(ViPipe, 0x3671, 0x07); + sc500ai_write_register(ViPipe, 0x3672, 0x17); + sc500ai_write_register(ViPipe, 0x3673, 0x1e); + sc500ai_write_register(ViPipe, 0x3674, 0x82); + sc500ai_write_register(ViPipe, 0x3675, 0x64); + sc500ai_write_register(ViPipe, 0x3676, 0x66); + sc500ai_write_register(ViPipe, 0x367a, 0x48); + sc500ai_write_register(ViPipe, 0x367b, 0x78); + sc500ai_write_register(ViPipe, 0x367c, 0x58); + sc500ai_write_register(ViPipe, 0x367d, 0x78); + sc500ai_write_register(ViPipe, 0x3690, 0x34); + sc500ai_write_register(ViPipe, 0x3691, 0x34); + sc500ai_write_register(ViPipe, 0x3692, 0x54); + sc500ai_write_register(ViPipe, 0x369c, 0x48); + sc500ai_write_register(ViPipe, 0x369d, 0x78); + sc500ai_write_register(ViPipe, 0x36ec, 0x1a); + sc500ai_write_register(ViPipe, 0x3904, 0x04); + sc500ai_write_register(ViPipe, 0x3908, 0x41); + sc500ai_write_register(ViPipe, 0x391d, 0x04); + sc500ai_write_register(ViPipe, 0x39c2, 0x30); + sc500ai_write_register(ViPipe, 0x3e01, 0xcd); + sc500ai_write_register(ViPipe, 0x3e02, 0xc0); + sc500ai_write_register(ViPipe, 0x3e16, 0x00); + sc500ai_write_register(ViPipe, 0x3e17, 0x80); + sc500ai_write_register(ViPipe, 0x4500, 0x88); + sc500ai_write_register(ViPipe, 0x4509, 0x20); + sc500ai_write_register(ViPipe, 0x481b, 0x50); // hs-trail + sc500ai_write_register(ViPipe, 0x5799, 0x00); + sc500ai_write_register(ViPipe, 0x59e0, 0x60); + sc500ai_write_register(ViPipe, 0x59e1, 0x08); + sc500ai_write_register(ViPipe, 0x59e2, 0x3f); + sc500ai_write_register(ViPipe, 0x59e3, 0x18); + sc500ai_write_register(ViPipe, 0x59e4, 0x18); + sc500ai_write_register(ViPipe, 0x59e5, 0x3f); + sc500ai_write_register(ViPipe, 0x59e7, 0x02); + sc500ai_write_register(ViPipe, 0x59e8, 0x38); + sc500ai_write_register(ViPipe, 0x59e9, 0x20); + sc500ai_write_register(ViPipe, 0x59ea, 0x0c); + sc500ai_write_register(ViPipe, 0x59ec, 0x08); + sc500ai_write_register(ViPipe, 0x59ed, 0x02); + sc500ai_write_register(ViPipe, 0x59ee, 0xa0); + sc500ai_write_register(ViPipe, 0x59ef, 0x08); + sc500ai_write_register(ViPipe, 0x59f4, 0x18); + sc500ai_write_register(ViPipe, 0x59f5, 0x10); + sc500ai_write_register(ViPipe, 0x59f6, 0x0c); + sc500ai_write_register(ViPipe, 0x59f9, 0x02); + sc500ai_write_register(ViPipe, 0x59fa, 0x18); + sc500ai_write_register(ViPipe, 0x59fb, 0x10); + sc500ai_write_register(ViPipe, 0x59fc, 0x0c); + sc500ai_write_register(ViPipe, 0x59ff, 0x02); + sc500ai_write_register(ViPipe, 0x36e9, 0x1c); + sc500ai_write_register(ViPipe, 0x36f9, 0x24); + sc500ai_init_ex(ViPipe); + + sc500ai_default_reg_init(ViPipe); + + sc500ai_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC500AI 1620P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +static void sc500ai_wdr_1620p30_2to1_init(VI_PIPE ViPipe) +{ + sc500ai_write_register(ViPipe, 0x0103, 0x01); + sc500ai_write_register(ViPipe, 0x0100, 0x00); + sc500ai_write_register(ViPipe, 0x36e9, 0x80); + sc500ai_write_register(ViPipe, 0x36f9, 0x80); + sc500ai_write_register(ViPipe, 0x301f, 0x06); + sc500ai_write_register(ViPipe, 0x3106, 0x01); + sc500ai_write_register(ViPipe, 0x320e, 0x0c); + sc500ai_write_register(ViPipe, 0x320f, 0xe4); + sc500ai_write_register(ViPipe, 0x3220, 0x53); + sc500ai_write_register(ViPipe, 0x3250, 0xff); + sc500ai_write_register(ViPipe, 0x3253, 0x0a); + sc500ai_write_register(ViPipe, 0x3301, 0x0b); + sc500ai_write_register(ViPipe, 0x3302, 0x20); + sc500ai_write_register(ViPipe, 0x3303, 0x10); + sc500ai_write_register(ViPipe, 0x3304, 0x70); + sc500ai_write_register(ViPipe, 0x3306, 0x50); + sc500ai_write_register(ViPipe, 0x3308, 0x18); + sc500ai_write_register(ViPipe, 0x3309, 0x80); + sc500ai_write_register(ViPipe, 0x330a, 0x00); + sc500ai_write_register(ViPipe, 0x330b, 0xe8); + sc500ai_write_register(ViPipe, 0x330d, 0x30); + sc500ai_write_register(ViPipe, 0x330e, 0x30); + sc500ai_write_register(ViPipe, 0x330f, 0x02); + sc500ai_write_register(ViPipe, 0x3310, 0x02); + sc500ai_write_register(ViPipe, 0x331c, 0x08); + sc500ai_write_register(ViPipe, 0x331e, 0x61); + sc500ai_write_register(ViPipe, 0x331f, 0x71); + sc500ai_write_register(ViPipe, 0x3320, 0x11); + sc500ai_write_register(ViPipe, 0x3333, 0x10); + sc500ai_write_register(ViPipe, 0x334c, 0x10); + sc500ai_write_register(ViPipe, 0x3356, 0x11); + sc500ai_write_register(ViPipe, 0x3364, 0x17); + sc500ai_write_register(ViPipe, 0x336d, 0x03); + sc500ai_write_register(ViPipe, 0x3390, 0x08); + sc500ai_write_register(ViPipe, 0x3391, 0x18); + sc500ai_write_register(ViPipe, 0x3392, 0x38); + sc500ai_write_register(ViPipe, 0x3393, 0x0a); + sc500ai_write_register(ViPipe, 0x3394, 0x0a); + sc500ai_write_register(ViPipe, 0x3395, 0x12); + sc500ai_write_register(ViPipe, 0x3396, 0x08); + sc500ai_write_register(ViPipe, 0x3397, 0x18); + sc500ai_write_register(ViPipe, 0x3398, 0x38); + sc500ai_write_register(ViPipe, 0x3399, 0x0a); + sc500ai_write_register(ViPipe, 0x339a, 0x0a); + sc500ai_write_register(ViPipe, 0x339b, 0x0a); + sc500ai_write_register(ViPipe, 0x339c, 0x12); + sc500ai_write_register(ViPipe, 0x33ac, 0x10); + sc500ai_write_register(ViPipe, 0x33ae, 0x20); + sc500ai_write_register(ViPipe, 0x33af, 0x21); + sc500ai_write_register(ViPipe, 0x360f, 0x01); + sc500ai_write_register(ViPipe, 0x3621, 0xe8); + sc500ai_write_register(ViPipe, 0x3622, 0x06); + sc500ai_write_register(ViPipe, 0x3630, 0x82); + sc500ai_write_register(ViPipe, 0x3633, 0x33); + sc500ai_write_register(ViPipe, 0x3634, 0x64); + sc500ai_write_register(ViPipe, 0x3637, 0x50); + sc500ai_write_register(ViPipe, 0x363a, 0x1f); + sc500ai_write_register(ViPipe, 0x363c, 0x40); + sc500ai_write_register(ViPipe, 0x3651, 0x7d); + sc500ai_write_register(ViPipe, 0x3670, 0x0a); + sc500ai_write_register(ViPipe, 0x3671, 0x06); + sc500ai_write_register(ViPipe, 0x3672, 0x16); + sc500ai_write_register(ViPipe, 0x3673, 0x17); + sc500ai_write_register(ViPipe, 0x3674, 0x82); + sc500ai_write_register(ViPipe, 0x3675, 0x62); + sc500ai_write_register(ViPipe, 0x3676, 0x44); + sc500ai_write_register(ViPipe, 0x367a, 0x48); + sc500ai_write_register(ViPipe, 0x367b, 0x78); + sc500ai_write_register(ViPipe, 0x367c, 0x48); + sc500ai_write_register(ViPipe, 0x367d, 0x58); + sc500ai_write_register(ViPipe, 0x3690, 0x34); + sc500ai_write_register(ViPipe, 0x3691, 0x34); + sc500ai_write_register(ViPipe, 0x3692, 0x54); + sc500ai_write_register(ViPipe, 0x369c, 0x48); + sc500ai_write_register(ViPipe, 0x369d, 0x78); + sc500ai_write_register(ViPipe, 0x36ea, 0x35); + sc500ai_write_register(ViPipe, 0x36eb, 0x04); + sc500ai_write_register(ViPipe, 0x36ec, 0x0a); + sc500ai_write_register(ViPipe, 0x36ed, 0x14); + sc500ai_write_register(ViPipe, 0x36fa, 0x35); + sc500ai_write_register(ViPipe, 0x36fb, 0x04); + sc500ai_write_register(ViPipe, 0x36fc, 0x00); + sc500ai_write_register(ViPipe, 0x36fd, 0x16); + sc500ai_write_register(ViPipe, 0x3904, 0x04); + sc500ai_write_register(ViPipe, 0x3908, 0x41); + sc500ai_write_register(ViPipe, 0x391f, 0x10); + sc500ai_write_register(ViPipe, 0x39c2, 0x30); + sc500ai_write_register(ViPipe, 0x3e00, 0x01); + sc500ai_write_register(ViPipe, 0x3e01, 0x82); + sc500ai_write_register(ViPipe, 0x3e02, 0x00); + sc500ai_write_register(ViPipe, 0x3e04, 0x18); + sc500ai_write_register(ViPipe, 0x3e05, 0x20); + sc500ai_write_register(ViPipe, 0x3e23, 0x00); + sc500ai_write_register(ViPipe, 0x3e24, 0xc6); + sc500ai_write_register(ViPipe, 0x4500, 0x88); + sc500ai_write_register(ViPipe, 0x4509, 0x20); + sc500ai_write_register(ViPipe, 0x4800, 0x04); + sc500ai_write_register(ViPipe, 0x4837, 0x15); + sc500ai_write_register(ViPipe, 0x4853, 0xfd); + sc500ai_write_register(ViPipe, 0x481b, 0x50); // hs-trail + sc500ai_write_register(ViPipe, 0x36e9, 0x44); + sc500ai_write_register(ViPipe, 0x36f9, 0x44); + sc500ai_write_register(ViPipe, 0x0100, 0x01); + sc500ai_init_ex(ViPipe); + + sc500ai_default_reg_init(ViPipe); + + sc500ai_write_register(ViPipe, 0x0100, 0x01); + + delay_ms(50); + + printf("===SC500AI sensor 1620P30fps 10bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} + +/* 1440P30 and 1440P25 */ +static void sc500ai_linear_1440p30_init(VI_PIPE ViPipe) +{ + sc500ai_write_register(ViPipe, 0x0103, 0x01); + sc500ai_write_register(ViPipe, 0x0100, 0x00); + sc500ai_write_register(ViPipe, 0x36e9, 0x80); + sc500ai_write_register(ViPipe, 0x36f9, 0x80); + sc500ai_write_register(ViPipe, 0x301f, 0x03); + sc500ai_write_register(ViPipe, 0x3200, 0x00); + sc500ai_write_register(ViPipe, 0x3201, 0xa0); + sc500ai_write_register(ViPipe, 0x3202, 0x00); + sc500ai_write_register(ViPipe, 0x3203, 0x5a); + sc500ai_write_register(ViPipe, 0x3204, 0x0a); + sc500ai_write_register(ViPipe, 0x3205, 0xa7); + sc500ai_write_register(ViPipe, 0x3206, 0x06); + sc500ai_write_register(ViPipe, 0x3207, 0x01); + sc500ai_write_register(ViPipe, 0x3208, 0x0a); + sc500ai_write_register(ViPipe, 0x3209, 0x00); + sc500ai_write_register(ViPipe, 0x320a, 0x05); + sc500ai_write_register(ViPipe, 0x320b, 0xa0); + sc500ai_write_register(ViPipe, 0x320c, 0x05); + sc500ai_write_register(ViPipe, 0x320d, 0x78); + sc500ai_write_register(ViPipe, 0x320e, 0x05); + sc500ai_write_register(ViPipe, 0x320f, 0xdc); + sc500ai_write_register(ViPipe, 0x3210, 0x00); + sc500ai_write_register(ViPipe, 0x3211, 0x04); + sc500ai_write_register(ViPipe, 0x3212, 0x00); + sc500ai_write_register(ViPipe, 0x3213, 0x04); + sc500ai_write_register(ViPipe, 0x3253, 0x0a); + sc500ai_write_register(ViPipe, 0x3301, 0x08); + sc500ai_write_register(ViPipe, 0x3302, 0x18); + sc500ai_write_register(ViPipe, 0x3303, 0x10); + sc500ai_write_register(ViPipe, 0x3304, 0x4c); + sc500ai_write_register(ViPipe, 0x3306, 0x44); + sc500ai_write_register(ViPipe, 0x3308, 0x10); + sc500ai_write_register(ViPipe, 0x3309, 0x58); + sc500ai_write_register(ViPipe, 0x330a, 0x00); + sc500ai_write_register(ViPipe, 0x330b, 0xd8); + sc500ai_write_register(ViPipe, 0x330d, 0x14); + sc500ai_write_register(ViPipe, 0x330e, 0x20); + sc500ai_write_register(ViPipe, 0x330f, 0x02); + sc500ai_write_register(ViPipe, 0x3310, 0x02); + sc500ai_write_register(ViPipe, 0x331c, 0x04); + sc500ai_write_register(ViPipe, 0x331e, 0x3d); + sc500ai_write_register(ViPipe, 0x331f, 0x49); + sc500ai_write_register(ViPipe, 0x3320, 0x09); + sc500ai_write_register(ViPipe, 0x3333, 0x10); + sc500ai_write_register(ViPipe, 0x334c, 0x08); + sc500ai_write_register(ViPipe, 0x3356, 0x09); + sc500ai_write_register(ViPipe, 0x3364, 0x17); + sc500ai_write_register(ViPipe, 0x336d, 0x03); + sc500ai_write_register(ViPipe, 0x3390, 0x08); + sc500ai_write_register(ViPipe, 0x3391, 0x18); + sc500ai_write_register(ViPipe, 0x3392, 0x38); + sc500ai_write_register(ViPipe, 0x3393, 0x08); + sc500ai_write_register(ViPipe, 0x3394, 0x20); + sc500ai_write_register(ViPipe, 0x3395, 0x20); + sc500ai_write_register(ViPipe, 0x3396, 0x08); + sc500ai_write_register(ViPipe, 0x3397, 0x18); + sc500ai_write_register(ViPipe, 0x3398, 0x38); + sc500ai_write_register(ViPipe, 0x3399, 0x08); + sc500ai_write_register(ViPipe, 0x339a, 0x20); + sc500ai_write_register(ViPipe, 0x339b, 0x20); + sc500ai_write_register(ViPipe, 0x339c, 0x20); + sc500ai_write_register(ViPipe, 0x33ac, 0x10); + sc500ai_write_register(ViPipe, 0x33ae, 0x10); + sc500ai_write_register(ViPipe, 0x33af, 0x19); + sc500ai_write_register(ViPipe, 0x360f, 0x01); + sc500ai_write_register(ViPipe, 0x3622, 0x03); + sc500ai_write_register(ViPipe, 0x363a, 0x1f); + sc500ai_write_register(ViPipe, 0x363c, 0x40); + sc500ai_write_register(ViPipe, 0x3651, 0x7d); + sc500ai_write_register(ViPipe, 0x3670, 0x0a); + sc500ai_write_register(ViPipe, 0x3671, 0x07); + sc500ai_write_register(ViPipe, 0x3672, 0x17); + sc500ai_write_register(ViPipe, 0x3673, 0x1e); + sc500ai_write_register(ViPipe, 0x3674, 0x82); + sc500ai_write_register(ViPipe, 0x3675, 0x64); + sc500ai_write_register(ViPipe, 0x3676, 0x66); + sc500ai_write_register(ViPipe, 0x367a, 0x48); + sc500ai_write_register(ViPipe, 0x367b, 0x78); + sc500ai_write_register(ViPipe, 0x367c, 0x58); + sc500ai_write_register(ViPipe, 0x367d, 0x78); + sc500ai_write_register(ViPipe, 0x3690, 0x34); + sc500ai_write_register(ViPipe, 0x3691, 0x34); + sc500ai_write_register(ViPipe, 0x3692, 0x54); + sc500ai_write_register(ViPipe, 0x369c, 0x48); + sc500ai_write_register(ViPipe, 0x369d, 0x78); + sc500ai_write_register(ViPipe, 0x36ea, 0x39); + sc500ai_write_register(ViPipe, 0x36eb, 0x0e); + sc500ai_write_register(ViPipe, 0x36ec, 0x1a); + sc500ai_write_register(ViPipe, 0x36ed, 0x34); + sc500ai_write_register(ViPipe, 0x36fa, 0x32); + sc500ai_write_register(ViPipe, 0x36fb, 0x0e); + sc500ai_write_register(ViPipe, 0x36fc, 0x10); + sc500ai_write_register(ViPipe, 0x36fd, 0x14); + sc500ai_write_register(ViPipe, 0x3904, 0x04); + sc500ai_write_register(ViPipe, 0x3908, 0x41); + sc500ai_write_register(ViPipe, 0x391d, 0x04); + sc500ai_write_register(ViPipe, 0x39c2, 0x30); + sc500ai_write_register(ViPipe, 0x3e01, 0xbb); + sc500ai_write_register(ViPipe, 0x3e02, 0x00); + sc500ai_write_register(ViPipe, 0x3e16, 0x00); + sc500ai_write_register(ViPipe, 0x3e17, 0x80); + sc500ai_write_register(ViPipe, 0x4500, 0x88); + sc500ai_write_register(ViPipe, 0x4509, 0x20); + sc500ai_write_register(ViPipe, 0x481b, 0x50); // hs-trail + sc500ai_write_register(ViPipe, 0x4837, 0x2a); + sc500ai_write_register(ViPipe, 0x5799, 0x00); + sc500ai_write_register(ViPipe, 0x59e0, 0x60); + sc500ai_write_register(ViPipe, 0x59e1, 0x08); + sc500ai_write_register(ViPipe, 0x59e2, 0x3f); + sc500ai_write_register(ViPipe, 0x59e3, 0x18); + sc500ai_write_register(ViPipe, 0x59e4, 0x18); + sc500ai_write_register(ViPipe, 0x59e5, 0x3f); + sc500ai_write_register(ViPipe, 0x59e7, 0x02); + sc500ai_write_register(ViPipe, 0x59e8, 0x38); + sc500ai_write_register(ViPipe, 0x59e9, 0x20); + sc500ai_write_register(ViPipe, 0x59ea, 0x0c); + sc500ai_write_register(ViPipe, 0x59ec, 0x08); + sc500ai_write_register(ViPipe, 0x59ed, 0x02); + sc500ai_write_register(ViPipe, 0x59ee, 0xa0); + sc500ai_write_register(ViPipe, 0x59ef, 0x08); + sc500ai_write_register(ViPipe, 0x59f4, 0x18); + sc500ai_write_register(ViPipe, 0x59f5, 0x10); + sc500ai_write_register(ViPipe, 0x59f6, 0x0c); + sc500ai_write_register(ViPipe, 0x59f9, 0x02); + sc500ai_write_register(ViPipe, 0x59fa, 0x18); + sc500ai_write_register(ViPipe, 0x59fb, 0x10); + sc500ai_write_register(ViPipe, 0x59fc, 0x0c); + sc500ai_write_register(ViPipe, 0x59ff, 0x02); + sc500ai_write_register(ViPipe, 0x36e9, 0x44); + sc500ai_write_register(ViPipe, 0x36f9, 0x44); + sc500ai_init_ex(ViPipe); + + sc500ai_default_reg_init(ViPipe); + + sc500ai_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC500AI 1440P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +static void sc500ai_wdr_1440p30_2to1_init(VI_PIPE ViPipe) +{ + sc500ai_write_register(ViPipe, 0x0103, 0x01); + sc500ai_write_register(ViPipe, 0x0100, 0x00); + sc500ai_write_register(ViPipe, 0x36e9, 0x80); + sc500ai_write_register(ViPipe, 0x36f9, 0x80); + sc500ai_write_register(ViPipe, 0x301f, 0x12); + sc500ai_write_register(ViPipe, 0x3106, 0x01); + sc500ai_write_register(ViPipe, 0x3200, 0x00); + sc500ai_write_register(ViPipe, 0x3201, 0xa0); + sc500ai_write_register(ViPipe, 0x3202, 0x00); + sc500ai_write_register(ViPipe, 0x3203, 0x5a); + sc500ai_write_register(ViPipe, 0x3204, 0x0a); + sc500ai_write_register(ViPipe, 0x3205, 0xa7); + sc500ai_write_register(ViPipe, 0x3206, 0x06); + sc500ai_write_register(ViPipe, 0x3207, 0x01); + sc500ai_write_register(ViPipe, 0x3208, 0x0a); + sc500ai_write_register(ViPipe, 0x3209, 0x00); + sc500ai_write_register(ViPipe, 0x320a, 0x05); + sc500ai_write_register(ViPipe, 0x320b, 0xa0); + sc500ai_write_register(ViPipe, 0x320c, 0x05); + sc500ai_write_register(ViPipe, 0x320d, 0xdc); + sc500ai_write_register(ViPipe, 0x320e, 0x0b); + sc500ai_write_register(ViPipe, 0x320f, 0xb8); + sc500ai_write_register(ViPipe, 0x3210, 0x00); + sc500ai_write_register(ViPipe, 0x3211, 0x04); + sc500ai_write_register(ViPipe, 0x3212, 0x00); + sc500ai_write_register(ViPipe, 0x3213, 0x04); + sc500ai_write_register(ViPipe, 0x3220, 0x53); + sc500ai_write_register(ViPipe, 0x3250, 0xff); + sc500ai_write_register(ViPipe, 0x3253, 0x0a); + sc500ai_write_register(ViPipe, 0x3301, 0x0b); + sc500ai_write_register(ViPipe, 0x3302, 0x20); + sc500ai_write_register(ViPipe, 0x3303, 0x10); + sc500ai_write_register(ViPipe, 0x3304, 0x60); + sc500ai_write_register(ViPipe, 0x3306, 0x40); + sc500ai_write_register(ViPipe, 0x3308, 0x18); + sc500ai_write_register(ViPipe, 0x3309, 0x80); + sc500ai_write_register(ViPipe, 0x330a, 0x01); + sc500ai_write_register(ViPipe, 0x330b, 0x04); + sc500ai_write_register(ViPipe, 0x330d, 0x28); + sc500ai_write_register(ViPipe, 0x330e, 0x30); + sc500ai_write_register(ViPipe, 0x330f, 0x02); + sc500ai_write_register(ViPipe, 0x3310, 0x02); + sc500ai_write_register(ViPipe, 0x331c, 0x08); + sc500ai_write_register(ViPipe, 0x331e, 0x51); + sc500ai_write_register(ViPipe, 0x331f, 0x71); + sc500ai_write_register(ViPipe, 0x3320, 0x11); + sc500ai_write_register(ViPipe, 0x3333, 0x10); + sc500ai_write_register(ViPipe, 0x334c, 0x10); + sc500ai_write_register(ViPipe, 0x3356, 0x11); + sc500ai_write_register(ViPipe, 0x3364, 0x17); + sc500ai_write_register(ViPipe, 0x336d, 0x03); + sc500ai_write_register(ViPipe, 0x3390, 0x08); + sc500ai_write_register(ViPipe, 0x3391, 0x18); + sc500ai_write_register(ViPipe, 0x3392, 0x38); + sc500ai_write_register(ViPipe, 0x3393, 0x0a); + sc500ai_write_register(ViPipe, 0x3394, 0x0a); + sc500ai_write_register(ViPipe, 0x3395, 0x12); + sc500ai_write_register(ViPipe, 0x3396, 0x08); + sc500ai_write_register(ViPipe, 0x3397, 0x18); + sc500ai_write_register(ViPipe, 0x3398, 0x38); + sc500ai_write_register(ViPipe, 0x3399, 0x0a); + sc500ai_write_register(ViPipe, 0x339a, 0x0a); + sc500ai_write_register(ViPipe, 0x339b, 0x0a); + sc500ai_write_register(ViPipe, 0x339c, 0x12); + sc500ai_write_register(ViPipe, 0x33ac, 0x10); + sc500ai_write_register(ViPipe, 0x33ae, 0x20); + sc500ai_write_register(ViPipe, 0x33af, 0x21); + sc500ai_write_register(ViPipe, 0x360f, 0x01); + sc500ai_write_register(ViPipe, 0x3621, 0xe8); + sc500ai_write_register(ViPipe, 0x3622, 0x06); + sc500ai_write_register(ViPipe, 0x3630, 0x82); + sc500ai_write_register(ViPipe, 0x3633, 0x33); + sc500ai_write_register(ViPipe, 0x3634, 0x64); + sc500ai_write_register(ViPipe, 0x3637, 0x50); + sc500ai_write_register(ViPipe, 0x363a, 0x1f); + sc500ai_write_register(ViPipe, 0x363c, 0x40); + sc500ai_write_register(ViPipe, 0x3651, 0x7d); + sc500ai_write_register(ViPipe, 0x3670, 0x0a); + sc500ai_write_register(ViPipe, 0x3671, 0x06); + sc500ai_write_register(ViPipe, 0x3672, 0x16); + sc500ai_write_register(ViPipe, 0x3673, 0x17); + sc500ai_write_register(ViPipe, 0x3674, 0x82); + sc500ai_write_register(ViPipe, 0x3675, 0x62); + sc500ai_write_register(ViPipe, 0x3676, 0x44); + sc500ai_write_register(ViPipe, 0x367a, 0x48); + sc500ai_write_register(ViPipe, 0x367b, 0x78); + sc500ai_write_register(ViPipe, 0x367c, 0x48); + sc500ai_write_register(ViPipe, 0x367d, 0x58); + sc500ai_write_register(ViPipe, 0x3690, 0x34); + sc500ai_write_register(ViPipe, 0x3691, 0x34); + sc500ai_write_register(ViPipe, 0x3692, 0x54); + sc500ai_write_register(ViPipe, 0x369c, 0x48); + sc500ai_write_register(ViPipe, 0x369d, 0x78); + sc500ai_write_register(ViPipe, 0x36ea, 0x31); + sc500ai_write_register(ViPipe, 0x36eb, 0x04); + sc500ai_write_register(ViPipe, 0x36ec, 0x0a); + sc500ai_write_register(ViPipe, 0x36ed, 0x24); + sc500ai_write_register(ViPipe, 0x36fa, 0x31); + sc500ai_write_register(ViPipe, 0x36fb, 0x04); + sc500ai_write_register(ViPipe, 0x36fc, 0x00); + sc500ai_write_register(ViPipe, 0x36fd, 0x26); + sc500ai_write_register(ViPipe, 0x3904, 0x04); + sc500ai_write_register(ViPipe, 0x3908, 0x41); + sc500ai_write_register(ViPipe, 0x391f, 0x10); + sc500ai_write_register(ViPipe, 0x39c2, 0x30); + sc500ai_write_register(ViPipe, 0x3e00, 0x01); + sc500ai_write_register(ViPipe, 0x3e01, 0x5e); + sc500ai_write_register(ViPipe, 0x3e02, 0x00); + sc500ai_write_register(ViPipe, 0x3e04, 0x15); + sc500ai_write_register(ViPipe, 0x3e05, 0xe0); + sc500ai_write_register(ViPipe, 0x3e23, 0x00); + sc500ai_write_register(ViPipe, 0x3e24, 0xb4); + sc500ai_write_register(ViPipe, 0x4500, 0x88); + sc500ai_write_register(ViPipe, 0x4509, 0x20); + sc500ai_write_register(ViPipe, 0x4800, 0x24); + sc500ai_write_register(ViPipe, 0x4837, 0x18); + sc500ai_write_register(ViPipe, 0x4853, 0xfd); + sc500ai_write_register(ViPipe, 0x481b, 0x50); // hs-trail + sc500ai_write_register(ViPipe, 0x36e9, 0x40); + sc500ai_write_register(ViPipe, 0x36f9, 0x40); + sc500ai_init_ex(ViPipe); + + sc500ai_default_reg_init(ViPipe); + + sc500ai_write_register(ViPipe, 0x0100, 0x01); + + delay_ms(50); + + printf("===SC500AI sensor 1440P30fps 10bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc501ai_2L/Makefile b/middleware/v2/component/isp/sensor/cv181x/sms_sc501ai_2L/Makefile new file mode 100644 index 000000000..1bb770b2a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc501ai_2L/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc501ai_2l.a +TARGET_SO = $(MW_LIB)/libsns_sc501ai_2l.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc501ai_2L/sc501ai_2L_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc501ai_2L/sc501ai_2L_cmos.c new file mode 100644 index 000000000..3a9471c9a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc501ai_2L/sc501ai_2L_cmos.c @@ -0,0 +1,1033 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc501ai_2L_cmos_ex.h" +#include "sc501ai_2L_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define SC501AI_2L_ID 500 +#define SENSOR_SC501AI_2L_WIDTH 2880 +#define SENSOR_SC501AI_2L_HEIGHT 1620 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC501AI_2L[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC501AI_2L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC501AI_2L[dev]) +#define SC501AI_2L_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC501AI_2L[dev] = pstCtx) +#define SC501AI_2L_SENSOR_RESET_CTX(dev) (g_pastSC501AI_2L[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC501AI_2L_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC501AI_2L_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC501AI_2L_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC501AI_2L_STATE_S g_astSC501AI_2L_State[VI_MAX_PIPE_NUM] = {{0} }; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****SC501AI_2L Lines Range*****/ +#define SC501AI_2L_FULL_LINES_MAX (0x7FFF) + +/*****SC501AI_2L Register Address*****/ +#define SC501AI_2L_SHS1_0_ADDR 0x3E00 +#define SC501AI_2L_SHS1_1_ADDR 0x3E01 +#define SC501AI_2L_SHS1_2_ADDR 0x3E02 +#define SC501AI_2L_AGAIN1_ADDR 0x3E08 +#define SC501AI_2L_DGAIN1_ADDR 0x3E06 +#define SC501AI_2L_VMAX_ADDR 0x320E +#define SC501AI_2L_TABLE_END 0xFFFF + +#define SC501AI_2L_RES_IS_1620P(w, h) ((w) <= 2880 && (h) <= 1620) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC501AI_2L_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 0.5; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astSC501AI_2L_mode[SC501AI_2L_MODE_1620P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC501AI_2L_mode[SC501AI_2L_MODE_1620P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = g_astSC501AI_2L_mode[SC501AI_2L_MODE_1620P30].stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = g_astSC501AI_2L_mode[SC501AI_2L_MODE_1620P30].stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astSC501AI_2L_mode[SC501AI_2L_MODE_1620P30].stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = g_astSC501AI_2L_mode[SC501AI_2L_MODE_1620P30].stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = 2 * (pstSnsState->u32FLStd - 5); + pstAeSnsDft->u32MinIntTime = 3; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + case WDR_MODE_2To1_LINE: + break; + } + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC501AI_2L_MODE_1620P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > SC501AI_2L_FULL_LINES_MAX) ? SC501AI_2L_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF); + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = 2 * (pstSnsState->u32FLStd - 5); + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + CVI_U32 u32TmpIntTime = u32IntTime[0]; + CVI_U32 maxExp = 2 * pstSnsState->au32FL[0] - 10; + + /* linear exposure reg range: + * min : 3 + * max : 2 * vts - 10 + * step : 1 + */ + u32TmpIntTime = (u32TmpIntTime > maxExp) ? maxExp : u32TmpIntTime; + if (u32TmpIntTime < 3) + u32TmpIntTime = 3; + u32IntTime[0] = u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = (u32TmpIntTime & 0xF) << 4; + + return CVI_SUCCESS; + +} + +struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +}; + +static struct gain_tbl_info_s AgainInfo[5] = { + { + .gainMax = 1536, + .idxBase = 0, + .regGain = 0x03, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 3080, + .idxBase = 33, + .regGain = 0x23, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 6161, + .idxBase = 97, + .regGain = 0x27, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 12321, + .idxBase = 161, + .regGain = 0x2F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, + { + .gainMax = 24644, + .idxBase = 225, + .regGain = 0x3F, + .regGainFineBase = 0x40, + .regGainFineStep = 1, + }, +}; + +static CVI_U32 Again_table[289] = { + 1024, 1040, 1055, 1072, 1088, 1103, 1120, 1135, 1152, 1168, 1183, 1200, 1216, 1231, + 1248, 1263, 1280, 1296, 1311, 1328, 1344, 1359, 1376, 1391, 1408, 1424, 1439, 1456, + 1472, 1487, 1504, 1519, 1536, 1552, 1576, 1600, 1625, 1649, 1673, 1697, 1722, 1746, + 1770, 1795, 1819, 1843, 1867, 1892, 1915, 1940, 1965, 1988, 2013, 2037, 2061, 2085, + 2110, 2135, 2158, 2183, 2207, 2231, 2255, 2280, 2304, 2328, 2353, 2376, 2401, 2425, + 2449, 2473, 2498, 2523, 2546, 2571, 2595, 2619, 2643, 2668, 2692, 2716, 2741, 2764, + 2789, 2813, 2837, 2862, 2886, 2911, 2934, 2959, 2983, 3007, 3032, 3056, 3080, 3104, + 3152, 3202, 3250, 3299, 3347, 3395, 3444, 3492, 3540, 3590, 3638, 3687, 3735, 3783, + 3832, 3880, 3929, 3978, 4026, 4075, 4123, 4171, 4220, 4269, 4317, 4366, 4414, 4463, + 4511, 4559, 4609, 4657, 4705, 4754, 4802, 4851, 4899, 4947, 4997, 5045, 5093, 5142, + 5190, 5239, 5287, 5336, 5385, 5433, 5481, 5530, 5578, 5627, 5676, 5724, 5773, 5821, + 5869, 5918, 5966, 6016, 6064, 6112, 6161, 6209, 6306, 6404, 6500, 6597, 6694, 6792, + 6888, 6985, 7083, 7180, 7276, 7373, 7471, 7568, 7664, 7761, 7859, 7956, 8052, 8150, + 8247, 8344, 8440, 8538, 8635, 8732, 8828, 8926, 9023, 9120, 9217, 9314, 9411, 9508, + 9605, 9702, 9799, 9896, 9993, 10090, 10187, 10285, 10381, 10478, 10575, 10673, 10769, + 10866, 10963, 11061, 11157, 11254, 11352, 11449, 11545, 11642, 11740, 11837, 11933, + 12030, 12128, 12225, 12321, 12419, 12613, 12807, 13001, 13195, 13389, 13583, 13777, + 13971, 14166, 14359, 14554, 14747, 14942, 15135, 15330, 15523, 15718, 15911, 16106, + 16300, 16494, 16688, 16882, 17076, 17270, 17464, 17658, 17852, 18046, 18240, 18435, + 18628, 18823, 19016, 19211, 19404, 19599, 19792, 19987, 20180, 20375, 20569, 20763, + 20957, 21151, 21345, 21539, 21733, 21927, 22121, 22316, 22509, 22704, 22897, 23092, + 23285, 23480, 23673, 23868, 24061, 24256, 24450, 24644, +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[288]) { + *pu32AgainLin = Again_table[288]; + *pu32AgainDb = 288; + return CVI_SUCCESS; + } + + for (i = 1; i < 289; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 dgain = *pu32DgainLin; + CVI_U32 dgainBase; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + + /* range check */ + if (dgain > g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max) { + *pu32DgainLin = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + *pu32DgainDb = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + return CVI_SUCCESS; + } + if (dgain < 1024) { + *pu32DgainLin = 1024; + *pu32DgainDb = 1024; + return CVI_SUCCESS; + } + /* find the base then use 1/128 as step */ + if (dgain < 2048) + dgainBase = 1024; + else if (dgain < 4096) + dgainBase = 2048; + else if (dgain < 8192) + dgainBase = 4096; + else if (dgain < 16384) + dgainBase = 8192; + else + dgainBase = 16384; + dgain = dgain * 128 / dgainBase; + *pu32DgainLin = dgainBase * dgain / 128; + *pu32DgainDb = *pu32DgainLin; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + CVI_U32 dgainReg; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + static bool bGainLogicChanged[VI_MAX_PIPE_NUM] = {true}; + CVI_U32 dgainBase; + + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + // control sensor DPC to fix high-gain noise + if (Again_table[u32Again] >= 30720 && bGainLogicChanged[ViPipe]) { + sc501ai_2l_write_register(ViPipe, 0x5799, 0x7); + bGainLogicChanged[ViPipe] = false; + } else if (Again_table[u32Again] <= 20480 && !bGainLogicChanged[ViPipe]) { + sc501ai_2l_write_register(ViPipe, 0x5799, 0x0); + bGainLogicChanged[ViPipe] = true; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + tbl_num = sizeof(AgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &AgainInfo[i]; + + if (u32Again >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_1_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + if (u32Dgain > g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max) + u32Dgain = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + if (u32Dgain < 1024) + u32Dgain = 1024; + /* find the base then use 1/128 as step */ + if (u32Dgain < 2048) { + dgainBase = 1024; + dgainReg = 0x0; + } else if (u32Dgain < 4096) { + dgainBase = 2048; + dgainReg = 0x1; + } else if (u32Dgain < 8192) { + dgainBase = 4096; + dgainReg = 0x3; + } else if (u32Dgain < 16384) { + dgainBase = 8192; + dgainReg = 0x7; + } else { + dgainBase = 16384; + dgainReg = 0xf; + } + u32Dgain = u32Dgain * 128 / dgainBase; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0_ADDR].u32Data = (dgainReg & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1_ADDR].u32Data = (u32Dgain & 0xFF); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0; + CVI_U32 u32ShortTimeMinLimit = 5; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32MaxSexp = 2 * g_astSC501AI_2L_State[ViPipe].u32Sexp_MAX - 14; + + (void) u16ManRatioEnable; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + /* short exposure reg range: + * min : 5 + * max : 2 * (max sexp - 7) + * step : 4 + * long exposure reg range: + * min : 5 + * max : 2 * (vts - max sexp - 9) + * step : 4 + */ + u32IntTimeMaxTmp = ((2 * pstSnsState->au32FL[0] - 16) * 0x40) / (au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32MaxSexp) ? u32MaxSexp : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp < u32ShortTimeMinLimit) ? u32ShortTimeMinLimit : u32IntTimeMaxTmp; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + syslog(LOG_DEBUG, "ViPipe = %d ratio = %d, (%d, %d)\n", ViPipe, au32Ratio[0], + u32IntTimeMaxTmp, u32ShortTimeMinLimit); + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const SC501AI_2L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC501AI_2L_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + + case WDR_MODE_2To1_LINE: + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunSC501AI_2L_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc501ai_2l_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc501ai_2l_addr_byte; + pstI2c_data[i].u32DataByteNum = sc501ai_2l_data_byte; + } + + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC501AI_2L_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC501AI_2L_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC501AI_2L_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC501AI_2L_AGAIN1_ADDR; + pstI2c_data[LINEAR_AGAIN_1_ADDR].u32RegAddr = SC501AI_2L_AGAIN1_ADDR + 1; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC501AI_2L_DGAIN1_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC501AI_2L_DGAIN1_ADDR + 1; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC501AI_2L_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC501AI_2L_VMAX_ADDR + 1; + + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC501AI_2L_RES_IS_1620P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC501AI_2L_MODE_1620P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC501AI_2L_MODE_S *pstMode = CVI_NULL; + + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC501AI_2L_MODE_1620P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC501AI_2L_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc501ai_2l_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC501AI_2L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc501ai_2l_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc501ai_2l_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc501ai_2l_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc501ai_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC501AI_2L_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + SC501AI_2L_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC501AI_2L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC501AI_2L_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = SC501AI_2L_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, SC501AI_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, SC501AI_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, SC501AI_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16SC501AI_2L_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC501AI_2L_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC501AI_2L_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc501ai_2l_standby, + .pfnRestart = sc501ai_2l_restart, + .pfnMirrorFlip = sc501ai_2l_mirror_flip, + .pfnWriteReg = sc501ai_2l_write_register, + .pfnReadReg = sc501ai_2l_read_register, + .pfnSetBusInfo = sc501ai_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc501ai_2l_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc501ai_2L/sc501ai_2L_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc501ai_2L/sc501ai_2L_cmos_ex.h new file mode 100644 index 000000000..57cb54b61 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc501ai_2L/sc501ai_2L_cmos_ex.h @@ -0,0 +1,85 @@ +#ifndef __SC501AI_2L_CMOS_EX_H_ +#define __SC501AI_2L_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc501ai_2l_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_2_ADDR, + LINEAR_AGAIN_0_ADDR, + LINEAR_AGAIN_1_ADDR, + LINEAR_DGAIN_0_ADDR, + LINEAR_DGAIN_1_ADDR, + LINEAR_VMAX_0_ADDR, + LINEAR_VMAX_1_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC501AI_2L_MODE_E { + SC501AI_2L_MODE_1620P30 = 0, + SC501AI_2L_MODE_LINEAR_NUM, + SC501AI_2L_MODE_NUM +} SC501AI_2L_MODE_E; + +typedef struct _SC501AI_2L_STATE_S { + CVI_U32 u32Sexp_MAX; /* (2*{16’h3e23,16’h3e24} – 'd10)/2 */ +} SC501AI_2L_STATE_S; + +typedef struct _SC501AI_2L_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + CVI_U16 u16SexpMaxReg; /* {16’h3e23,16’h3e24} */ + char name[64]; +} SC501AI_2L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC501AI_2L[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC501AI_2L_BusInfo[]; +extern CVI_U16 g_au16SC501AI_2L_GainMode[]; +extern CVI_U16 g_au16SC501AI_2L_L2SMode[]; +extern const CVI_U8 sc501ai_2l_i2c_addr; +extern const CVI_U32 sc501ai_2l_addr_byte; +extern const CVI_U32 sc501ai_2l_data_byte; +extern void sc501ai_2l_init(VI_PIPE ViPipe); +extern void sc501ai_2l_exit(VI_PIPE ViPipe); +extern void sc501ai_2l_standby(VI_PIPE ViPipe); +extern void sc501ai_2l_restart(VI_PIPE ViPipe); +extern int sc501ai_2l_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc501ai_2l_read_register(VI_PIPE ViPipe, int addr); +extern void sc501ai_2l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc501ai_2l_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC501AI_2L_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc501ai_2L/sc501ai_2L_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc501ai_2L/sc501ai_2L_cmos_param.h new file mode 100644 index 000000000..1527a6fcc --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc501ai_2L/sc501ai_2L_cmos_param.h @@ -0,0 +1,225 @@ +#ifndef __SC501AI_2L_CMOS_PARAM_H_ +#define __SC501AI_2L_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc501ai_2L_cmos_ex.h" + +static const SC501AI_2L_MODE_S g_astSC501AI_2L_mode[SC501AI_2L_MODE_NUM] = { + [SC501AI_2L_MODE_1620P30] = { + .name = "1620p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2880, + .u32Height = 1620, + }, + .stMaxSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.52, /* 1650 * 30 / 0x7FFF*/ + .u32HtsDef = 2560, /* NA */ + .u32VtsDef = 1650, + .stExp[0] = { + .u16Min = 3, + .u16Max = 3290, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 24644, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 32640, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.02792946062982082367, 3.36534714698791503906}, //B: slope, intercept + {0.02071751467883586884, 5.34583568572998046875}, //Gb: slope, intercept + {0.02110148966312408447, 5.02954530715942382813}, //Gr: slope, intercept + {0.02168512716889381409, 4.89776754379272460938}, //R: slope, intercept + }, + { //iso 200 + {0.03194080293178558350, 5.61192893981933593750}, //B: slope, intercept + {0.02428408525884151459, 7.94834280014038085938}, //Gb: slope, intercept + {0.02499442733824253082, 7.72430133819580078125}, //Gr: slope, intercept + {0.02584112435579299927, 7.20574426651000976563}, //R: slope, intercept + }, + { //iso 400 + {0.04612467437982559204, 6.88752269744873046875}, //B: slope, intercept + {0.03022909909486770630, 11.05101776123046875000}, //Gb: slope, intercept + {0.03175539523363113403, 10.60332489013671875000}, //Gr: slope, intercept + {0.03522306308150291443, 9.36425399780273437500}, //R: slope, intercept + }, + { //iso 800 + {0.06092500314116477966, 9.79670524597167968750}, //B: slope, intercept + {0.03984217345714569092, 15.30182266235351562500}, //Gb: slope, intercept + {0.04019560664892196655, 14.93132972717285156250}, //Gr: slope, intercept + {0.04470816254615783691, 13.26843166351318359375}, //R: slope, intercept + }, + { //iso 1600 + {0.08295634388923645020, 14.20334625244140625000}, //B: slope, intercept + {0.05075264349579811096, 20.99221038818359375000}, //Gb: slope, intercept + {0.05426201224327087402, 20.08068656921386718750}, //Gr: slope, intercept + {0.05945669487118721008, 19.02898788452148437500}, //R: slope, intercept + }, + { //iso 3200 + {0.09782519936561584473, 21.84967994689941406250}, //B: slope, intercept + {0.06690908223390579224, 26.53993988037109375000}, //Gb: slope, intercept + {0.06954573839902877808, 25.74129104614257812500}, //Gr: slope, intercept + {0.09061723947525024414, 22.98998260498046875000}, //R: slope, intercept + }, + { //iso 6400 + {0.14311420917510986328, 28.96467971801757812500}, //B: slope, intercept + {0.08148498833179473877, 37.93062591552734375000}, //Gb: slope, intercept + {0.08273542672395706177, 38.37096405029296875000}, //Gr: slope, intercept + {0.12093253433704376221, 33.31475067138671875000}, //R: slope, intercept + }, + { //iso 12800 + {0.17958122491836547852, 43.49506759643554687500}, //B: slope, intercept + {0.09839969873428344727, 55.43268966674804687500}, //Gb: slope, intercept + {0.10201884806156158447, 52.97607040405273437500}, //Gr: slope, intercept + {0.15302789211273193359, 47.54779434204101562500}, //R: slope, intercept + }, + { //iso 25600 + {0.25833165645599365234, 56.96470642089843750000}, //B: slope, intercept + {0.13260601460933685303, 74.69016265869140625000}, //Gb: slope, intercept + {0.14035490155220031738, 75.44366455078125000000}, //Gr: slope, intercept + {0.23465165495872497559, 60.52228164672851562500}, //R: slope, intercept + }, + { //iso 51200 + {0.37595292925834655762, 78.54853057861328125000}, //B: slope, intercept + {0.21475413441658020020, 102.12300872802734375000}, //Gb: slope, intercept + {0.20840260386466979980, 103.65763854980468750000}, //Gr: slope, intercept + {0.34428051114082336426, 87.83551025390625000000}, //R: slope, intercept + }, + { //iso 102400 + {0.51122575998306274414, 113.49224090576171875000}, //B: slope, intercept + {0.29245173931121826172, 154.26939392089843750000}, //Gb: slope, intercept + {0.31501635909080505371, 148.29017639160156250000}, //Gr: slope, intercept + {0.47034618258476257324, 124.06208038330078125000}, //R: slope, intercept + }, + { //iso 204800 + {0.67213481664657592773, 134.71751403808593750000}, //B: slope, intercept + {0.40368056297302246094, 189.80801391601562500000}, //Gb: slope, intercept + {0.43581819534301757813, 186.44682312011718750000}, //Gr: slope, intercept + {0.60127359628677368164, 160.66384887695312500000}, //R: slope, intercept + }, + { //iso 409600 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 819200 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {257, 260, 260, 260, 260, 261, 259, 258, /*8*/255, 248, 264, 300, 291, 310, 310, 311}, + {257, 260, 260, 260, 260, 261, 259, 257, /*8*/254, 247, 261, 296, 287, 309, 309, 306}, + {257, 260, 260, 260, 260, 261, 259, 257, /*8*/255, 248, 262, 298, 289, 308, 308, 308}, + {257, 260, 260, 260, 260, 261, 259, 258, /*8*/255, 247, 261, 301, 293, 310, 308, 314}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1095, 1105, 1102, 1108, 1108, 1108}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1104, 1101, 1108, 1108, 1107}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1104, 1102, 1107, 1107, 1107}, + {1093, 1093, 1093, 1093, 1093, 1094, 1093, 1093, + /*8*/1092, 1090, 1094, 1105, 1103, 1108, 1107, 1109}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc501ai_2l_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {1, 2, 0, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + .dphy = { + .enable = 1, + .hs_settle = 14, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC501AI_2L_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc501ai_2L/sc501ai_2L_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc501ai_2L/sc501ai_2L_sensor_ctl.c new file mode 100644 index 000000000..fc7a232cf --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc501ai_2L/sc501ai_2L_sensor_ctl.c @@ -0,0 +1,425 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc501ai_2L_cmos_ex.h" + +static void sc501ai_2l_linear_1620p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc501ai_2l_i2c_addr = 0x30; /* I2C Address of SC501AI_2L */ +const CVI_U32 sc501ai_2l_addr_byte = 2; +const CVI_U32 sc501ai_2l_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc501ai_2l_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC501AI_2L_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc501ai_2l_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc501ai_2l_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc501ai_2l_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc501ai_2l_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc501ai_2l_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc501ai_2l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc501ai_2l_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc501ai_2l_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc501ai_2l_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc501ai_2l_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc501ai_2l_addr_byte + sc501ai_2l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc501ai_2l_standby(VI_PIPE ViPipe) +{ + sc501ai_2l_write_register(ViPipe, 0x0100, 0x00); +} + +void sc501ai_2l_restart(VI_PIPE ViPipe) +{ + sc501ai_2l_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc501ai_2l_write_register(ViPipe, 0x0100, 0x01); +} + +void sc501ai_2l_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC501AI_2L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc501ai_2l_write_register(ViPipe, + g_pastSC501AI_2L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC501AI_2L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC501AI_2L_CHIP_ID_HI_ADDR 0x3107 +#define SC501AI_2L_CHIP_ID_LO_ADDR 0x3108 +#define SC501AI_2L_CHIP_ID 0xce1f + +void sc501ai_2l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x6; + break; + case ISP_SNS_FLIP: + val |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x66; + break; + default: + return; + } + + sc501ai_2l_write_register(ViPipe, 0x3221, val); +} + +static int sc501ai_2l_init_ex(VI_PIPE ViPipe) +{ + CVI_U32 debounce = 0; + int nVal, cnt = 0; + CVI_U16 tmp = 0, tmpPrev = 0; + + while (debounce++ < 5) { + nVal = sc501ai_2l_read_register(ViPipe, 0x3109); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "debounce read fail.\n"); + return nVal; + } + tmp = (nVal & 0xFF) << 8; + if (tmp != tmpPrev) + debounce = 0; + tmpPrev = tmp; + if (cnt++ > 20) { + CVI_TRACE_SNS(CVI_DBG_ERR, "debounce fail.\n"); + return nVal; + } + } + if (tmp == 1) { + sc501ai_2l_write_register(ViPipe, 0x336d, 0x23); + } else { + sc501ai_2l_write_register(ViPipe, 0x336d, 0x03); + } + + debounce = 0; + cnt = 0; + while (debounce++ < 5) { + nVal = sc501ai_2l_read_register(ViPipe, 0x3040); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "debounce read fail.\n"); + return nVal; + } + tmp = (nVal & 0xFF) << 8; + if (tmp != tmpPrev) + debounce = 0; + tmpPrev = tmp; + if (cnt++ > 20) { + CVI_TRACE_SNS(CVI_DBG_ERR, "debounce fail.\n"); + return nVal; + } + } + if (tmp == 0) { + sc501ai_2l_write_register(ViPipe, 0x363c, 0x42); + } else { + sc501ai_2l_write_register(ViPipe, 0x363c, 0x40); + } + + return CVI_SUCCESS; +} + +int sc501ai_2l_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + delay_ms(4); + if (sc501ai_2l_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc501ai_2l_read_register(ViPipe, SC501AI_2L_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc501ai_2l_read_register(ViPipe, SC501AI_2L_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != SC501AI_2L_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc501ai_2l_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + + bInit = g_pastSC501AI_2L[ViPipe]->bInit; + enWDRMode = g_pastSC501AI_2L[ViPipe]->enWDRMode; + + sc501ai_2l_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_2To1_LINE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n"); + } else { + sc501ai_2l_linear_1620p30_init(ViPipe); + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_2To1_LINE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n"); + } else { + sc501ai_2l_linear_1620p30_init(ViPipe); + } + } + g_pastSC501AI_2L[ViPipe]->bInit = CVI_TRUE; +} + +void sc501ai_2l_exit(VI_PIPE ViPipe) +{ + sc501ai_2l_i2c_exit(ViPipe); +} + +/* 1620P30 and 1620P25 */ +static void sc501ai_2l_linear_1620p30_init(VI_PIPE ViPipe) +{ + sc501ai_2l_write_register(ViPipe, 0x0103, 0x01); + sc501ai_2l_write_register(ViPipe, 0x0100, 0x00); + sc501ai_2l_write_register(ViPipe, 0x36e9, 0x80); + sc501ai_2l_write_register(ViPipe, 0x36f9, 0x80); + sc501ai_2l_write_register(ViPipe, 0x3018, 0x32); + sc501ai_2l_write_register(ViPipe, 0x3019, 0x0c); + sc501ai_2l_write_register(ViPipe, 0x301f, 0x0b); + sc501ai_2l_write_register(ViPipe, 0x3253, 0x0a); + sc501ai_2l_write_register(ViPipe, 0x3301, 0x0a); + sc501ai_2l_write_register(ViPipe, 0x3302, 0x18); + sc501ai_2l_write_register(ViPipe, 0x3303, 0x10); + sc501ai_2l_write_register(ViPipe, 0x3304, 0x60); + sc501ai_2l_write_register(ViPipe, 0x3306, 0x60); + sc501ai_2l_write_register(ViPipe, 0x3308, 0x10); + sc501ai_2l_write_register(ViPipe, 0x3309, 0x70); + sc501ai_2l_write_register(ViPipe, 0x330a, 0x00); + sc501ai_2l_write_register(ViPipe, 0x330b, 0xf0); + sc501ai_2l_write_register(ViPipe, 0x330d, 0x18); + sc501ai_2l_write_register(ViPipe, 0x330e, 0x20); + sc501ai_2l_write_register(ViPipe, 0x330f, 0x02); + sc501ai_2l_write_register(ViPipe, 0x3310, 0x02); + sc501ai_2l_write_register(ViPipe, 0x331c, 0x04); + sc501ai_2l_write_register(ViPipe, 0x331e, 0x51); + sc501ai_2l_write_register(ViPipe, 0x331f, 0x61); + sc501ai_2l_write_register(ViPipe, 0x3320, 0x09); + sc501ai_2l_write_register(ViPipe, 0x3333, 0x10); + sc501ai_2l_write_register(ViPipe, 0x334c, 0x08); + sc501ai_2l_write_register(ViPipe, 0x3356, 0x09); + sc501ai_2l_write_register(ViPipe, 0x3364, 0x17); + sc501ai_2l_write_register(ViPipe, 0x336d, 0x03); + sc501ai_2l_write_register(ViPipe, 0x3390, 0x08); + sc501ai_2l_write_register(ViPipe, 0x3391, 0x18); + sc501ai_2l_write_register(ViPipe, 0x3392, 0x38); + sc501ai_2l_write_register(ViPipe, 0x3393, 0x0a); + sc501ai_2l_write_register(ViPipe, 0x3394, 0x20); + sc501ai_2l_write_register(ViPipe, 0x3395, 0x20); + sc501ai_2l_write_register(ViPipe, 0x3396, 0x08); + sc501ai_2l_write_register(ViPipe, 0x3397, 0x18); + sc501ai_2l_write_register(ViPipe, 0x3398, 0x38); + sc501ai_2l_write_register(ViPipe, 0x3399, 0x0a); + sc501ai_2l_write_register(ViPipe, 0x339a, 0x20); + sc501ai_2l_write_register(ViPipe, 0x339b, 0x20); + sc501ai_2l_write_register(ViPipe, 0x339c, 0x20); + sc501ai_2l_write_register(ViPipe, 0x33ac, 0x10); + sc501ai_2l_write_register(ViPipe, 0x33ae, 0x10); + sc501ai_2l_write_register(ViPipe, 0x33af, 0x19); + sc501ai_2l_write_register(ViPipe, 0x360f, 0x01); + sc501ai_2l_write_register(ViPipe, 0x3622, 0x03); + sc501ai_2l_write_register(ViPipe, 0x363a, 0x1f); + sc501ai_2l_write_register(ViPipe, 0x363c, 0x40); + sc501ai_2l_write_register(ViPipe, 0x3651, 0x7d); + sc501ai_2l_write_register(ViPipe, 0x3670, 0x0a); + sc501ai_2l_write_register(ViPipe, 0x3671, 0x07); + sc501ai_2l_write_register(ViPipe, 0x3672, 0x17); + sc501ai_2l_write_register(ViPipe, 0x3673, 0x1e); + sc501ai_2l_write_register(ViPipe, 0x3674, 0x82); + sc501ai_2l_write_register(ViPipe, 0x3675, 0x64); + sc501ai_2l_write_register(ViPipe, 0x3676, 0x66); + sc501ai_2l_write_register(ViPipe, 0x367a, 0x48); + sc501ai_2l_write_register(ViPipe, 0x367b, 0x78); + sc501ai_2l_write_register(ViPipe, 0x367c, 0x58); + sc501ai_2l_write_register(ViPipe, 0x367d, 0x78); + sc501ai_2l_write_register(ViPipe, 0x3690, 0x34); + sc501ai_2l_write_register(ViPipe, 0x3691, 0x34); + sc501ai_2l_write_register(ViPipe, 0x3692, 0x54); + sc501ai_2l_write_register(ViPipe, 0x369c, 0x48); + sc501ai_2l_write_register(ViPipe, 0x369d, 0x78); + sc501ai_2l_write_register(ViPipe, 0x36ec, 0x0a); + sc501ai_2l_write_register(ViPipe, 0x3904, 0x04); + sc501ai_2l_write_register(ViPipe, 0x3908, 0x41); + sc501ai_2l_write_register(ViPipe, 0x391d, 0x04); + sc501ai_2l_write_register(ViPipe, 0x39c2, 0x30); + sc501ai_2l_write_register(ViPipe, 0x3e01, 0xcd); + sc501ai_2l_write_register(ViPipe, 0x3e02, 0xc0); + sc501ai_2l_write_register(ViPipe, 0x3e16, 0x00); + sc501ai_2l_write_register(ViPipe, 0x3e17, 0x80); + sc501ai_2l_write_register(ViPipe, 0x4500, 0x88); + sc501ai_2l_write_register(ViPipe, 0x4509, 0x20); + sc501ai_2l_write_register(ViPipe, 0x4837, 0x14); + sc501ai_2l_write_register(ViPipe, 0x5799, 0x00); + sc501ai_2l_write_register(ViPipe, 0x59e0, 0x60); + sc501ai_2l_write_register(ViPipe, 0x59e1, 0x08); + sc501ai_2l_write_register(ViPipe, 0x59e2, 0x3f); + sc501ai_2l_write_register(ViPipe, 0x59e3, 0x18); + sc501ai_2l_write_register(ViPipe, 0x59e4, 0x18); + sc501ai_2l_write_register(ViPipe, 0x59e5, 0x3f); + sc501ai_2l_write_register(ViPipe, 0x59e7, 0x02); + sc501ai_2l_write_register(ViPipe, 0x59e8, 0x38); + sc501ai_2l_write_register(ViPipe, 0x59e9, 0x20); + sc501ai_2l_write_register(ViPipe, 0x59ea, 0x0c); + sc501ai_2l_write_register(ViPipe, 0x59ec, 0x08); + sc501ai_2l_write_register(ViPipe, 0x59ed, 0x02); + sc501ai_2l_write_register(ViPipe, 0x59ee, 0xa0); + sc501ai_2l_write_register(ViPipe, 0x59ef, 0x08); + sc501ai_2l_write_register(ViPipe, 0x59f4, 0x18); + sc501ai_2l_write_register(ViPipe, 0x59f5, 0x10); + sc501ai_2l_write_register(ViPipe, 0x59f6, 0x0c); + sc501ai_2l_write_register(ViPipe, 0x59f9, 0x02); + sc501ai_2l_write_register(ViPipe, 0x59fa, 0x18); + sc501ai_2l_write_register(ViPipe, 0x59fb, 0x10); + sc501ai_2l_write_register(ViPipe, 0x59fc, 0x0c); + sc501ai_2l_write_register(ViPipe, 0x59ff, 0x02); + sc501ai_2l_write_register(ViPipe, 0x36e9, 0x1c); + sc501ai_2l_write_register(ViPipe, 0x36f9, 0x24); + sc501ai_2l_init_ex(ViPipe); + sc501ai_2l_default_reg_init(ViPipe); + + sc501ai_2l_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC501AI_2L 1620P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc531ai_2L/Makefile b/middleware/v2/component/isp/sensor/cv181x/sms_sc531ai_2L/Makefile new file mode 100644 index 000000000..ae828df60 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc531ai_2L/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_sc531ai_2l.a +TARGET_SO = $(MW_LIB)/libsns_sc531ai_2l.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc531ai_2L/sc531ai_2L_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc531ai_2L/sc531ai_2L_cmos.c new file mode 100644 index 000000000..2e003b166 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc531ai_2L/sc531ai_2L_cmos.c @@ -0,0 +1,981 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "sc531ai_2L_cmos_ex.h" +#include "sc531ai_2L_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define sc531AI_2L_ID 500 +#define SENSOR_sc531AI_2L_WIDTH 2880 +#define SENSOR_sc531AI_2L_HEIGHT 1620 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastsc531AI_2L[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define sc531AI_2L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastsc531AI_2L[dev]) +#define sc531AI_2L_SENSOR_SET_CTX(dev, pstCtx) (g_pastsc531AI_2L[dev] = pstCtx) +#define sc531AI_2L_SENSOR_RESET_CTX(dev) (g_pastsc531AI_2L[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunsc531AI_2L_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16sc531AI_2L_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16sc531AI_2L_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +sc531AI_2L_STATE_S g_astsc531AI_2L_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc531ai_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****sc531AI_2L Lines Range*****/ +#define sc531AI_2L_FULL_LINES_MAX (0x7FFF) + +/*****sc531AI_2L Register Address*****/ +#define sc531AI_2L_SHS1_0_ADDR 0x3E00 +#define sc531AI_2L_SHS1_1_ADDR 0x3E01 +#define sc531AI_2L_SHS1_2_ADDR 0x3E02 +#define sc531AI_2L_AGAIN_ADDR 0x3E09 +#define sc531AI_2L_DGAIN_ADDR 0x3E06 +#define sc531AI_2L_DGAIN_FINEADDR 0x3E07 +#define sc531AI_2L_FLIP_MIRROR_ADDR 0x3221 +#define sc531AI_2L_VMAX_ADDR 0x320E +#define sc531AI_2L_TABLE_END 0xFFFF + +#define sc531AI_2L_RES_IS_1620P(w, h) ((w) <= 2880 && (h) <= 1620) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = sc531AI_2L_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 0.5; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astsc531AI_2L_mode[sc531AI_2L_MODE_1620P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astsc531AI_2L_mode[sc531AI_2L_MODE_1620P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = g_astsc531AI_2L_mode[sc531AI_2L_MODE_1620P30].stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = g_astsc531AI_2L_mode[sc531AI_2L_MODE_1620P30].stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astsc531AI_2L_mode[sc531AI_2L_MODE_1620P30].stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = g_astsc531AI_2L_mode[sc531AI_2L_MODE_1620P30].stDgain[0].u32Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = 2 * (pstSnsState->u32FLStd - 5); + pstAeSnsDft->u32MinIntTime = 3; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + case WDR_MODE_2To1_LINE: + break; + } + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astsc531AI_2L_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astsc531AI_2L_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astsc531AI_2L_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case sc531AI_2L_MODE_1620P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > sc531AI_2L_FULL_LINES_MAX) ? sc531AI_2L_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF); + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = 2 * (pstSnsState->u32FLStd - 5); + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + CVI_U32 u32TmpIntTime = u32IntTime[0]; + CVI_U32 maxExp = 2 * pstSnsState->au32FL[0] - 10; + + /* linear exposure reg range: + * min : 3 + * max : 2 * vts - 10 + * step : 1 + */ + u32TmpIntTime = (u32TmpIntTime > maxExp) ? maxExp : u32TmpIntTime; + if (u32TmpIntTime < 3) + u32TmpIntTime = 3; + u32IntTime[0] = u32TmpIntTime; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = (u32TmpIntTime & 0xF) << 4; + + return CVI_SUCCESS; + +} + +static CVI_U32 Again_table[] = { + 1024, 2048, 2447, 4894, 9789, 19578, 39157, 78315 +}; + +static CVI_U32 AgainReg[] = { + 0x00, 0x01, 0x40, 0x48, 0x49, 0x4B, 0x4F, 0x5F +}; + +struct gain_tbl_info_s { + CVI_U16 gainMax; + CVI_U16 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +}; + +static struct gain_tbl_info_s DgainInfo[2] = { + { + .gainMax = 2016, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, +}; + +static CVI_U32 Dgain_table[64] = { + 1024, 1055, 1088, 1120, 1152, 1183, 1216, 1248, 1280, 1311, 1344, 1376, 1408, 1439, 1472, 1504, + 1536, 1567, 1600, 1632, 1664, 1695, 1728, 1760, 1792, 1823, 1856, 1888, 1920, 1951, 1984, 2016, + 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008, + 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, 3904, 3968, 4032, +}; + +static CVI_U32 Again_tableSize = sizeof(Again_table) / sizeof(CVI_U32); +static CVI_U32 Dgain_tableSize = sizeof(Dgain_table) / sizeof(CVI_U32); + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 i; + (void)ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= Again_table[Again_tableSize-1]) { + *pu32AgainLin = Again_table[Again_tableSize-1]; + *pu32AgainDb = AgainReg[Again_tableSize-1]; + return CVI_SUCCESS; + } + + for (i = 1; i < Again_tableSize; i++) { + if (*pu32AgainLin < Again_table[i]) { + *pu32AgainLin = Again_table[i - 1]; + *pu32AgainDb = AgainReg[i - 1]; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void)ViPipe; + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= Dgain_table[Dgain_tableSize - 1]) { + *pu32DgainLin = Dgain_table[Dgain_tableSize - 1]; + *pu32DgainDb = Dgain_tableSize - 1; + return CVI_SUCCESS; + } + + for (CVI_U32 i = 1; i < Dgain_tableSize; i++) { + if (*pu32DgainLin < Dgain_table[i]) { + *pu32DgainLin = Dgain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + + /* find Again register setting. */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_ADDR].u32Data = (u32Again & 0xFF); + + /* find Dgain register setting. */ + tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s); + for (i = tbl_num - 1; i >= 0; i--) { + info = &DgainInfo[i]; + if (u32Dgain >= info->idxBase) + break; + } + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_FINE_ADDR].u32Data = (u32Dgain & 0xFF); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0; + CVI_U32 u32ShortTimeMinLimit = 5; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32MaxSexp = 2 * g_astsc531AI_2L_State[ViPipe].u32Sexp_MAX - 14; + + (void) u16ManRatioEnable; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + /* short exposure reg range: + * min : 5 + * max : 2 * (max sexp - 7) + * step : 4 + * long exposure reg range: + * min : 5 + * max : 2 * (vts - max sexp - 9) + * step : 4 + */ + u32IntTimeMaxTmp = ((2 * pstSnsState->au32FL[0] - 16) * 0x40) / (au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32MaxSexp) ? u32MaxSexp : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp < u32ShortTimeMinLimit) ? u32ShortTimeMinLimit : u32IntTimeMaxTmp; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + syslog(LOG_DEBUG, "ViPipe = %d ratio = %d, (%d, %d)\n", ViPipe, au32Ratio[0], + u32IntTimeMaxTmp, u32ShortTimeMinLimit); + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const sc531AI_2L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astsc531AI_2L_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astsc531AI_2L_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + + case WDR_MODE_2To1_LINE: + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunsc531AI_2L_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = sc531ai_2l_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc531ai_2l_addr_byte; + pstI2c_data[i].u32DataByteNum = sc531ai_2l_data_byte; + } + + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = sc531AI_2L_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = sc531AI_2L_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = sc531AI_2L_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = sc531AI_2L_AGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_ADDR].u32RegAddr = sc531AI_2L_DGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_FINE_ADDR].u32RegAddr = sc531AI_2L_DGAIN_FINEADDR; + pstI2c_data[LINEAR_FLIP_MIRROR].u32RegAddr = sc531AI_2L_FLIP_MIRROR_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = sc531AI_2L_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = sc531AI_2L_VMAX_ADDR + 1; + + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = CVI_FALSE; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (sc531AI_2L_RES_IS_1620P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = sc531AI_2L_MODE_1620P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sc531ai_2l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U8 value = 0; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + if (pstSnsState->bInit == CVI_TRUE && g_aeSc531ai_MirrorFip[ViPipe] != eSnsMirrorFlip) { + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + value |= 0; + break; + case ISP_SNS_MIRROR: + value |= 0x6; + break; + case ISP_SNS_FLIP: + value |= 0x60; + break; + case ISP_SNS_MIRROR_FLIP: + value |= 0x66; + break; + default: + return; + } + + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u8DropFrmNum = 1; + g_aeSc531ai_MirrorFip[ViPipe] = eSnsMirrorFlip; + } + +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const sc531AI_2L_MODE_S *pstMode = CVI_NULL; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = sc531AI_2L_MODE_1620P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astsc531AI_2L_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc531ai_2l_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astsc531AI_2L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astsc531AI_2L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &sc531ai_2l_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = sc531ai_2l_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc531ai_2l_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 sc531ai_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunsc531AI_2L_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + sc531AI_2L_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + sc531AI_2L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + sc531AI_2L_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = sc531AI_2L_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, sc531AI_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, sc531AI_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, sc531AI_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16sc531AI_2L_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16sc531AI_2L_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC531AI_2L_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc531ai_2l_standby, + .pfnRestart = sc531ai_2l_restart, + .pfnMirrorFlip = sc531ai_2l_mirror_flip, + .pfnWriteReg = sc531ai_2l_write_register, + .pfnReadReg = sc531ai_2l_read_register, + .pfnSetBusInfo = sc531ai_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sc531ai_2l_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc531ai_2L/sc531ai_2L_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc531ai_2L/sc531ai_2L_cmos_ex.h new file mode 100644 index 000000000..05c948c72 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc531ai_2L/sc531ai_2L_cmos_ex.h @@ -0,0 +1,84 @@ +#ifndef __SC531AI_2L_CMOS_EX_H_ +#define __SC531AI_2L_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum sc531ai_2l_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_2_ADDR, + LINEAR_AGAIN_ADDR, + LINEAR_DGAIN_ADDR, + LINEAR_DGAIN_FINE_ADDR, + LINEAR_FLIP_MIRROR, + LINEAR_VMAX_H_ADDR, + LINEAR_VMAX_L_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _sc531AI_2L_MODE_E { + sc531AI_2L_MODE_1620P30 = 0, + sc531AI_2L_MODE_LINEAR_NUM, + sc531AI_2L_MODE_NUM +} sc531AI_2L_MODE_E; + +typedef struct _sc531AI_2L_STATE_S { + CVI_U32 u32Sexp_MAX; +} sc531AI_2L_STATE_S; + +typedef struct _sc531AI_2L_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + CVI_U16 u16SexpMaxReg; + char name[64]; +} sc531AI_2L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastsc531AI_2L[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunsc531AI_2L_BusInfo[]; +extern CVI_U16 g_au16sc531AI_2L_GainMode[]; +extern CVI_U16 g_au16sc531AI_2L_L2SMode[]; +extern const CVI_U8 sc531ai_2l_i2c_addr; +extern const CVI_U32 sc531ai_2l_addr_byte; +extern const CVI_U32 sc531ai_2l_data_byte; +extern void sc531ai_2l_init(VI_PIPE ViPipe); +extern void sc531ai_2l_exit(VI_PIPE ViPipe); +extern void sc531ai_2l_standby(VI_PIPE ViPipe); +extern void sc531ai_2l_restart(VI_PIPE ViPipe); +extern int sc531ai_2l_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc531ai_2l_read_register(VI_PIPE ViPipe, int addr); +extern int sc531ai_2l_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __sc531AI_2L_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc531ai_2L/sc531ai_2L_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sms_sc531ai_2L/sc531ai_2L_cmos_param.h new file mode 100644 index 000000000..ec0de0eb0 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc531ai_2L/sc531ai_2L_cmos_param.h @@ -0,0 +1,225 @@ +#ifndef __SC531AI_2L_CMOS_PARAM_H_ +#define __SC531AI_2L_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc531ai_2L_cmos_ex.h" + +static const sc531AI_2L_MODE_S g_astsc531AI_2L_mode[sc531AI_2L_MODE_NUM] = { + [sc531AI_2L_MODE_1620P30] = { + .name = "1620p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2880, + .u32Height = 1620, + }, + .stMaxSize = { + .u32Width = 2880, + .u32Height = 1620, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.52, /* 1650 * 30 / 0x7FFF*/ + .u32HtsDef = 2560, /* NA */ + .u32VtsDef = 1650, + .stExp[0] = { + .u16Min = 3, + .u16Max = 3290,/* 2*vts-10 */ + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 78315, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 4032, + .u32Def = 1024, + .u32Step = 1, + }, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.02792946062982082367, 3.36534714698791503906}, //B: slope, intercept + {0.02071751467883586884, 5.34583568572998046875}, //Gb: slope, intercept + {0.02110148966312408447, 5.02954530715942382813}, //Gr: slope, intercept + {0.02168512716889381409, 4.89776754379272460938}, //R: slope, intercept + }, + { //iso 200 + {0.03194080293178558350, 5.61192893981933593750}, //B: slope, intercept + {0.02428408525884151459, 7.94834280014038085938}, //Gb: slope, intercept + {0.02499442733824253082, 7.72430133819580078125}, //Gr: slope, intercept + {0.02584112435579299927, 7.20574426651000976563}, //R: slope, intercept + }, + { //iso 400 + {0.04612467437982559204, 6.88752269744873046875}, //B: slope, intercept + {0.03022909909486770630, 11.05101776123046875000}, //Gb: slope, intercept + {0.03175539523363113403, 10.60332489013671875000}, //Gr: slope, intercept + {0.03522306308150291443, 9.36425399780273437500}, //R: slope, intercept + }, + { //iso 800 + {0.06092500314116477966, 9.79670524597167968750}, //B: slope, intercept + {0.03984217345714569092, 15.30182266235351562500}, //Gb: slope, intercept + {0.04019560664892196655, 14.93132972717285156250}, //Gr: slope, intercept + {0.04470816254615783691, 13.26843166351318359375}, //R: slope, intercept + }, + { //iso 1600 + {0.08295634388923645020, 14.20334625244140625000}, //B: slope, intercept + {0.05075264349579811096, 20.99221038818359375000}, //Gb: slope, intercept + {0.05426201224327087402, 20.08068656921386718750}, //Gr: slope, intercept + {0.05945669487118721008, 19.02898788452148437500}, //R: slope, intercept + }, + { //iso 3200 + {0.09782519936561584473, 21.84967994689941406250}, //B: slope, intercept + {0.06690908223390579224, 26.53993988037109375000}, //Gb: slope, intercept + {0.06954573839902877808, 25.74129104614257812500}, //Gr: slope, intercept + {0.09061723947525024414, 22.98998260498046875000}, //R: slope, intercept + }, + { //iso 6400 + {0.14311420917510986328, 28.96467971801757812500}, //B: slope, intercept + {0.08148498833179473877, 37.93062591552734375000}, //Gb: slope, intercept + {0.08273542672395706177, 38.37096405029296875000}, //Gr: slope, intercept + {0.12093253433704376221, 33.31475067138671875000}, //R: slope, intercept + }, + { //iso 12800 + {0.17958122491836547852, 43.49506759643554687500}, //B: slope, intercept + {0.09839969873428344727, 55.43268966674804687500}, //Gb: slope, intercept + {0.10201884806156158447, 52.97607040405273437500}, //Gr: slope, intercept + {0.15302789211273193359, 47.54779434204101562500}, //R: slope, intercept + }, + { //iso 25600 + {0.25833165645599365234, 56.96470642089843750000}, //B: slope, intercept + {0.13260601460933685303, 74.69016265869140625000}, //Gb: slope, intercept + {0.14035490155220031738, 75.44366455078125000000}, //Gr: slope, intercept + {0.23465165495872497559, 60.52228164672851562500}, //R: slope, intercept + }, + { //iso 51200 + {0.37595292925834655762, 78.54853057861328125000}, //B: slope, intercept + {0.21475413441658020020, 102.12300872802734375000}, //Gb: slope, intercept + {0.20840260386466979980, 103.65763854980468750000}, //Gr: slope, intercept + {0.34428051114082336426, 87.83551025390625000000}, //R: slope, intercept + }, + { //iso 102400 + {0.51122575998306274414, 113.49224090576171875000}, //B: slope, intercept + {0.29245173931121826172, 154.26939392089843750000}, //Gb: slope, intercept + {0.31501635909080505371, 148.29017639160156250000}, //Gr: slope, intercept + {0.47034618258476257324, 124.06208038330078125000}, //R: slope, intercept + }, + { //iso 204800 + {0.67213481664657592773, 134.71751403808593750000}, //B: slope, intercept + {0.40368056297302246094, 189.80801391601562500000}, //Gb: slope, intercept + {0.43581819534301757813, 186.44682312011718750000}, //Gr: slope, intercept + {0.60127359628677368164, 160.66384887695312500000}, //R: slope, intercept + }, + { //iso 409600 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 819200 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.81907004117965698242, 103.53753662109375000000}, //B: slope, intercept + {0.56758689880371093750, 134.64016723632812500000}, //Gb: slope, intercept + {0.60227775573730468750, 125.39395904541015625000}, //Gr: slope, intercept + {0.76318585872650146484, 111.18676757812500000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {260, 260, 260, 260, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093}, +#endif + }, + }, +}; + +struct combo_dev_attr_s sc531ai_2l_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {1, 2, 0, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + .dphy = { + .enable = 1, + .hs_settle = 14, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __sc531AI_2L_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sms_sc531ai_2L/sc531ai_2L_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sms_sc531ai_2L/sc531ai_2L_sensor_ctl.c new file mode 100644 index 000000000..d005dc750 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sms_sc531ai_2L/sc531ai_2L_sensor_ctl.c @@ -0,0 +1,377 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "sc531ai_2L_cmos_ex.h" + +static void sc531ai_2l_linear_1620p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc531ai_2l_i2c_addr = 0x30; /* I2C Address of sc531AI_2L */ +const CVI_U32 sc531ai_2l_addr_byte = 2; +const CVI_U32 sc531ai_2l_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc531ai_2l_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunsc531AI_2L_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc531ai_2l_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int sc531ai_2l_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int sc531ai_2l_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (sc531ai_2l_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc531ai_2l_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, sc531ai_2l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc531ai_2l_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc531ai_2l_write_register(VI_PIPE ViPipe, int addr, int data) +{ + int idx = 0; + int ret; + char buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (sc531ai_2l_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc531ai_2l_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc531ai_2l_addr_byte + sc531ai_2l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void sc531ai_2l_standby(VI_PIPE ViPipe) +{ + sc531ai_2l_write_register(ViPipe, 0x0100, 0x00); +} + +void sc531ai_2l_restart(VI_PIPE ViPipe) +{ + sc531ai_2l_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc531ai_2l_write_register(ViPipe, 0x0100, 0x01); +} + +void sc531ai_2l_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastsc531AI_2L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc531ai_2l_write_register(ViPipe, + g_pastsc531AI_2L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastsc531AI_2L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define sc531AI_2L_CHIP_ID_HI_ADDR 0x3107 +#define sc531AI_2L_CHIP_ID_LO_ADDR 0x3108 +#define sc531AI_2L_CHIP_ID 0x9e39 + +int sc531ai_2l_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc531ai_2l_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc531ai_2l_read_register(ViPipe, sc531AI_2L_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = sc531ai_2l_read_register(ViPipe, sc531AI_2L_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != sc531AI_2L_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc531ai_2l_init(VI_PIPE ViPipe) +{ + sc531ai_2l_i2c_init(ViPipe); + + sc531ai_2l_linear_1620p30_init(ViPipe); + + g_pastsc531AI_2L[ViPipe]->bInit = CVI_TRUE; +} + +void sc531ai_2l_exit(VI_PIPE ViPipe) +{ + sc531ai_2l_i2c_exit(ViPipe); +} + +/* 1620P30 */ +static void sc531ai_2l_linear_1620p30_init(VI_PIPE ViPipe) +{ + sc531ai_2l_write_register(ViPipe, 0x0103, 0x01); + sc531ai_2l_write_register(ViPipe, 0x0100, 0x00); + sc531ai_2l_write_register(ViPipe, 0x36e9, 0x80); + sc531ai_2l_write_register(ViPipe, 0x37f9, 0x80); + sc531ai_2l_write_register(ViPipe, 0x3018, 0x32); + sc531ai_2l_write_register(ViPipe, 0x3019, 0x0c); + sc531ai_2l_write_register(ViPipe, 0x301f, 0x69); + sc531ai_2l_write_register(ViPipe, 0x3250, 0x40); + sc531ai_2l_write_register(ViPipe, 0x3251, 0x98); + sc531ai_2l_write_register(ViPipe, 0x3253, 0x0c); + sc531ai_2l_write_register(ViPipe, 0x325f, 0x20); + sc531ai_2l_write_register(ViPipe, 0x3301, 0x08); + sc531ai_2l_write_register(ViPipe, 0x3304, 0x50); + sc531ai_2l_write_register(ViPipe, 0x3306, 0x88); + sc531ai_2l_write_register(ViPipe, 0x3308, 0x14); + sc531ai_2l_write_register(ViPipe, 0x3309, 0x70); + sc531ai_2l_write_register(ViPipe, 0x330a, 0x00); + sc531ai_2l_write_register(ViPipe, 0x330b, 0xf8); + sc531ai_2l_write_register(ViPipe, 0x330d, 0x10); + sc531ai_2l_write_register(ViPipe, 0x330e, 0x42); + sc531ai_2l_write_register(ViPipe, 0x331e, 0x41); + sc531ai_2l_write_register(ViPipe, 0x331f, 0x61); + sc531ai_2l_write_register(ViPipe, 0x3333, 0x10); + sc531ai_2l_write_register(ViPipe, 0x335d, 0x60); + sc531ai_2l_write_register(ViPipe, 0x335e, 0x06); + sc531ai_2l_write_register(ViPipe, 0x335f, 0x08); + sc531ai_2l_write_register(ViPipe, 0x3364, 0x56); + sc531ai_2l_write_register(ViPipe, 0x3366, 0x01); + sc531ai_2l_write_register(ViPipe, 0x337c, 0x02); + sc531ai_2l_write_register(ViPipe, 0x337d, 0x0a); + sc531ai_2l_write_register(ViPipe, 0x3390, 0x01); + sc531ai_2l_write_register(ViPipe, 0x3391, 0x03); + sc531ai_2l_write_register(ViPipe, 0x3392, 0x07); + sc531ai_2l_write_register(ViPipe, 0x3393, 0x08); + sc531ai_2l_write_register(ViPipe, 0x3394, 0x08); + sc531ai_2l_write_register(ViPipe, 0x3395, 0x08); + sc531ai_2l_write_register(ViPipe, 0x3396, 0x40); + sc531ai_2l_write_register(ViPipe, 0x3397, 0x48); + sc531ai_2l_write_register(ViPipe, 0x3398, 0x4b); + sc531ai_2l_write_register(ViPipe, 0x3399, 0x08); + sc531ai_2l_write_register(ViPipe, 0x339a, 0x08); + sc531ai_2l_write_register(ViPipe, 0x339b, 0x08); + sc531ai_2l_write_register(ViPipe, 0x339c, 0x1d); + sc531ai_2l_write_register(ViPipe, 0x33a2, 0x04); + sc531ai_2l_write_register(ViPipe, 0x33ae, 0x30); + sc531ai_2l_write_register(ViPipe, 0x33af, 0x50); + sc531ai_2l_write_register(ViPipe, 0x33b1, 0x80); + sc531ai_2l_write_register(ViPipe, 0x33b2, 0x48); + sc531ai_2l_write_register(ViPipe, 0x33b3, 0x30); + sc531ai_2l_write_register(ViPipe, 0x349f, 0x02); + sc531ai_2l_write_register(ViPipe, 0x34a6, 0x48); + sc531ai_2l_write_register(ViPipe, 0x34a7, 0x4b); + sc531ai_2l_write_register(ViPipe, 0x34a8, 0x30); + sc531ai_2l_write_register(ViPipe, 0x34a9, 0x18); + sc531ai_2l_write_register(ViPipe, 0x34f8, 0x5f); + sc531ai_2l_write_register(ViPipe, 0x34f9, 0x08); + sc531ai_2l_write_register(ViPipe, 0x3632, 0x48); + sc531ai_2l_write_register(ViPipe, 0x3633, 0x32); + sc531ai_2l_write_register(ViPipe, 0x3637, 0x27); + sc531ai_2l_write_register(ViPipe, 0x3638, 0xc1); + sc531ai_2l_write_register(ViPipe, 0x363b, 0x20); + sc531ai_2l_write_register(ViPipe, 0x363d, 0x02); + sc531ai_2l_write_register(ViPipe, 0x3670, 0x09); + sc531ai_2l_write_register(ViPipe, 0x3674, 0x8b); + sc531ai_2l_write_register(ViPipe, 0x3675, 0xc6); + sc531ai_2l_write_register(ViPipe, 0x3676, 0x8b); + sc531ai_2l_write_register(ViPipe, 0x367c, 0x40); + sc531ai_2l_write_register(ViPipe, 0x367d, 0x48); + sc531ai_2l_write_register(ViPipe, 0x3690, 0x32); + sc531ai_2l_write_register(ViPipe, 0x3691, 0x43); + sc531ai_2l_write_register(ViPipe, 0x3692, 0x33); + sc531ai_2l_write_register(ViPipe, 0x3693, 0x40); + sc531ai_2l_write_register(ViPipe, 0x3694, 0x4b); + sc531ai_2l_write_register(ViPipe, 0x3698, 0x85); + sc531ai_2l_write_register(ViPipe, 0x3699, 0x8f); + sc531ai_2l_write_register(ViPipe, 0x369a, 0xa0); + sc531ai_2l_write_register(ViPipe, 0x369b, 0xc3); + sc531ai_2l_write_register(ViPipe, 0x36a2, 0x49); + sc531ai_2l_write_register(ViPipe, 0x36a3, 0x4b); + sc531ai_2l_write_register(ViPipe, 0x36a4, 0x4f); + sc531ai_2l_write_register(ViPipe, 0x36d0, 0x01); + sc531ai_2l_write_register(ViPipe, 0x36ea, 0x0b); + sc531ai_2l_write_register(ViPipe, 0x36eb, 0x04); + sc531ai_2l_write_register(ViPipe, 0x36ec, 0x03); + sc531ai_2l_write_register(ViPipe, 0x36ed, 0x14); + sc531ai_2l_write_register(ViPipe, 0x370f, 0x01); + sc531ai_2l_write_register(ViPipe, 0x3722, 0x00); + sc531ai_2l_write_register(ViPipe, 0x3728, 0x10); + sc531ai_2l_write_register(ViPipe, 0x37b0, 0x03); + sc531ai_2l_write_register(ViPipe, 0x37b1, 0x03); + sc531ai_2l_write_register(ViPipe, 0x37b2, 0x83); + sc531ai_2l_write_register(ViPipe, 0x37b3, 0x48); + sc531ai_2l_write_register(ViPipe, 0x37b4, 0x49); + sc531ai_2l_write_register(ViPipe, 0x37fa, 0x0b); + sc531ai_2l_write_register(ViPipe, 0x37fb, 0x24); + sc531ai_2l_write_register(ViPipe, 0x37fc, 0x01); + sc531ai_2l_write_register(ViPipe, 0x37fd, 0x14); + sc531ai_2l_write_register(ViPipe, 0x3901, 0x00); + sc531ai_2l_write_register(ViPipe, 0x3902, 0xc5); + sc531ai_2l_write_register(ViPipe, 0x3904, 0x08); + sc531ai_2l_write_register(ViPipe, 0x3905, 0x8c); + sc531ai_2l_write_register(ViPipe, 0x3909, 0x00); + sc531ai_2l_write_register(ViPipe, 0x391d, 0x04); + sc531ai_2l_write_register(ViPipe, 0x391f, 0x44); + sc531ai_2l_write_register(ViPipe, 0x3926, 0x21); + sc531ai_2l_write_register(ViPipe, 0x3929, 0x18); + sc531ai_2l_write_register(ViPipe, 0x3933, 0x82); + sc531ai_2l_write_register(ViPipe, 0x3934, 0x0a); + sc531ai_2l_write_register(ViPipe, 0x3937, 0x5f); + sc531ai_2l_write_register(ViPipe, 0x3939, 0x00); + sc531ai_2l_write_register(ViPipe, 0x393a, 0x00); + sc531ai_2l_write_register(ViPipe, 0x39dc, 0x02); + sc531ai_2l_write_register(ViPipe, 0x3e01, 0xcd); + sc531ai_2l_write_register(ViPipe, 0x3e02, 0xa0); + sc531ai_2l_write_register(ViPipe, 0x440e, 0x02); + sc531ai_2l_write_register(ViPipe, 0x4509, 0x20); + sc531ai_2l_write_register(ViPipe, 0x4837, 0x14); + sc531ai_2l_write_register(ViPipe, 0x5010, 0x10); + sc531ai_2l_write_register(ViPipe, 0x5780, 0x66); + sc531ai_2l_write_register(ViPipe, 0x578d, 0x40); + sc531ai_2l_write_register(ViPipe, 0x5799, 0x06); + sc531ai_2l_write_register(ViPipe, 0x57ad, 0x00); + sc531ai_2l_write_register(ViPipe, 0x5ae0, 0xfe); + sc531ai_2l_write_register(ViPipe, 0x5ae1, 0x40); + sc531ai_2l_write_register(ViPipe, 0x5ae2, 0x30); + sc531ai_2l_write_register(ViPipe, 0x5ae3, 0x2a); + sc531ai_2l_write_register(ViPipe, 0x5ae4, 0x24); + sc531ai_2l_write_register(ViPipe, 0x5ae5, 0x30); + sc531ai_2l_write_register(ViPipe, 0x5ae6, 0x2a); + sc531ai_2l_write_register(ViPipe, 0x5ae7, 0x24); + sc531ai_2l_write_register(ViPipe, 0x5ae8, 0x3c); + sc531ai_2l_write_register(ViPipe, 0x5ae9, 0x30); + sc531ai_2l_write_register(ViPipe, 0x5aea, 0x28); + sc531ai_2l_write_register(ViPipe, 0x5aeb, 0x3c); + sc531ai_2l_write_register(ViPipe, 0x5aec, 0x30); + sc531ai_2l_write_register(ViPipe, 0x5aed, 0x28); + sc531ai_2l_write_register(ViPipe, 0x5aee, 0xfe); + sc531ai_2l_write_register(ViPipe, 0x5aef, 0x40); + sc531ai_2l_write_register(ViPipe, 0x5af4, 0x30); + sc531ai_2l_write_register(ViPipe, 0x5af5, 0x2a); + sc531ai_2l_write_register(ViPipe, 0x5af6, 0x24); + sc531ai_2l_write_register(ViPipe, 0x5af7, 0x30); + sc531ai_2l_write_register(ViPipe, 0x5af8, 0x2a); + sc531ai_2l_write_register(ViPipe, 0x5af9, 0x24); + sc531ai_2l_write_register(ViPipe, 0x5afa, 0x3c); + sc531ai_2l_write_register(ViPipe, 0x5afb, 0x30); + sc531ai_2l_write_register(ViPipe, 0x5afc, 0x28); + sc531ai_2l_write_register(ViPipe, 0x5afd, 0x3c); + sc531ai_2l_write_register(ViPipe, 0x5afe, 0x30); + sc531ai_2l_write_register(ViPipe, 0x5aff, 0x28); + sc531ai_2l_write_register(ViPipe, 0x36e9, 0x44); + sc531ai_2l_write_register(ViPipe, 0x37f9, 0x44); + + sc531ai_2l_default_reg_init(ViPipe); + + sc531ai_2l_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===sc531AI_2L 1620P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_f23/Makefile b/middleware/v2/component/isp/sensor/cv181x/soi_f23/Makefile new file mode 100644 index 000000000..9a364ba1a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_f23/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_f23.a +TARGET_SO = $(MW_LIB)/libsns_f23.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_f23/f23_cmos.c b/middleware/v2/component/isp/sensor/cv181x/soi_f23/f23_cmos.c new file mode 100644 index 000000000..9f432a4b3 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_f23/f23_cmos.c @@ -0,0 +1,1124 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "f23_cmos_ex.h" +#include "f23_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define F23_ID 35 +#define SENSOR_F23_WIDTH 1920 +#define SENSOR_F23_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastF23[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define F23_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastF23[dev]) +#define F23_SENSOR_SET_CTX(dev, pstCtx) (g_pastF23[dev] = pstCtx) +#define F23_SENSOR_RESET_CTX(dev) (g_pastF23[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunF23_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16F23_GainMode[VI_MAX_PIPE_NUM] = {0}; + +F23_STATE_S g_astF23_State[VI_MAX_PIPE_NUM] = {{0} }; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****F23 Lines Range*****/ +#define F23_FULL_LINES_MAX (0xFFFF) +#define F23_FULL_LINES_MAX_2TO1_WDR (0xFFFF) + +/*****F23 Register Address*****/ +#define F23_GLAT_ADDR 0x1F +#define F23_GRP_ADDR 0xC0 +#define F23_SHS1_ADDR 0x01 +#define F23_SHS2_ADDR 0x05 +#define F23_GAIN_ADDR 0x00 +#define F23_DGAIN_ADDR 0x0D +#define F23_VMAX_ADDR 0x22 +#define F23_TABLE_END 0xff + +#define F23_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = F23_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stDgainAccu.f32Accuracy = 6; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astF23_mode[F23_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astF23_mode[F23_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 15872; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 4096; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 5; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astF23_mode[F23_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astF23_mode[F23_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstAeSnsDft->u32MinIntTime = 1; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 15872; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 4096; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 5; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astF23_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astF23_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astF23_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case F23_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > F23_FULL_LINES_MAX_2TO1_WDR) ? F23_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case F23_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > F23_FULL_LINES_MAX) ? F23_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + g_astF23_State[ViPipe].u32Sexp_MAX = u32VMAX - + g_astF23_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height * 2; + /* Sexp = 1,3,5,7... */ + if (g_astF23_State[ViPipe].u32Sexp_MAX < 2) { + g_astF23_State[ViPipe].u32Sexp_MAX = 1; + } else { + g_astF23_State[ViPipe].u32Sexp_MAX = (g_astF23_State[ViPipe].u32Sexp_MAX & (~0x1)) - 1; + syslog(LOG_DEBUG, "VMAX %d, MAX_SEXP %d\n", u32VMAX, g_astF23_State[ViPipe].u32Sexp_MAX); + } + } + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_DATA].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_DATA].u32Data = ((u32VMAX & 0xFF00) >> 8); + } else { + pstSnsRegsInfo->astI2cData[WDR2_VMAX_0_DATA].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_VMAX_1_DATA].u32Data = ((u32VMAX & 0xFF00) >> 8); + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_cif_wdr(VI_PIPE ViPipe, ISP_SNS_CIF_INFO_S *pstCifCfg) +{ + const F23_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astF23_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstCifCfg->wdr_manual.manual_en = 0; + return CVI_SUCCESS; + } + + pstCifCfg->wdr_manual.devno = f23_rx_attr.devno; + pstCifCfg->wdr_manual.manual_en = 1; + pstCifCfg->wdr_manual.l2s_distance = g_astF23_State[ViPipe].u8SexpReg; + pstCifCfg->wdr_manual.lsef_length = pstMode->astImg[0].stSnsSize.u32Height; + pstCifCfg->wdr_manual.discard_padding_lines = 0; + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + CVI_U8 u8SexpReg; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = (u32ShortIntTime > g_astF23_State[ViPipe].u32Sexp_MAX) ? + g_astF23_State[ViPipe].u32Sexp_MAX : u32ShortIntTime; + if (!pstSnsState->au32WDRIntTime[0]) + pstSnsState->au32WDRIntTime[0] = 1; + /* short exp = SexpReg * 2 + 1 */ + u8SexpReg = (pstSnsState->au32WDRIntTime[0] - 1) >> 1; + pstSnsState->au32WDRIntTime[0] = (u8SexpReg << 1) + 1; + g_astF23_State[ViPipe].u8SexpReg = u8SexpReg; + + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = u32LongIntTime; + + if ((pstSnsState->au32WDRIntTime[0] + pstSnsState->au32WDRIntTime[1] + 5) > pstSnsState->au32FL[0]) { + CVI_TRACE_SNS(CVI_DBG_ERR, "inttime over spec [%u, %u, %u]\n", + pstSnsState->au32WDRIntTime[0], + pstSnsState->au32WDRIntTime[1], + pstSnsState->au32FL[0]); + return CVI_FAILURE; + } + + pstSnsRegsInfo->astI2cData[WDR2_SHS1_0_DATA].u32Data = (pstSnsState->au32WDRIntTime[1] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_SHS1_1_DATA].u32Data = ((pstSnsState->au32WDRIntTime[1] & 0xFF00) >> 8); + + pstSnsRegsInfo->astI2cData[WDR2_SHS2_DATA].u32Data = (u8SexpReg & 0xFF); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + /* update cif*/ + cmos_get_cif_wdr(ViPipe, &pstSnsState->astSyncInfo[0].cifCfg); + } else { + if ((u32IntTime[0] + 5) > pstSnsState->au32FL[0]) { + CVI_TRACE_SNS(CVI_DBG_ERR, "inttime over spec [%u, %u]\n", + u32IntTime[0], + pstSnsState->au32FL[0]); + return CVI_FAILURE; + } + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_DATA].u32Data = (u32IntTime[0] & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_DATA].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[64] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[63]) { + *pu32AgainLin = gain_table[63]; + *pu32AgainDb = 63; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin <= 1024) { + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + } else if (*pu32DgainLin <= 2048) { + *pu32DgainLin = 2048; + *pu32DgainDb = 1; + } else { + *pu32DgainLin = 4096; + *pu32DgainDb = 3; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0] | g_astF23_mode[pstSnsState->u8ImgMode].u8DgainReg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_DATA].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_DATA].u32Data = (u32Dgain & 0xFF); + } else { + /* DOL mode */ + pstSnsRegsInfo->astI2cData[WDR2_AGAIN_DATA].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN_DATA].u32Data = (u32Dgain & 0xFF); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 1; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 5) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > g_astF23_State[ViPipe].u32Sexp_MAX) ? + g_astF23_State[ViPipe].u32Sexp_MAX : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio is too large!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const F23_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astF23_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == F23_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = F23_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astF23_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == F23_MODE_1080P30) + pstSnsState->u8ImgMode = F23_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astF23_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "2to1 line WDR 1080p mode(60fps->30fps)\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunF23_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = f23_i2c_addr; + pstI2c_data[i].u32AddrByteNum = f23_addr_byte; + pstI2c_data[i].u32DataByteNum = f23_data_byte; + } + + //DOL 2t1 Mode Regs + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + //Linear Mode Regs + pstI2c_data[WDR2_SHS1_0_ADDR].u32RegAddr = F23_GRP_ADDR; + pstI2c_data[WDR2_SHS1_0_ADDR].u32Data = F23_SHS1_ADDR; + pstI2c_data[WDR2_SHS1_0_DATA].u32RegAddr = F23_GRP_ADDR + 1; + + pstI2c_data[WDR2_SHS1_1_ADDR].u32RegAddr = F23_GRP_ADDR + 2; + pstI2c_data[WDR2_SHS1_1_ADDR].u32Data = F23_SHS1_ADDR + 1; + pstI2c_data[WDR2_SHS1_1_DATA].u32RegAddr = F23_GRP_ADDR + 3; + + pstI2c_data[WDR2_SHS2_ADDR].u32RegAddr = F23_GRP_ADDR + 4; + pstI2c_data[WDR2_SHS2_ADDR].u32Data = F23_SHS2_ADDR; + pstI2c_data[WDR2_SHS2_DATA].u32RegAddr = F23_GRP_ADDR + 5; + + pstI2c_data[WDR2_AGAIN_ADDR].u32RegAddr = F23_GRP_ADDR + 6; + pstI2c_data[WDR2_AGAIN_ADDR].u32Data = F23_GAIN_ADDR; + pstI2c_data[WDR2_AGAIN_DATA].u32RegAddr = F23_GRP_ADDR + 7; + + pstI2c_data[WDR2_DGAIN_ADDR].u32RegAddr = F23_GRP_ADDR + 8; + pstI2c_data[WDR2_DGAIN_ADDR].u32Data = F23_DGAIN_ADDR; + pstI2c_data[WDR2_DGAIN_DATA].u32RegAddr = F23_GRP_ADDR + 9; + + pstI2c_data[WDR2_VMAX_0_ADDR].u32RegAddr = F23_GRP_ADDR + 10; + pstI2c_data[WDR2_VMAX_0_ADDR].u32Data = F23_VMAX_ADDR; + pstI2c_data[WDR2_VMAX_0_DATA].u32RegAddr = F23_GRP_ADDR + 11; + + pstI2c_data[WDR2_VMAX_1_ADDR].u32RegAddr = F23_GRP_ADDR + 12; + pstI2c_data[WDR2_VMAX_1_ADDR].u32Data = F23_VMAX_ADDR + 1; + pstI2c_data[WDR2_VMAX_1_DATA].u32RegAddr = F23_GRP_ADDR + 13; + + pstI2c_data[WDR2_REL].u32RegAddr = F23_GLAT_ADDR; + pstI2c_data[WDR2_REL].u32Data = 0x80; + + break; + default: + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = F23_GRP_ADDR; + pstI2c_data[LINEAR_SHS1_0_ADDR].u32Data = F23_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_0_DATA].u32RegAddr = F23_GRP_ADDR + 1; + + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = F23_GRP_ADDR + 2; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32Data = F23_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_1_DATA].u32RegAddr = F23_GRP_ADDR + 3; + + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = F23_GRP_ADDR + 4; + pstI2c_data[LINEAR_AGAIN_ADDR].u32Data = F23_GAIN_ADDR; + pstI2c_data[LINEAR_AGAIN_DATA].u32RegAddr = F23_GRP_ADDR + 5; + + pstI2c_data[LINEAR_DGAIN_ADDR].u32RegAddr = F23_GRP_ADDR + 6; + pstI2c_data[LINEAR_DGAIN_ADDR].u32Data = F23_DGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_DATA].u32RegAddr = F23_GRP_ADDR + 7; + + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = F23_GRP_ADDR + 8; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32Data = F23_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_0_DATA].u32RegAddr = F23_GRP_ADDR + 9; + + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = F23_GRP_ADDR + 10; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32Data = F23_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_1_DATA].u32RegAddr = F23_GRP_ADDR + 11; + + pstI2c_data[LINEAR_REL].u32RegAddr = F23_GLAT_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0x80; + + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + /* recalcualte CIF WDR info */ + cmos_get_cif_wdr(ViPipe, &pstCfg0->cifCfg); + pstCfg0->cifCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[WDR2_REL].u32Data = 0x80; + pstI2c_data[WDR2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_REL].u32Data = 0x80; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (F23_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = F23_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (F23_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = F23_MODE_1080P30_WDR; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const F23_MODE_S *pstMode = CVI_NULL; + + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = F23_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astF23_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F23_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &f23_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astF23_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astF23_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstRxAttr->wdr_manu.manual_en = 1; + pstRxAttr->wdr_manu.l2s_distance = g_astF23_State[ViPipe].u8SexpReg; + pstRxAttr->wdr_manu.lsef_length = pstRxAttr->img_size.height; + pstRxAttr->wdr_manu.discard_padding_lines = 0; + pstRxAttr->wdr_manu.update = 1; + } else { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &f23_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = f23_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = f23_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 f23_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunF23_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + F23_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + F23_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + F23_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + F23_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = F23_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, F23_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, F23_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, F23_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16F23_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsF23_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = f23_standby, + .pfnRestart = f23_restart, + .pfnMirrorFlip = CVI_NULL, + .pfnWriteReg = f23_write_register, + .pfnReadReg = f23_read_register, + .pfnSetBusInfo = f23_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_f23/f23_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/soi_f23/f23_cmos_ex.h new file mode 100644 index 000000000..cd4e52a3b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_f23/f23_cmos_ex.h @@ -0,0 +1,107 @@ +#ifndef __F23_CMOS_EX_H_ +#define __F23_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum f23_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_0_DATA, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_1_DATA, + LINEAR_AGAIN_ADDR, + LINEAR_AGAIN_DATA, + LINEAR_DGAIN_ADDR, + LINEAR_DGAIN_DATA, + LINEAR_VMAX_0_ADDR, + LINEAR_VMAX_0_DATA, + LINEAR_VMAX_1_ADDR, + LINEAR_VMAX_1_DATA, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum f23_dol2_regs_e { + WDR2_SHS1_0_ADDR, + WDR2_SHS1_0_DATA, + WDR2_SHS1_1_ADDR, + WDR2_SHS1_1_DATA, + WDR2_SHS2_ADDR, + WDR2_SHS2_DATA, + WDR2_AGAIN_ADDR, + WDR2_AGAIN_DATA, + WDR2_DGAIN_ADDR, + WDR2_DGAIN_DATA, + WDR2_VMAX_0_ADDR, + WDR2_VMAX_0_DATA, + WDR2_VMAX_1_ADDR, + WDR2_VMAX_1_DATA, + WDR2_REL, + WDR2_REGS_NUM +}; + +typedef enum _F23_MODE_E { + F23_MODE_1080P30 = 0, + F23_MODE_LINEAR_NUM, + F23_MODE_1080P30_WDR = F23_MODE_LINEAR_NUM, + F23_MODE_NUM +} F23_MODE_E; + +typedef struct _F23_STATE_S { + CVI_U32 u8SexpReg; + CVI_U32 u32Sexp_MAX; +} F23_STATE_S; + +typedef struct _F23_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + char name[64]; +} F23_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastF23[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunF23_BusInfo[]; +extern CVI_U16 g_au16F23_GainMode[]; +extern const CVI_U8 f23_i2c_addr; +extern const CVI_U32 f23_addr_byte; +extern const CVI_U32 f23_data_byte; +extern void f23_init(VI_PIPE ViPipe); +extern void f23_exit(VI_PIPE ViPipe); +extern void f23_standby(VI_PIPE ViPipe); +extern void f23_restart(VI_PIPE ViPipe); +extern int f23_write_register(VI_PIPE ViPipe, int addr, int data); +extern int f23_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __F23_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_f23/f23_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/soi_f23/f23_cmos_param.h new file mode 100644 index 000000000..4672b9d31 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_f23/f23_cmos_param.h @@ -0,0 +1,203 @@ +#ifndef __F23_CMOS_PARAM_H_ +#define __F23_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "f23_cmos_ex.h" + +static const F23_MODE_S g_astF23_mode[F23_MODE_NUM] = { + [F23_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.52, /* 1125 * 30 / 0xFFFF */ + .u32HtsDef = 2560, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1120, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 4096, + .u16Def = 1024, + .u16Step = 1, + }, + .u8DgainReg = 0x50, + }, + [F23_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.03, /* 2250 * 30 / 0xFFFF */ + .u32HtsDef = 640, + .u32VtsDef = 2250, + .stExp[0] = { + .u16Min = 1, + .u16Max = 131, + .u16Def = 13, + .u16Step = 2, + }, + .stExp[1] = { + .u16Min = 132, + .u16Max = 2096, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 4096, + .u16Def = 1024, + .u16Step = 1, + }, + .u8DgainReg = 0x50, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {68, 68, 68, 68, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1096, 1096, 1096, 1096 +#endif + }, + .stAuto = { + {68, 66, 67, 65, 135, 271, 255, 255, /*8*/255, 255, 255, 255, 256, 255, 256, 256}, + {68, 66, 67, 65, 135, 255, 255, 255, /*8*/255, 255, 255, 255, 256, 255, 256, 256}, + {68, 66, 67, 65, 128, 271, 271, 271, /*8*/255, 255, 256, 256, 256, 256, 256, 256}, + {68, 66, 67, 65, 128, 255, 271, 271, /*8*/255, 255, 256, 255, 256, 256, 256, 256}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1040, 1040, 1040, 1040, 1058, 1096, 1091, 1091, + /*8*/1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091}, + {1040, 1040, 1040, 1040, 1058, 1091, 1091, 1091, + /*8*/1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091}, + {1040, 1040, 1040, 1040, 1057, 1096, 1096, 1096, + /*8*/1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091}, + {1040, 1040, 1040, 1040, 1057, 1091, 1096, 1096, + /*8*/1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091}, +#endif + }, + }, +}; + +struct combo_dev_attr_s f23_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, +#ifdef FPGA_PORTING + .lane_id = {0, 4, -1, -1, -1}, +#else + .lane_id = {1, 0, 2, -1, -1}, +#endif +// .wdr_mode = CVI_MIPI_WDR_MODE_MANUAL, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __F23_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_f23/f23_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/soi_f23/f23_sensor_ctl.c new file mode 100644 index 000000000..8ae66aa0a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_f23/f23_sensor_ctl.c @@ -0,0 +1,427 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "f23_cmos_ex.h" + +static void f23_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void f23_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 f23_i2c_addr = 0x40; /* I2C Address of F23 */ +const CVI_U32 f23_addr_byte = 1; +const CVI_U32 f23_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int f23_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunF23_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, f23_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int f23_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int f23_read_register(VI_PIPE ViPipe, int addr) +{ + /* TODO:*/ + (void) ViPipe; + (void) addr; + + return CVI_SUCCESS; +} + + +int f23_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (f23_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (f23_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, f23_addr_byte + f23_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void f23_standby(VI_PIPE ViPipe) +{ + f23_write_register(ViPipe, 0x12, 0x40); +} + +void f23_restart(VI_PIPE ViPipe) +{ + f23_write_register(ViPipe, 0x12, 0x40); + delay_ms(20); + f23_write_register(ViPipe, 0x12, 0x00); +} + +void f23_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastF23[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + f23_write_register(ViPipe, + g_pastF23[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastF23[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void f23_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + CVI_U8 u8ImgMode; + + bInit = g_pastF23[ViPipe]->bInit; + enWDRMode = g_pastF23[ViPipe]->enWDRMode; + u8ImgMode = g_pastF23[ViPipe]->u8ImgMode; + + f23_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == F23_MODE_1080P30_WDR) { + /* F23_MODE_1080P30_WDR */ + f23_wdr_1080p30_2to1_init(ViPipe); + } else { + } + } else { + f23_linear_1080p30_init(ViPipe); + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == F23_MODE_1080P30_WDR) { + /* F23_MODE_1080P30_WDR */ + f23_wdr_1080p30_2to1_init(ViPipe); + } else { + } + } else { + f23_linear_1080p30_init(ViPipe); + } + } + g_pastF23[ViPipe]->bInit = CVI_TRUE; +} + +void f23_exit(VI_PIPE ViPipe) +{ + f23_i2c_exit(ViPipe); +} + +#ifdef FPGA_PORTING +static void f23_linear_1080p30_init(VI_PIPE ViPipe) +{ + f23_write_register(ViPipe, 0x12, 0x80); + delay_ms(15); + f23_write_register(ViPipe, 0x0E, 0x11); + f23_write_register(ViPipe, 0x0F, 0x14); + f23_write_register(ViPipe, 0x10, 0x40); + f23_write_register(ViPipe, 0x11, 0x80); + f23_write_register(ViPipe, 0x48, 0x05); + f23_write_register(ViPipe, 0x96, 0xAA); + f23_write_register(ViPipe, 0x94, 0xC0); + f23_write_register(ViPipe, 0x97, 0x8D); + f23_write_register(ViPipe, 0x96, 0x00); + f23_write_register(ViPipe, 0x12, 0x40); + f23_write_register(ViPipe, 0x48, 0x8A); + f23_write_register(ViPipe, 0x48, 0x0A); + f23_write_register(ViPipe, 0x0E, 0x11); + f23_write_register(ViPipe, 0x0F, 0x14); + +// f23_write_register(ViPipe, 0x10, 0x20); + f23_write_register(ViPipe, 0x10, 0x12); // VCO for FPGA + f23_write_register(ViPipe, 0x11, 0x80); + f23_write_register(ViPipe, 0x0D, 0xA0); + f23_write_register(ViPipe, 0x5F, 0x42); + f23_write_register(ViPipe, 0x60, 0x2B); + f23_write_register(ViPipe, 0x58, 0x12); + f23_write_register(ViPipe, 0x57, 0x60); + f23_write_register(ViPipe, 0x9D, 0x00); +// f23_write_register(ViPipe, 0x20, 0x00); +// f23_write_register(ViPipe, 0x21, 0x05); + f23_write_register(ViPipe, 0x20, 0x00); + f23_write_register(ViPipe, 0x21, 0x1e); // for FPGA, FrameW + f23_write_register(ViPipe, 0x22, 0x65); + f23_write_register(ViPipe, 0x23, 0x04); // FrameH + f23_write_register(ViPipe, 0x24, 0xC0); + f23_write_register(ViPipe, 0x25, 0x38); + f23_write_register(ViPipe, 0x26, 0x43); + f23_write_register(ViPipe, 0x27, 0xC3); + f23_write_register(ViPipe, 0x28, 0x19); + f23_write_register(ViPipe, 0x29, 0x04); + f23_write_register(ViPipe, 0x2C, 0x00); + f23_write_register(ViPipe, 0x2D, 0x00); + f23_write_register(ViPipe, 0x2E, 0x18); + f23_write_register(ViPipe, 0x2F, 0x44); + f23_write_register(ViPipe, 0x41, 0xC9); + f23_write_register(ViPipe, 0x42, 0x13); + f23_write_register(ViPipe, 0x46, 0x00); + f23_write_register(ViPipe, 0x76, 0x60); + f23_write_register(ViPipe, 0x77, 0x09); + f23_write_register(ViPipe, 0x1D, 0x00); + f23_write_register(ViPipe, 0x1E, 0x04); + f23_write_register(ViPipe, 0x6C, 0x50); // 1-lane +// f23_write_register(ViPipe, 0x6C, 0x40); // 2-lane + + f23_write_register(ViPipe, 0x68, 0x00); + f23_write_register(ViPipe, 0x6E, 0x2C); + f23_write_register(ViPipe, 0x70, 0x6C); + f23_write_register(ViPipe, 0x71, 0x6D); + f23_write_register(ViPipe, 0x72, 0x6A); + f23_write_register(ViPipe, 0x73, 0x36); + f23_write_register(ViPipe, 0x74, 0x02); + f23_write_register(ViPipe, 0x78, 0x9E); + f23_write_register(ViPipe, 0x89, 0x01); + f23_write_register(ViPipe, 0x6B, 0x20); + f23_write_register(ViPipe, 0x86, 0x40); + f23_write_register(ViPipe, 0x2A, 0xB1); + f23_write_register(ViPipe, 0x2B, 0x24); + f23_write_register(ViPipe, 0x31, 0x08); + f23_write_register(ViPipe, 0x32, 0x4F); + f23_write_register(ViPipe, 0x33, 0x20); + f23_write_register(ViPipe, 0x34, 0x5E); + f23_write_register(ViPipe, 0x35, 0x5E); + f23_write_register(ViPipe, 0x3A, 0xAF); + f23_write_register(ViPipe, 0x56, 0x32); + f23_write_register(ViPipe, 0x59, 0xBF); + f23_write_register(ViPipe, 0x5A, 0x04); + f23_write_register(ViPipe, 0x85, 0x5A); + f23_write_register(ViPipe, 0x8A, 0x04); + f23_write_register(ViPipe, 0x8F, 0x90); + f23_write_register(ViPipe, 0x91, 0x13); + f23_write_register(ViPipe, 0x5B, 0xA0); + f23_write_register(ViPipe, 0x5C, 0xF0); + f23_write_register(ViPipe, 0x5D, 0xFC); + f23_write_register(ViPipe, 0x5E, 0x1F); + f23_write_register(ViPipe, 0x62, 0x04); + f23_write_register(ViPipe, 0x63, 0x0F); + f23_write_register(ViPipe, 0x64, 0xC0); + f23_write_register(ViPipe, 0x66, 0x44); + f23_write_register(ViPipe, 0x67, 0x73); + f23_write_register(ViPipe, 0x69, 0x7C); + f23_write_register(ViPipe, 0x6A, 0x28); + f23_write_register(ViPipe, 0x7A, 0xC0); + f23_write_register(ViPipe, 0x4A, 0x05); + f23_write_register(ViPipe, 0x7E, 0xCD); + f23_write_register(ViPipe, 0x49, 0x10); + f23_write_register(ViPipe, 0x50, 0x02); + f23_write_register(ViPipe, 0x7B, 0x4A); + f23_write_register(ViPipe, 0x7C, 0x0C); + f23_write_register(ViPipe, 0x7F, 0x57); + f23_write_register(ViPipe, 0x90, 0x00); + f23_write_register(ViPipe, 0x8E, 0x00); + f23_write_register(ViPipe, 0x8C, 0xFF); + f23_write_register(ViPipe, 0x8D, 0xC7); + f23_write_register(ViPipe, 0x8B, 0x01); + f23_write_register(ViPipe, 0x0C, 0x40); // bit0: test pattern + f23_write_register(ViPipe, 0x65, 0x02); + f23_write_register(ViPipe, 0x80, 0x1A); + f23_write_register(ViPipe, 0x81, 0xC0); + f23_write_register(ViPipe, 0x19, 0x20); + f23_write_register(ViPipe, 0x99, 0x0F); + f23_write_register(ViPipe, 0x9B, 0x0F); + + //f23_default_reg_init(ViPipe); + + f23_write_register(ViPipe, 0x12, 0x00); + f23_write_register(ViPipe, 0x48, 0x8A); + f23_write_register(ViPipe, 0x48, 0x0A); + + printf("ViPipe:%d,===F23 1080P 30fps 10bit LINE FPGA Init OK!===\n", ViPipe); +} +#else +/* 1080P30 and 1080P25 */ +static void f23_linear_1080p30_init(VI_PIPE ViPipe) +{ + f23_write_register(ViPipe, 0x12, 0x80); + delay_ms(15); + f23_write_register(ViPipe, 0x0E, 0x11); + f23_write_register(ViPipe, 0x0F, 0x14); + f23_write_register(ViPipe, 0x10, 0x40); + f23_write_register(ViPipe, 0x11, 0x80); + f23_write_register(ViPipe, 0x48, 0x05); + f23_write_register(ViPipe, 0x96, 0xAA); + f23_write_register(ViPipe, 0x94, 0xC0); + f23_write_register(ViPipe, 0x97, 0x8D); + f23_write_register(ViPipe, 0x96, 0x00); + f23_write_register(ViPipe, 0x12, 0x40); + f23_write_register(ViPipe, 0x48, 0x8A); + f23_write_register(ViPipe, 0x48, 0x0A); + f23_write_register(ViPipe, 0x0E, 0x11); + f23_write_register(ViPipe, 0x0F, 0x14); + + f23_write_register(ViPipe, 0x10, 0x20); +// f23_write_register(ViPipe, 0x10, 0x12); // VCO for FPGA + f23_write_register(ViPipe, 0x11, 0x80); + f23_write_register(ViPipe, 0x0D, 0xA0); // for FPGA driving upto max + f23_write_register(ViPipe, 0x5F, 0x42); + f23_write_register(ViPipe, 0x60, 0x2B); + f23_write_register(ViPipe, 0x58, 0x12); + f23_write_register(ViPipe, 0x57, 0x60); + f23_write_register(ViPipe, 0x9D, 0x00); + f23_write_register(ViPipe, 0x20, 0x00); + f23_write_register(ViPipe, 0x21, 0x05); + // f23_write_register(ViPipe, 0x20, 0x00); + // f23_write_register(ViPipe, 0x21, 0x1e); // for FPGA, FrameW + f23_write_register(ViPipe, 0x22, 0x65); + f23_write_register(ViPipe, 0x23, 0x04); // FrameH + f23_write_register(ViPipe, 0x24, 0xC0); + f23_write_register(ViPipe, 0x25, 0x38); + f23_write_register(ViPipe, 0x26, 0x43); + f23_write_register(ViPipe, 0x27, 0xC3); + f23_write_register(ViPipe, 0x28, 0x19); + f23_write_register(ViPipe, 0x29, 0x04); + f23_write_register(ViPipe, 0x2C, 0x00); + f23_write_register(ViPipe, 0x2D, 0x00); + f23_write_register(ViPipe, 0x2E, 0x18); + f23_write_register(ViPipe, 0x2F, 0x44); + f23_write_register(ViPipe, 0x41, 0xC9); + f23_write_register(ViPipe, 0x42, 0x13); + f23_write_register(ViPipe, 0x46, 0x00); + f23_write_register(ViPipe, 0x76, 0x60); + f23_write_register(ViPipe, 0x77, 0x09); + f23_write_register(ViPipe, 0x1D, 0x00); + f23_write_register(ViPipe, 0x1E, 0x04); +// f23_write_register(ViPipe, 0x6C, 0x50); // 1-lane + f23_write_register(ViPipe, 0x6C, 0x40); // 2-lane + + f23_write_register(ViPipe, 0x68, 0x00); + f23_write_register(ViPipe, 0x6E, 0x2C); + f23_write_register(ViPipe, 0x70, 0x6C); + f23_write_register(ViPipe, 0x71, 0x6D); + f23_write_register(ViPipe, 0x72, 0x6A); + f23_write_register(ViPipe, 0x73, 0x36); + f23_write_register(ViPipe, 0x74, 0x02); + f23_write_register(ViPipe, 0x78, 0x9E); + f23_write_register(ViPipe, 0x89, 0x01); + f23_write_register(ViPipe, 0x6B, 0x20); + f23_write_register(ViPipe, 0x86, 0x40); + f23_write_register(ViPipe, 0x2A, 0xB1); + f23_write_register(ViPipe, 0x2B, 0x24); + f23_write_register(ViPipe, 0x31, 0x08); + f23_write_register(ViPipe, 0x32, 0x4F); + f23_write_register(ViPipe, 0x33, 0x20); + f23_write_register(ViPipe, 0x34, 0x5E); + f23_write_register(ViPipe, 0x35, 0x5E); + f23_write_register(ViPipe, 0x3A, 0xAF); + f23_write_register(ViPipe, 0x56, 0x32); + f23_write_register(ViPipe, 0x59, 0xBF); + f23_write_register(ViPipe, 0x5A, 0x04); + f23_write_register(ViPipe, 0x85, 0x5A); + f23_write_register(ViPipe, 0x8A, 0x04); + f23_write_register(ViPipe, 0x8F, 0x90); + f23_write_register(ViPipe, 0x91, 0x13); + f23_write_register(ViPipe, 0x5B, 0xA0); + f23_write_register(ViPipe, 0x5C, 0xF0); + f23_write_register(ViPipe, 0x5D, 0xFC); + f23_write_register(ViPipe, 0x5E, 0x1F); + f23_write_register(ViPipe, 0x62, 0x04); + f23_write_register(ViPipe, 0x63, 0x0F); + f23_write_register(ViPipe, 0x64, 0xC0); + f23_write_register(ViPipe, 0x66, 0x44); + f23_write_register(ViPipe, 0x67, 0x73); + f23_write_register(ViPipe, 0x69, 0x7C); + f23_write_register(ViPipe, 0x6A, 0x28); + f23_write_register(ViPipe, 0x7A, 0xC0); + f23_write_register(ViPipe, 0x4A, 0x05); + f23_write_register(ViPipe, 0x7E, 0xCD); + f23_write_register(ViPipe, 0x49, 0x10); + f23_write_register(ViPipe, 0x50, 0x02); + f23_write_register(ViPipe, 0x7B, 0x4A); + f23_write_register(ViPipe, 0x7C, 0x0C); + f23_write_register(ViPipe, 0x7F, 0x57); + f23_write_register(ViPipe, 0x90, 0x00); + f23_write_register(ViPipe, 0x8E, 0x00); + f23_write_register(ViPipe, 0x8C, 0xFF); + f23_write_register(ViPipe, 0x8D, 0xC7); + f23_write_register(ViPipe, 0x8B, 0x01); + f23_write_register(ViPipe, 0x0C, 0x40); // bit0: test pattern + f23_write_register(ViPipe, 0x65, 0x02); + f23_write_register(ViPipe, 0x80, 0x1A); + f23_write_register(ViPipe, 0x81, 0xC0); + f23_write_register(ViPipe, 0x19, 0x20); + f23_write_register(ViPipe, 0x99, 0x0F); + f23_write_register(ViPipe, 0x9B, 0x0F); + + //f23_default_reg_init(ViPipe); + + f23_write_register(ViPipe, 0x12, 0x00); + f23_write_register(ViPipe, 0x48, 0x8A); + f23_write_register(ViPipe, 0x48, 0x0A); + + printf("ViPipe:%d,===F23 1080P 30fps 10bit LINE FPGA Init OK!===\n", ViPipe); +} +#endif + +static void f23_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + (void) ViPipe; + + printf("===F23 sensor 1080P30fps HDR not support yet!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_f35/Makefile b/middleware/v2/component/isp/sensor/cv181x/soi_f35/Makefile new file mode 100644 index 000000000..43d630ab4 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_f35/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_f35.a +TARGET_SO = $(MW_LIB)/libsns_f35.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_f35/f35_cmos.c b/middleware/v2/component/isp/sensor/cv181x/soi_f35/f35_cmos.c new file mode 100644 index 000000000..492682bc2 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_f35/f35_cmos.c @@ -0,0 +1,1025 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "f35_cmos_ex.h" +#include "f35_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define F35_ID 35 +#define SENSOR_F35_WIDTH 1920 +#define SENSOR_F35_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastF35[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define F35_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastF35[dev]) +#define F35_SENSOR_SET_CTX(dev, pstCtx) (g_pastF35[dev] = pstCtx) +#define F35_SENSOR_RESET_CTX(dev) (g_pastF35[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunF35_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16F35_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16F35_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +F35_STATE_S g_astF35_State[VI_MAX_PIPE_NUM] = {{0} }; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****F35 Lines Range*****/ +#define F35_FULL_LINES_MAX (0xFFFF) +#define F35_FULL_LINES_MAX_2TO1_WDR (0xFFFF) + +/*****F35 Register Address*****/ +#define F35_SHS1_ADDR 0x01 +#define F35_SHS2_ADDR 0x05 +#define F35_GAIN_ADDR 0x00 +#define F35_DGAIN_ADDR 0x0D +#define F35_VMAX_ADDR 0x22 +#define F35_L2S_ADDR 0xAA +#define F35_TABLE_END 0xff + +#define F35_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = F35_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 2; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stDgainAccu.f32Accuracy = 6; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + pstAeSnsDft->enBlcType = AE_BLC_TYPE_LADDER; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astF35_mode[F35_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astF35_mode[F35_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 15872; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 4096; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + pstAeSnsDft->u32AEResponseFrame = 4; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astF35_mode[F35_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astF35_mode[F35_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstAeSnsDft->u32MinIntTime = 1; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 15872; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 4096; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astF35_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astF35_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astF35_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case F35_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > F35_FULL_LINES_MAX_2TO1_WDR) ? F35_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case F35_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > F35_FULL_LINES_MAX) ? F35_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + /* maximum sexp = 2 * reg_AA + 1 - 8. */ + CVI_U32 SexpLimit = g_astF35_mode[pstSnsState->u8ImgMode].u32L2S_MAX - 4; + + g_astF35_State[ViPipe].u32Sexp_MAX = SexpLimit * 2 + 1; + syslog(LOG_DEBUG, "VMAX %d, MAX_SEXP %d\n", u32VMAX, g_astF35_State[ViPipe].u32Sexp_MAX); + } + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_DATA].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_DATA].u32Data = ((u32VMAX & 0xFF00) >> 8); + } else { + pstSnsRegsInfo->astI2cData[WDR2_VMAX_0_DATA].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_VMAX_1_DATA].u32Data = ((u32VMAX & 0xFF00) >> 8); + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + CVI_U8 u8SexpReg; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = (u32ShortIntTime > g_astF35_State[ViPipe].u32Sexp_MAX) ? + g_astF35_State[ViPipe].u32Sexp_MAX : u32ShortIntTime; + if (!pstSnsState->au32WDRIntTime[0]) + pstSnsState->au32WDRIntTime[0] = 1; + /* short exp = SexpReg * 2 + 1 */ + u8SexpReg = (pstSnsState->au32WDRIntTime[0] - 1) >> 1; + pstSnsState->au32WDRIntTime[0] = (u8SexpReg << 1) + 1; + g_astF35_State[ViPipe].u8SexpReg = u8SexpReg; + + /* long exposure must be odd number. */ + if (!(u32LongIntTime & 0x1)) + u32LongIntTime = (u32LongIntTime > 1) ? u32LongIntTime - 1 : 1; + pstSnsState->au32WDRIntTime[1] = u32LongIntTime; + + if ((pstSnsState->au32WDRIntTime[0] + pstSnsState->au32WDRIntTime[1]) > pstSnsState->au32FL[0]) { + CVI_TRACE_SNS(CVI_DBG_ERR, "inttime over spec [%u, %u, %u]\n", + pstSnsState->au32WDRIntTime[0], + pstSnsState->au32WDRIntTime[1], + pstSnsState->au32FL[0]); + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[0] - pstSnsState->au32WDRIntTime[0]; + } + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + pstSnsRegsInfo->astI2cData[WDR2_SHS1_0_DATA].u32Data = (pstSnsState->au32WDRIntTime[1] & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_SHS1_1_DATA].u32Data = ((pstSnsState->au32WDRIntTime[1] & 0xFF00) >> 8); + + pstSnsRegsInfo->astI2cData[WDR2_SHS2_DATA].u32Data = (u8SexpReg & 0xFF); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if ((u32IntTime[0] + 5) > pstSnsState->au32FL[0]) { + CVI_TRACE_SNS(CVI_DBG_ERR, "inttime over spec [%u, %u]\n", + u32IntTime[0], + pstSnsState->au32FL[0]); + return CVI_FAILURE; + } + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_DATA].u32Data = (u32IntTime[0] & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_DATA].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[64] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[63]) { + *pu32AgainLin = gain_table[63]; + *pu32AgainDb = 63; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin < 2048) { + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + } else if (*pu32DgainLin < 4096) { + *pu32DgainLin = 2048; + *pu32DgainDb = 1; + } else { + *pu32DgainLin = 4096; + *pu32DgainDb = 3; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0] | g_astF35_mode[pstSnsState->u8ImgMode].u8DgainReg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_DATA].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_DATA].u32Data = (u32Dgain & 0xFF); + } else { + /* DOL mode */ + pstSnsRegsInfo->astI2cData[WDR2_AGAIN_DATA].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN_DATA].u32Data = (u32Dgain & 0xFF); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0; + CVI_U32 u32ShortTimeMinLimit = 1; + + (void) u16ManRatioEnable; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32IntTimeMaxTmp = (pstSnsState->au32FL[0] * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > g_astF35_State[ViPipe].u32Sexp_MAX) ? + g_astF35_State[ViPipe].u32Sexp_MAX : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const F35_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astF35_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == F35_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = F35_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astF35_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == F35_MODE_1080P30) + pstSnsState->u8ImgMode = F35_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astF35_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "2to1 line WDR 1080p mode(60fps->30fps)\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunF35_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + WDR2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = f35_i2c_addr; + pstI2c_data[i].u32AddrByteNum = f35_addr_byte; + pstI2c_data[i].u32DataByteNum = f35_data_byte; + } + + //DOL 2t1 Mode Regs + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + //Linear Mode Regs + pstI2c_data[WDR2_SHS1_0_DATA].u32RegAddr = F35_SHS1_ADDR; + + pstI2c_data[WDR2_SHS1_1_DATA].u32RegAddr = F35_SHS1_ADDR + 1; + + pstI2c_data[WDR2_SHS2_DATA].u32RegAddr = F35_SHS2_ADDR; + + pstI2c_data[WDR2_AGAIN_DATA].u32RegAddr = F35_GAIN_ADDR; + + pstI2c_data[WDR2_DGAIN_DATA].u32RegAddr = F35_DGAIN_ADDR; + pstI2c_data[WDR2_DGAIN_DATA].u8DelayFrmNum = 2; + + pstI2c_data[WDR2_VMAX_0_DATA].u32RegAddr = F35_VMAX_ADDR; + pstI2c_data[WDR2_VMAX_0_DATA].u8DelayFrmNum = 2; + + pstI2c_data[WDR2_VMAX_1_DATA].u32RegAddr = F35_VMAX_ADDR + 1; + pstI2c_data[WDR2_VMAX_1_DATA].u8DelayFrmNum = 2; + + break; + default: + pstI2c_data[LINEAR_SHS1_0_DATA].u32RegAddr = F35_SHS1_ADDR; + + pstI2c_data[LINEAR_SHS1_1_DATA].u32RegAddr = F35_SHS1_ADDR + 1; + + pstI2c_data[LINEAR_AGAIN_DATA].u32RegAddr = F35_GAIN_ADDR; + + pstI2c_data[LINEAR_DGAIN_DATA].u32RegAddr = F35_DGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_DATA].u8DelayFrmNum = 2; + + pstI2c_data[LINEAR_VMAX_0_DATA].u32RegAddr = F35_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_0_DATA].u8DelayFrmNum = 2; + + pstI2c_data[LINEAR_VMAX_1_DATA].u32RegAddr = F35_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_1_DATA].u8DelayFrmNum = 2; + + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (F35_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = F35_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (F35_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = F35_MODE_1080P30_WDR; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const F35_MODE_S *pstMode = CVI_NULL; + + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = F35_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astF35_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F35_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &f35_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astF35_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astF35_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &f35_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = f35_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = f35_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 f35_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunF35_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + F35_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + F35_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + F35_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + F35_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = F35_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, F35_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, F35_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, F35_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16F35_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16F35_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsF35_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = f35_standby, + .pfnRestart = f35_restart, + .pfnMirrorFlip = CVI_NULL, + .pfnWriteReg = f35_write_register, + .pfnReadReg = f35_read_register, + .pfnSetBusInfo = f35_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_f35/f35_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/soi_f35/f35_cmos_ex.h new file mode 100644 index 000000000..d57c93471 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_f35/f35_cmos_ex.h @@ -0,0 +1,94 @@ +#ifndef __F35_CMOS_EX_H_ +#define __F35_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum f35_linear_regs_e { + LINEAR_SHS1_0_DATA, + LINEAR_SHS1_1_DATA, + LINEAR_AGAIN_DATA, + LINEAR_DGAIN_DATA, + LINEAR_VMAX_0_DATA, + LINEAR_VMAX_1_DATA, + LINEAR_REGS_NUM +}; + +enum f35_dol2_regs_e { + WDR2_SHS1_0_DATA, + WDR2_SHS1_1_DATA, + WDR2_SHS2_DATA, + WDR2_AGAIN_DATA, + WDR2_DGAIN_DATA, + WDR2_VMAX_0_DATA, + WDR2_VMAX_1_DATA, + WDR2_REGS_NUM +}; + +typedef enum _F35_MODE_E { + F35_MODE_1080P30 = 0, + F35_MODE_LINEAR_NUM, + F35_MODE_1080P30_WDR = F35_MODE_LINEAR_NUM, + F35_MODE_NUM +} F35_MODE_E; + +typedef struct _F35_STATE_S { + CVI_U32 u8SexpReg; + CVI_U32 u32Sexp_MAX; +} F35_STATE_S; + +typedef struct _F35_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + CVI_U32 u32L2S_MAX; + char name[64]; +} F35_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastF35[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunF35_BusInfo[]; +extern CVI_U16 g_au16F35_GainMode[]; +extern CVI_U16 g_au16F35_L2SMode[]; +extern const CVI_U8 f35_i2c_addr; +extern const CVI_U32 f35_addr_byte; +extern const CVI_U32 f35_data_byte; +extern void f35_init(VI_PIPE ViPipe); +extern void f35_exit(VI_PIPE ViPipe); +extern void f35_standby(VI_PIPE ViPipe); +extern void f35_restart(VI_PIPE ViPipe); +extern int f35_write_register(VI_PIPE ViPipe, int addr, int data); +extern int f35_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __F35_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_f35/f35_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/soi_f35/f35_cmos_param.h new file mode 100644 index 000000000..d555b50c6 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_f35/f35_cmos_param.h @@ -0,0 +1,299 @@ +#ifndef __F35_CMOS_PARAM_H_ +#define __F35_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "f35_cmos_ex.h" + +static const F35_MODE_S g_astF35_mode[F35_MODE_NUM] = { + [F35_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.52, /* 1125 * 30 / 0xFFFF */ + .u32HtsDef = 2560, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1120, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 4096, + .u16Def = 1024, + .u16Step = 1, + }, + .u8DgainReg = 0xF0, + }, + [F35_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.03, /* 2250 * 30 / 0xFFFF */ + .u32HtsDef = 600, + .u32VtsDef = 2250, + .stExp[0] = { + .u16Min = 1, + .u16Max = 131, + .u16Def = 13, + .u16Step = 2, + }, + .stExp[1] = { + .u16Min = 132, + .u16Max = 2096, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 4096, + .u16Def = 1024, + .u16Step = 1, + }, + .u8DgainReg = 0xF0, + .u32L2S_MAX = 0xFC, + }, +}; + +ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.04988861083984375000, 4.38765525817871093750}, //B: slope, intercept + {0.04792890325188636780, 3.92597246170043945313}, //Gb: slope, intercept + {0.04811932146549224854, 3.89808440208435058594}, //Gr: slope, intercept + {0.05060157552361488342, 4.38360261917114257813}, //R: slope, intercept + }, + { //iso 200 + {0.05668020620942115784, 8.36383914947509765625}, //B: slope, intercept + {0.05190096050500869751, 9.12379550933837890625}, //Gb: slope, intercept + {0.05187550559639930725, 9.15234565734863281250}, //Gr: slope, intercept + {0.05625439062714576721, 8.55138778686523437500}, //R: slope, intercept + }, + { //iso 400 + {0.06673676520586013794, 14.12210369110107421875}, //B: slope, intercept + {0.05751207098364830017, 16.82577514648437500000}, //Gb: slope, intercept + {0.05804729461669921875, 16.61601066589355468750}, //Gr: slope, intercept + {0.06506298482418060303, 14.56138515472412109375}, //R: slope, intercept + }, + { //iso 800 + {0.08542215079069137573, 21.73256301879882812500}, //B: slope, intercept + {0.06953971832990646362, 27.63131332397460937500}, //Gb: slope, intercept + {0.06944745033979415894, 27.69048118591308593750}, //Gr: slope, intercept + {0.08224378526210784912, 22.75174522399902343750}, //R: slope, intercept + }, + { //iso 1600 + {0.10555629432201385498, 33.52949905395507812500}, //B: slope, intercept + {0.08282581716775894165, 43.78954315185546875000}, //Gb: slope, intercept + {0.08244660496711730957, 43.95007705688476562500}, //Gr: slope, intercept + {0.09990881383419036865, 35.52837753295898437500}, //R: slope, intercept + }, + { //iso 3200 + {0.13504384458065032959, 52.07051086425781250000}, //B: slope, intercept + {0.10585222393274307251, 68.38363647460937500000}, //Gb: slope, intercept + {0.10607221722602844238, 68.20414733886718750000}, //Gr: slope, intercept + {0.12796562910079956055, 55.04695510864257812500}, //R: slope, intercept + }, + { //iso 6400 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 12800 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 25600 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 51200 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 102400 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 204800 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 409600 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 819200 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 1638400 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, + { //iso 3276800 + {0.17905426025390625000, 79.02329254150390625000}, //B: slope, intercept + {0.15150412917137145996, 96.57375335693359375000}, //Gb: slope, intercept + {0.14989413321018218994, 96.65535736083984375000}, //Gr: slope, intercept + {0.16942876577377319336, 83.51070404052734375000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {68, 68, 68, 68, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1096, 1096, 1096, 1096 +#endif + }, + .stAuto = { + {68, 66, 67, 65, 69, 135, 271, 255, 255, /*8*/255, 255, 255, 255, 256, 255, 256}, + {68, 66, 67, 65, 69, 135, 255, 255, 255, /*8*/255, 255, 255, 255, 256, 255, 256}, + {68, 66, 67, 65, 69, 128, 271, 271, 271, /*8*/255, 255, 256, 256, 256, 256, 256}, + {68, 66, 67, 65, 69, 128, 255, 271, 271, /*8*/255, 255, 256, 255, 256, 256, 256}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1040, 1040, 1040, 1040, 1042, 1059, 1097, 1091, + /*8*/1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091}, + {1040, 1040, 1040, 1040, 1042, 1059, 1092, 1091, + /*8*/1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091}, + {1040, 1040, 1040, 1040, 1042, 1057, 1097, 1096, + /*8*/1091, 1091, 1091, 1091, 1097, 1091, 1091, 1091}, + {1040, 1040, 1040, 1040, 1042, 1057, 1092, 1096, + /*8*/1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091}, +#endif + }, + }, +}; + +struct combo_dev_attr_s f35_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {3, 4, 0, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __F35_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_f35/f35_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/soi_f35/f35_sensor_ctl.c new file mode 100644 index 000000000..4d8eb2162 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_f35/f35_sensor_ctl.c @@ -0,0 +1,396 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "f35_cmos_ex.h" + +static void f35_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void f35_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 f35_i2c_addr = 0x40; /* I2C Address of F35 */ +const CVI_U32 f35_addr_byte = 1; +const CVI_U32 f35_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int f35_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunF35_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, f35_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int f35_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int f35_read_register(VI_PIPE ViPipe, int addr) +{ + /* TODO:*/ + (void) ViPipe; + (void) addr; + + return CVI_SUCCESS; +} + + +int f35_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (f35_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (f35_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, f35_addr_byte + f35_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void f35_standby(VI_PIPE ViPipe) +{ + f35_write_register(ViPipe, 0x12, 0x40); +} + +void f35_restart(VI_PIPE ViPipe) +{ + f35_write_register(ViPipe, 0x12, 0x40); + delay_ms(20); + f35_write_register(ViPipe, 0x12, 0x00); +} + +void f35_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastF35[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + f35_write_register(ViPipe, + g_pastF35[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastF35[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void f35_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + CVI_U8 u8ImgMode; + + bInit = g_pastF35[ViPipe]->bInit; + enWDRMode = g_pastF35[ViPipe]->enWDRMode; + u8ImgMode = g_pastF35[ViPipe]->u8ImgMode; + + f35_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == F35_MODE_1080P30_WDR) { + /* F35_MODE_1080P30_WDR */ + f35_wdr_1080p30_2to1_init(ViPipe); + } else { + } + } else { + f35_linear_1080p30_init(ViPipe); + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == F35_MODE_1080P30_WDR) { + /* F35_MODE_1080P30_WDR */ + f35_wdr_1080p30_2to1_init(ViPipe); + } else { + } + } else { + f35_linear_1080p30_init(ViPipe); + } + } + g_pastF35[ViPipe]->bInit = CVI_TRUE; +} + +void f35_exit(VI_PIPE ViPipe) +{ + f35_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void f35_linear_1080p30_init(VI_PIPE ViPipe) +{ + f35_write_register(ViPipe, 0x12, 0x40); + f35_write_register(ViPipe, 0x48, 0x8A); + f35_write_register(ViPipe, 0x48, 0x0A); + f35_write_register(ViPipe, 0x0E, 0x11); + f35_write_register(ViPipe, 0x0F, 0x14); + f35_write_register(ViPipe, 0x10, 0x20); + f35_write_register(ViPipe, 0x11, 0x80); + f35_write_register(ViPipe, 0x0D, 0xF0); + f35_write_register(ViPipe, 0x5F, 0x42); + f35_write_register(ViPipe, 0x60, 0x2B); + f35_write_register(ViPipe, 0x58, 0x18); + f35_write_register(ViPipe, 0x57, 0x60); + f35_write_register(ViPipe, 0x64, 0xE0); + f35_write_register(ViPipe, 0x20, 0x00); + f35_write_register(ViPipe, 0x21, 0x05); + f35_write_register(ViPipe, 0x22, 0x65); + f35_write_register(ViPipe, 0x23, 0x04); + f35_write_register(ViPipe, 0x24, 0xC0); + f35_write_register(ViPipe, 0x25, 0x38); + f35_write_register(ViPipe, 0x26, 0x43); + f35_write_register(ViPipe, 0x27, 0x0C); + f35_write_register(ViPipe, 0x28, 0x15); + f35_write_register(ViPipe, 0x29, 0x02); + f35_write_register(ViPipe, 0x2A, 0x00); + f35_write_register(ViPipe, 0x2B, 0x12); + f35_write_register(ViPipe, 0x2C, 0x00); + f35_write_register(ViPipe, 0x2D, 0x00); + f35_write_register(ViPipe, 0x2E, 0x14); + f35_write_register(ViPipe, 0x2F, 0x44); + f35_write_register(ViPipe, 0x41, 0xC4); + f35_write_register(ViPipe, 0x42, 0x13); + f35_write_register(ViPipe, 0x46, 0x01); + f35_write_register(ViPipe, 0x76, 0x60); + f35_write_register(ViPipe, 0x77, 0x09); + f35_write_register(ViPipe, 0x80, 0x06); + f35_write_register(ViPipe, 0x1D, 0x00); + f35_write_register(ViPipe, 0x1E, 0x04); + f35_write_register(ViPipe, 0x6C, 0x40); + f35_write_register(ViPipe, 0x68, 0x00); + f35_write_register(ViPipe, 0x70, 0x6D); + f35_write_register(ViPipe, 0x71, 0xCD); + f35_write_register(ViPipe, 0x72, 0x6A); + f35_write_register(ViPipe, 0x73, 0x36); + f35_write_register(ViPipe, 0x74, 0x02); + f35_write_register(ViPipe, 0x78, 0x1E); + f35_write_register(ViPipe, 0x89, 0x81); + f35_write_register(ViPipe, 0x6E, 0x2C); + f35_write_register(ViPipe, 0x32, 0x4F); + f35_write_register(ViPipe, 0x33, 0x58); + f35_write_register(ViPipe, 0x34, 0x5F); + f35_write_register(ViPipe, 0x35, 0x5F); + f35_write_register(ViPipe, 0x3A, 0xAF); + f35_write_register(ViPipe, 0x3B, 0x00); + f35_write_register(ViPipe, 0x3C, 0x70); + f35_write_register(ViPipe, 0x3D, 0x8F); + f35_write_register(ViPipe, 0x3E, 0xFF); + f35_write_register(ViPipe, 0x3F, 0x85); + f35_write_register(ViPipe, 0x40, 0xFF); + f35_write_register(ViPipe, 0x56, 0x32); + f35_write_register(ViPipe, 0x59, 0x67); + f35_write_register(ViPipe, 0x85, 0x3C); + f35_write_register(ViPipe, 0x8A, 0x04); + f35_write_register(ViPipe, 0x91, 0x10); + f35_write_register(ViPipe, 0x9C, 0xE1); + f35_write_register(ViPipe, 0x5A, 0x09); + f35_write_register(ViPipe, 0x5C, 0x4C); + f35_write_register(ViPipe, 0x5D, 0xF4); + f35_write_register(ViPipe, 0x5E, 0x1E); + f35_write_register(ViPipe, 0x62, 0x04); + f35_write_register(ViPipe, 0x63, 0x0F); + f35_write_register(ViPipe, 0x66, 0x04); + f35_write_register(ViPipe, 0x67, 0x30); + f35_write_register(ViPipe, 0x6A, 0x12); + f35_write_register(ViPipe, 0x7A, 0xA0); + f35_write_register(ViPipe, 0x9D, 0x10); + f35_write_register(ViPipe, 0x4A, 0x05); + f35_write_register(ViPipe, 0x7E, 0xCD); + f35_write_register(ViPipe, 0x50, 0x02); + f35_write_register(ViPipe, 0x49, 0x10); + f35_write_register(ViPipe, 0x47, 0x02); + f35_write_register(ViPipe, 0x7B, 0x4A); + f35_write_register(ViPipe, 0x7C, 0x0C); + f35_write_register(ViPipe, 0x7F, 0x57); + f35_write_register(ViPipe, 0x8F, 0x81); + f35_write_register(ViPipe, 0x90, 0x00); + f35_write_register(ViPipe, 0x8C, 0xFF); + f35_write_register(ViPipe, 0x8D, 0xC7); + f35_write_register(ViPipe, 0x8E, 0x00); + f35_write_register(ViPipe, 0x8B, 0x01); + f35_write_register(ViPipe, 0x0C, 0x00); + f35_write_register(ViPipe, 0x69, 0x74); + f35_write_register(ViPipe, 0x65, 0x02); + f35_write_register(ViPipe, 0x81, 0x74); + f35_write_register(ViPipe, 0x19, 0x20); + + f35_default_reg_init(ViPipe); + + f35_write_register(ViPipe, 0x12, 0x00); + + printf("ViPipe:%d,===F35 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +static void f35_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + f35_write_register(ViPipe, 0x12, 0x48); + f35_write_register(ViPipe, 0x48, 0x96); + f35_write_register(ViPipe, 0x48, 0x16); + f35_write_register(ViPipe, 0x0E, 0x11); + f35_write_register(ViPipe, 0x0F, 0x14); + f35_write_register(ViPipe, 0x10, 0x3C); + f35_write_register(ViPipe, 0x11, 0x80); + f35_write_register(ViPipe, 0x0D, 0xF0); + f35_write_register(ViPipe, 0x5F, 0x42); + f35_write_register(ViPipe, 0x60, 0x2B); + f35_write_register(ViPipe, 0x58, 0x18); + f35_write_register(ViPipe, 0x57, 0x60); + f35_write_register(ViPipe, 0x64, 0xE0); + f35_write_register(ViPipe, 0x20, 0x58); + f35_write_register(ViPipe, 0x21, 0x02); + f35_write_register(ViPipe, 0x22, 0xCA); + f35_write_register(ViPipe, 0x23, 0x08); + f35_write_register(ViPipe, 0x24, 0xE0); + f35_write_register(ViPipe, 0x25, 0x38); + f35_write_register(ViPipe, 0x26, 0x41); + f35_write_register(ViPipe, 0x27, 0x07); + f35_write_register(ViPipe, 0x28, 0x25); + f35_write_register(ViPipe, 0x29, 0x02); + f35_write_register(ViPipe, 0x2A, 0x00); + f35_write_register(ViPipe, 0x2B, 0x12); + f35_write_register(ViPipe, 0x2C, 0x02); + f35_write_register(ViPipe, 0x2D, 0x00); + f35_write_register(ViPipe, 0x2E, 0x14); + f35_write_register(ViPipe, 0x2F, 0x44); + f35_write_register(ViPipe, 0x41, 0xC8); + f35_write_register(ViPipe, 0x42, 0x13); + f35_write_register(ViPipe, 0x46, 0x05); + f35_write_register(ViPipe, 0x76, 0x60); + f35_write_register(ViPipe, 0x77, 0x09); + f35_write_register(ViPipe, 0x80, 0x06); + f35_write_register(ViPipe, 0x1D, 0x00); + f35_write_register(ViPipe, 0x1E, 0x04); + f35_write_register(ViPipe, 0x6C, 0x40); + f35_write_register(ViPipe, 0x68, 0x00); + f35_write_register(ViPipe, 0x70, 0xDD); + f35_write_register(ViPipe, 0x71, 0xCB); + f35_write_register(ViPipe, 0x72, 0xD5); + f35_write_register(ViPipe, 0x73, 0x59); + f35_write_register(ViPipe, 0x74, 0x02); + f35_write_register(ViPipe, 0x78, 0x94); + f35_write_register(ViPipe, 0x89, 0x81); + f35_write_register(ViPipe, 0x6E, 0x2C); + f35_write_register(ViPipe, 0x84, 0x20); + f35_write_register(ViPipe, 0x6B, 0x20); + f35_write_register(ViPipe, 0x86, 0x40); + f35_write_register(ViPipe, 0x32, 0x4F); + f35_write_register(ViPipe, 0x33, 0x58); + f35_write_register(ViPipe, 0x34, 0x5F); + f35_write_register(ViPipe, 0x35, 0x5F); + f35_write_register(ViPipe, 0x3A, 0xAF); + f35_write_register(ViPipe, 0x3B, 0x00); + f35_write_register(ViPipe, 0x3C, 0x70); + f35_write_register(ViPipe, 0x3D, 0x8F); + f35_write_register(ViPipe, 0x3E, 0xFF); + f35_write_register(ViPipe, 0x3F, 0x85); + f35_write_register(ViPipe, 0x40, 0xFF); + f35_write_register(ViPipe, 0x56, 0x32); + f35_write_register(ViPipe, 0x59, 0x67); + f35_write_register(ViPipe, 0x85, 0x3C); + f35_write_register(ViPipe, 0x8A, 0x04); + f35_write_register(ViPipe, 0x91, 0x10); + f35_write_register(ViPipe, 0x9C, 0xE1); + f35_write_register(ViPipe, 0x5A, 0x09); + f35_write_register(ViPipe, 0x5C, 0x4C); + f35_write_register(ViPipe, 0x5D, 0xF4); + f35_write_register(ViPipe, 0x5E, 0x1E); + f35_write_register(ViPipe, 0x62, 0x04); + f35_write_register(ViPipe, 0x63, 0x0F); + f35_write_register(ViPipe, 0x66, 0x04); + f35_write_register(ViPipe, 0x67, 0x30); + f35_write_register(ViPipe, 0x6A, 0x12); + f35_write_register(ViPipe, 0x7A, 0xA0); + f35_write_register(ViPipe, 0x9D, 0x10); + f35_write_register(ViPipe, 0x4A, 0x05); + f35_write_register(ViPipe, 0x7E, 0xCD); + f35_write_register(ViPipe, 0x50, 0x02); + f35_write_register(ViPipe, 0x49, 0x10); + f35_write_register(ViPipe, 0x47, 0x02); + f35_write_register(ViPipe, 0x7B, 0x4A); + f35_write_register(ViPipe, 0x7C, 0x0C); + f35_write_register(ViPipe, 0x7F, 0x57); + f35_write_register(ViPipe, 0x8F, 0x81); + f35_write_register(ViPipe, 0x90, 0x00); + f35_write_register(ViPipe, 0x8C, 0xFF); + f35_write_register(ViPipe, 0x8D, 0xC7); + f35_write_register(ViPipe, 0x8E, 0x00); + f35_write_register(ViPipe, 0x8B, 0x01); + f35_write_register(ViPipe, 0x0C, 0x00); + f35_write_register(ViPipe, 0x69, 0x74); + f35_write_register(ViPipe, 0x65, 0x02); + f35_write_register(ViPipe, 0x81, 0x74); + f35_write_register(ViPipe, 0x19, 0x20); + f35_write_register(ViPipe, 0xA9, 0x14); + f35_write_register(ViPipe, 0xAA, 0xFF); // set l2s to max value + + f35_default_reg_init(ViPipe); + + if (g_au16F35_GainMode[ViPipe] == SNS_GAIN_MODE_ONLY_LEF) { + f35_write_register(ViPipe, 0x46, 0x01); + } else { + f35_write_register(ViPipe, 0x46, 0x05); + } + + f35_write_register(ViPipe, 0x12, 0x08); + + usleep(33*1000); + printf("===F35 sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_f37p/Makefile b/middleware/v2/component/isp/sensor/cv181x/soi_f37p/Makefile new file mode 100644 index 000000000..20147a162 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_f37p/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_f37p.a +TARGET_SO = $(MW_LIB)/libsns_f37p.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_f37p/f37p_cmos.c b/middleware/v2/component/isp/sensor/cv181x/soi_f37p/f37p_cmos.c new file mode 100644 index 000000000..de8095048 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_f37p/f37p_cmos.c @@ -0,0 +1,821 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "f37p_cmos_ex.h" +#include "f37p_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define F37P_ID 0x0841 +#define F37P_I2C_ADDR_1 0x40 +#define F37P_I2C_ADDR_2 0x42 +#define F37P_I2C_ADDR_3 0x44 +#define F37P_I2C_ADDR_4 0x46 +#define F37P_I2C_ADDR_IS_VALID(addr) ((addr) == F37P_I2C_ADDR_1 || (addr) == F37P_I2C_ADDR_2 \ + || (addr) == F37P_I2C_ADDR_3 || (addr) == F37P_I2C_ADDR_4) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastF37P[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define F37P_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastF37P[dev]) +#define F37P_SENSOR_SET_CTX(dev, pstCtx) (g_pastF37P[dev] = pstCtx) +#define F37P_SENSOR_RESET_CTX(dev) (g_pastF37P[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunF37P_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16F37P_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16F37P_L2SMode[VI_MAX_PIPE_NUM] = {0}; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeF37P_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****F37P Lines Range*****/ +#define F37P_FULL_LINES_MAX (0xFFFF) + +/*****F37P Register Address*****/ +#define F37P_EXP_ADDR 0x01 +#define F37P_GAIN_ADDR 0x00 +#define F37P_VMAX_ADDR 0x22 +#define F37P_BLC_CTAL_ADDR 0x4a +#define F37P_TABLE_END 0xff + +#define F37P_RES_IS_1080P(w, h) ((w) == 1920 && (h) == 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const F37P_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astF37P_mode[pstSnsState->u8ImgMode]; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = F37P_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 2; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + pstAeSnsDft->enBlcType = AE_BLC_TYPE_LADDER; + + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + pstAeSnsDft->u32AEResponseFrame = 4; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astF37P_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astF37P_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astF37P_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case F37P_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > F37P_FULL_LINES_MAX) ? F37P_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H_DATA].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_DATA].u32Data = (u32VMAX & 0xFF); + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if ((u32IntTime[0] + 5) > pstSnsState->au32FL[0]) { + CVI_TRACE_SNS(CVI_DBG_ERR, "inttime over spec [%u, %u]\n", + u32IntTime[0], + pstSnsState->au32FL[0]); + return CVI_FAILURE; + } + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_DATA].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_DATA].u32Data = (u32IntTime[0] & 0xFF); + + return CVI_SUCCESS; +} + +static const CVI_U32 gain_table[] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; +static const CVI_U32 gain_table_size = ARRAY_SIZE(gain_table); + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + CVI_U32 i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[gain_table_size - 1]) { + *pu32AgainLin = gain_table[gain_table_size - 1]; + *pu32AgainDb = gain_table_size - 1; + return CVI_SUCCESS; + } + + for (i = 1; i < gain_table_size; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_DATA].u32Data = (u32Again & 0xFF); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const F37P_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astF37P_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = F37P_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astF37P_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + static CVI_U32 delay_frame; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunF37P_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = f37p_i2c_addr; + pstI2c_data[i].u32AddrByteNum = f37p_addr_byte; + pstI2c_data[i].u32DataByteNum = f37p_data_byte; + } + + switch (pstSnsState->enWDRMode) { + default: + pstI2c_data[LINEAR_BLC_CTRL_CLOSE].u32RegAddr = F37P_BLC_CTAL_ADDR; + pstI2c_data[LINEAR_BLC_CTRL_CLOSE].u32Data = 0x1; + pstI2c_data[LINEAR_EXP_L_DATA].u32RegAddr = F37P_EXP_ADDR; + pstI2c_data[LINEAR_EXP_H_DATA].u32RegAddr = F37P_EXP_ADDR + 1; + pstI2c_data[LINEAR_AGAIN_DATA].u32RegAddr = F37P_GAIN_ADDR; + pstI2c_data[LINEAR_VMAX_L_DATA].u32RegAddr = F37P_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_H_DATA].u32RegAddr = F37P_VMAX_ADDR + 1; + pstI2c_data[LINEAR_BLC_CTRL_OPEN].u32RegAddr = F37P_BLC_CTAL_ADDR; + pstI2c_data[LINEAR_BLC_CTRL_OPEN].u32Data = 0x0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + delay_frame = 0; + pstI2c_data[LINEAR_BLC_CTRL_CLOSE].bUpdate = CVI_TRUE; + } else { + if (++delay_frame == 2) { + pstCfg0->snsCfg.astI2cData[LINEAR_BLC_CTRL_OPEN].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeF37P_MirrorFip[ViPipe] != eSnsMirrorFlip) { + f37p_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeF37P_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (F37P_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = F37P_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const F37P_MODE_S *pstMode = CVI_NULL; + + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = F37P_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astF37P_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + F37P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &f37p_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astF37P_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astF37P_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &f37p_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = f37p_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = f37p_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (F37P_I2C_ADDR_IS_VALID(s32I2cAddr)) + f37p_i2c_addr = s32I2cAddr; +} + +static CVI_S32 f37p_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunF37P_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + F37P_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + F37P_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + F37P_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + F37P_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = F37P_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, F37P_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, F37P_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, F37P_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16F37P_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16F37P_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsF37P_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = f37p_standby, + .pfnRestart = f37p_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = f37p_write_register, + .pfnReadReg = f37p_read_register, + .pfnSetBusInfo = f37p_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = f37p_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_f37p/f37p_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/soi_f37p/f37p_cmos_ex.h new file mode 100644 index 000000000..de0465e0f --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_f37p/f37p_cmos_ex.h @@ -0,0 +1,77 @@ +#ifndef __F37P_CMOS_EX_H_ +#define __F37P_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +enum f37p_linear_regs_e { + LINEAR_BLC_CTRL_CLOSE, + LINEAR_EXP_H_DATA, + LINEAR_EXP_L_DATA, + LINEAR_AGAIN_DATA, + LINEAR_VMAX_H_DATA, + LINEAR_VMAX_L_DATA, + LINEAR_BLC_CTRL_OPEN, + LINEAR_REGS_NUM +}; + +typedef enum _F37P_MODE_E { + F37P_MODE_1080P30 = 0, + F37P_MODE_LINEAR_NUM, + F37P_MODE_NUM +} F37P_MODE_E; + +typedef struct _F37P_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + CVI_U32 u32L2S_MAX; + char name[64]; +} F37P_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastF37P[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunF37P_BusInfo[]; +extern CVI_U8 f37p_i2c_addr; +extern const CVI_U32 f37p_addr_byte; +extern const CVI_U32 f37p_data_byte; +extern void f37p_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void f37p_init(VI_PIPE ViPipe); +extern void f37p_exit(VI_PIPE ViPipe); +extern void f37p_standby(VI_PIPE ViPipe); +extern void f37p_restart(VI_PIPE ViPipe); +extern int f37p_write_register(VI_PIPE ViPipe, int addr, int data); +extern int f37p_read_register(VI_PIPE ViPipe, int addr); +extern int f37p_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __F37P_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_f37p/f37p_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/soi_f37p/f37p_cmos_param.h new file mode 100644 index 000000000..3648a52be --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_f37p/f37p_cmos_param.h @@ -0,0 +1,125 @@ +#ifndef __F37P_CMOS_PARAM_H_ +#define __F37P_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "f37p_cmos_ex.h" + +static const F37P_MODE_S g_astF37P_mode[F37P_MODE_NUM] = { + [F37P_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.52, /* 1125 * 30 / 0xFFFF */ + .u32HtsDef = 2560, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1120, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {64, 64, 64, 64, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1040, 1040, 1040, 1040 +#endif + }, + .stAuto = { + {64, 64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, +#endif + }, + }, +}; + +struct combo_dev_attr_s f37p_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 1, 3, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 8, + } + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __F37P_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_f37p/f37p_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/soi_f37p/f37p_sensor_ctl.c new file mode 100644 index 000000000..fce19875b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_f37p/f37p_sensor_ctl.c @@ -0,0 +1,362 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "f37p_cmos_ex.h" + +static void f37p_linear_1080p30_init(VI_PIPE ViPipe); + +CVI_U8 f37p_i2c_addr = 0x40; /* I2C Address of F37P */ +const CVI_U32 f37p_addr_byte = 1; +const CVI_U32 f37p_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int f37p_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunF37P_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, f37p_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int f37p_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int f37p_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, f37p_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + ret = read(g_fd[ViPipe], buf, f37p_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (f37p_data_byte == 1) { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; + +} + +int f37p_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (f37p_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (f37p_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, f37p_addr_byte + f37p_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void f37p_standby(VI_PIPE ViPipe) +{ + f37p_write_register(ViPipe, 0x12, 0x40); +} + +void f37p_restart(VI_PIPE ViPipe) +{ + f37p_write_register(ViPipe, 0x12, 0x40); + delay_ms(20); + f37p_write_register(ViPipe, 0x12, 0x00); +} + +void f37p_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastF37P[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + f37p_write_register(ViPipe, + g_pastF37P[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastF37P[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void f37p_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = f37p_read_register(ViPipe, 0x12) & ~0x30; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x20; + break; + case ISP_SNS_FLIP: + val |= 0x10; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x30; + break; + default: + return; + } + + f37p_write_register(ViPipe, 0x12, val); +} + +#define F37P_CHIP_ID_HI_ADDR 0x0A +#define F37P_CHIP_ID_LO_ADDR 0x0B +#define F37P_CHIP_ID 0x0841 + +int f37p_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + if (f37p_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + delay_ms(4); + + nVal = f37p_read_register(ViPipe, F37P_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = f37p_read_register(ViPipe, F37P_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != F37P_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void f37p_init(VI_PIPE ViPipe) +{ + + f37p_i2c_init(ViPipe); + + f37p_linear_1080p30_init(ViPipe); + + g_pastF37P[ViPipe]->bInit = CVI_TRUE; +} + +void f37p_exit(VI_PIPE ViPipe) +{ + f37p_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void f37p_linear_1080p30_init(VI_PIPE ViPipe) +{ + f37p_write_register(ViPipe, 0x12, 0x40); + f37p_write_register(ViPipe, 0x48, 0x8A); + f37p_write_register(ViPipe, 0x48, 0x0A); + f37p_write_register(ViPipe, 0x0E, 0x19); + f37p_write_register(ViPipe, 0x0F, 0x04); + f37p_write_register(ViPipe, 0x10, 0x20); + f37p_write_register(ViPipe, 0x11, 0x80); + f37p_write_register(ViPipe, 0x46, 0x09); + f37p_write_register(ViPipe, 0x47, 0x66); + f37p_write_register(ViPipe, 0x0D, 0xF2); + f37p_write_register(ViPipe, 0x57, 0x6A); + f37p_write_register(ViPipe, 0x58, 0x22); + f37p_write_register(ViPipe, 0x5F, 0x41); + f37p_write_register(ViPipe, 0x60, 0x24); + f37p_write_register(ViPipe, 0xA5, 0xC0); + f37p_write_register(ViPipe, 0x20, 0x00); + f37p_write_register(ViPipe, 0x21, 0x05); + f37p_write_register(ViPipe, 0x22, 0x65); + f37p_write_register(ViPipe, 0x23, 0x04); + f37p_write_register(ViPipe, 0x24, 0xC0); + f37p_write_register(ViPipe, 0x25, 0x38); + f37p_write_register(ViPipe, 0x26, 0x43); + f37p_write_register(ViPipe, 0x27, 0xC6); + f37p_write_register(ViPipe, 0x28, 0x15); + f37p_write_register(ViPipe, 0x29, 0x04); + f37p_write_register(ViPipe, 0x2A, 0xBB); + f37p_write_register(ViPipe, 0x2B, 0x14); + f37p_write_register(ViPipe, 0x2C, 0x02); + f37p_write_register(ViPipe, 0x2D, 0x00); + f37p_write_register(ViPipe, 0x2E, 0x14); + f37p_write_register(ViPipe, 0x2F, 0x04); + f37p_write_register(ViPipe, 0x41, 0xC5); + f37p_write_register(ViPipe, 0x42, 0x33); + f37p_write_register(ViPipe, 0x47, 0x46); + f37p_write_register(ViPipe, 0x76, 0x60); + f37p_write_register(ViPipe, 0x77, 0x09); + f37p_write_register(ViPipe, 0x80, 0x01); + f37p_write_register(ViPipe, 0xAF, 0x22); + f37p_write_register(ViPipe, 0xAB, 0x00); + f37p_write_register(ViPipe, 0x1D, 0x00); + f37p_write_register(ViPipe, 0x1E, 0x04); + f37p_write_register(ViPipe, 0x6C, 0x40); + f37p_write_register(ViPipe, 0x9E, 0xF8); + f37p_write_register(ViPipe, 0x6E, 0x2C); + f37p_write_register(ViPipe, 0x70, 0x6C); + f37p_write_register(ViPipe, 0x71, 0x6D); + f37p_write_register(ViPipe, 0x72, 0x6A); + f37p_write_register(ViPipe, 0x73, 0x56); + f37p_write_register(ViPipe, 0x74, 0x02); + f37p_write_register(ViPipe, 0x78, 0x9D); + f37p_write_register(ViPipe, 0x89, 0x01); + f37p_write_register(ViPipe, 0x6B, 0x20); + f37p_write_register(ViPipe, 0x86, 0x40); + f37p_write_register(ViPipe, 0x31, 0x10); + f37p_write_register(ViPipe, 0x32, 0x18); + f37p_write_register(ViPipe, 0x33, 0xE8); + f37p_write_register(ViPipe, 0x34, 0x5E); + f37p_write_register(ViPipe, 0x35, 0x5E); + f37p_write_register(ViPipe, 0x3A, 0xAF); + f37p_write_register(ViPipe, 0x3B, 0x00); + f37p_write_register(ViPipe, 0x3C, 0xFF); + f37p_write_register(ViPipe, 0x3D, 0xFF); + f37p_write_register(ViPipe, 0x3E, 0xFF); + f37p_write_register(ViPipe, 0x3F, 0xBB); + f37p_write_register(ViPipe, 0x40, 0xFF); + f37p_write_register(ViPipe, 0x56, 0x92); + f37p_write_register(ViPipe, 0x59, 0xAF); + f37p_write_register(ViPipe, 0x5A, 0x47); + f37p_write_register(ViPipe, 0x61, 0x18); + f37p_write_register(ViPipe, 0x6F, 0x04); + f37p_write_register(ViPipe, 0x85, 0x5F); + f37p_write_register(ViPipe, 0x8A, 0x44); + f37p_write_register(ViPipe, 0x91, 0x13); + f37p_write_register(ViPipe, 0x94, 0xA0); + f37p_write_register(ViPipe, 0x9B, 0x83); + f37p_write_register(ViPipe, 0x9C, 0xE1); + f37p_write_register(ViPipe, 0xA4, 0x80); + f37p_write_register(ViPipe, 0xA6, 0x22); + f37p_write_register(ViPipe, 0xA9, 0x1C); + f37p_write_register(ViPipe, 0x5B, 0xE7); + f37p_write_register(ViPipe, 0x5C, 0x28); + f37p_write_register(ViPipe, 0x5D, 0x67); + f37p_write_register(ViPipe, 0x5E, 0x11); + f37p_write_register(ViPipe, 0x62, 0x21); + f37p_write_register(ViPipe, 0x63, 0x0F); + f37p_write_register(ViPipe, 0x64, 0xD0); + f37p_write_register(ViPipe, 0x65, 0x02); + f37p_write_register(ViPipe, 0x67, 0x49); + f37p_write_register(ViPipe, 0x66, 0x00); + f37p_write_register(ViPipe, 0x68, 0x00); + f37p_write_register(ViPipe, 0x69, 0x72); + f37p_write_register(ViPipe, 0x6A, 0x12); + f37p_write_register(ViPipe, 0x7A, 0x00); + f37p_write_register(ViPipe, 0x82, 0x20); + f37p_write_register(ViPipe, 0x8D, 0x47); + f37p_write_register(ViPipe, 0x8F, 0x90); + f37p_write_register(ViPipe, 0x45, 0x01); + f37p_write_register(ViPipe, 0x97, 0x20); + f37p_write_register(ViPipe, 0x13, 0x81); + f37p_write_register(ViPipe, 0x96, 0x84); + f37p_write_register(ViPipe, 0x4A, 0x01); + f37p_write_register(ViPipe, 0xB1, 0x00); + f37p_write_register(ViPipe, 0xA1, 0x0F); + f37p_write_register(ViPipe, 0xBE, 0x00); + f37p_write_register(ViPipe, 0x7E, 0x48); + f37p_write_register(ViPipe, 0xB5, 0xC0); + f37p_write_register(ViPipe, 0x50, 0x02); + f37p_write_register(ViPipe, 0x49, 0x10); + f37p_write_register(ViPipe, 0x7F, 0x57); + f37p_write_register(ViPipe, 0x90, 0x00); + f37p_write_register(ViPipe, 0x7B, 0x4A); + f37p_write_register(ViPipe, 0x7C, 0x0C); + f37p_write_register(ViPipe, 0x8C, 0xFF); + f37p_write_register(ViPipe, 0x8E, 0x00); + f37p_write_register(ViPipe, 0x8B, 0x01); + f37p_write_register(ViPipe, 0x0C, 0x00); + f37p_write_register(ViPipe, 0xBC, 0x11); + f37p_write_register(ViPipe, 0x19, 0x20); + f37p_write_register(ViPipe, 0x1B, 0x4F); + + f37p_default_reg_init(ViPipe); + + f37p_write_register(ViPipe, 0x12, 0x00); + + delay_ms(80); + + printf("ViPipe:%d,===F37P 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_k06/Makefile b/middleware/v2/component/isp/sensor/cv181x/soi_k06/Makefile new file mode 100644 index 000000000..f1045598e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_k06/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_k06.a +TARGET_SO = $(MW_LIB)/libsns_k06.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_k06/k06_cmos.c b/middleware/v2/component/isp/sensor/cv181x/soi_k06/k06_cmos.c new file mode 100644 index 000000000..5c720b650 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_k06/k06_cmos.c @@ -0,0 +1,819 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "k06_cmos_ex.h" +#include "k06_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define K06_ID 06 +#define K06_I2C_ADDR_1 0x40 +#define K06_I2C_ADDR_2 0x44 +#define K06_I2C_ADDR_IS_VALID(addr) ((addr) == K06_I2C_ADDR_1 || (addr) == K06_I2C_ADDR_2) +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastK06[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define K06_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastK06[dev]) +#define K06_SENSOR_SET_CTX(dev, pstCtx) (g_pastK06[dev] = pstCtx) +#define K06_SENSOR_RESET_CTX(dev) (g_pastK06[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunK06_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16K06_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16K06_L2SMode[VI_MAX_PIPE_NUM] = {0}; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeK06_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****K06 Lines Range*****/ +#define K06_FULL_LINES_MAX (0xFFFF) + +/*****K06 Register Address*****/ +#define K06_SHS1_ADDR 0x01 +#define K06_GAIN_ADDR 0x00 +#define K06_VMAX_ADDR 0x22 +#define K06_TABLE_END 0xff + +#define K06_RES_IS_1440P(w, h) ((w) == 2560 && (h) == 1440) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const K06_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astK06_mode[pstSnsState->u8ImgMode]; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = K06_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 25); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 2; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 25 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + pstAeSnsDft->enBlcType = AE_BLC_TYPE_LADDER; + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? + g_au32InitExposure[ViPipe] : g_astK06_mode[K06_MODE_1440P25].stExp[0].u16Def; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astK06_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astK06_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astK06_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case K06_MODE_1440P25: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > K06_FULL_LINES_MAX) ? K06_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_DATA].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_DATA].u32Data = ((u32VMAX & 0xFF00) >> 8); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if ((u32IntTime[0] + 5) > pstSnsState->au32FL[0]) { + CVI_TRACE_SNS(CVI_DBG_ERR, "inttime over spec [%u, %u]\n", + u32IntTime[0], + pstSnsState->au32FL[0]); + return CVI_FAILURE; + } + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_DATA].u32Data = (u32IntTime[0] & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_DATA].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[64] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[63]) { + *pu32AgainLin = gain_table[63]; + *pu32AgainDb = 63; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_DATA].u32Data = (u32Again & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const K06_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astK06_mode[pstSnsState->u8ImgMode]; + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = K06_MODE_1440P25; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astK06_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunK06_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = k06_i2c_addr; + pstI2c_data[i].u32AddrByteNum = k06_addr_byte; + pstI2c_data[i].u32DataByteNum = k06_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + pstI2c_data[LINEAR_SHS1_0_DATA].u32RegAddr = K06_SHS1_ADDR; + + pstI2c_data[LINEAR_SHS1_1_DATA].u32RegAddr = K06_SHS1_ADDR + 1; + + pstI2c_data[LINEAR_AGAIN_DATA].u32RegAddr = K06_GAIN_ADDR; + + pstI2c_data[LINEAR_VMAX_0_DATA].u32RegAddr = K06_VMAX_ADDR; + + pstI2c_data[LINEAR_VMAX_1_DATA].u32RegAddr = K06_VMAX_ADDR + 1; + + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (K06_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = K06_MODE_1440P25; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeK06_MirrorFip[ViPipe] != eSnsMirrorFlip) { + k06_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeK06_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const K06_MODE_S *pstMode = CVI_NULL; + + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = K06_MODE_1440P25; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astK06_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + K06_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &k06_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astK06_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astK06_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &k06_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = k06_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = k06_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (K06_I2C_ADDR_IS_VALID(s32I2cAddr)) + k06_i2c_addr = s32I2cAddr; +} + +static CVI_S32 k06_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunK06_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + K06_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + K06_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + K06_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + K06_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = K06_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, K06_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, K06_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, K06_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16K06_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16K06_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsK06_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = k06_standby, + .pfnRestart = k06_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = k06_write_register, + .pfnReadReg = k06_read_register, + .pfnSetBusInfo = k06_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = k06_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_k06/k06_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/soi_k06/k06_cmos_ex.h new file mode 100644 index 000000000..e23696056 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_k06/k06_cmos_ex.h @@ -0,0 +1,82 @@ +#ifndef __K06_CMOS_EX_H_ +#define __K06_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum k06_linear_regs_e { + LINEAR_SHS1_0_DATA, + LINEAR_SHS1_1_DATA, + LINEAR_AGAIN_DATA, + LINEAR_VMAX_0_DATA, + LINEAR_VMAX_1_DATA, + LINEAR_REGS_NUM +}; + + +typedef enum _K06_MODE_E { + K06_MODE_1440P25 = 0, + K06_MODE_LINEAR_NUM, + K06_MODE_NUM +} K06_MODE_E; + +typedef struct _K06_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + CVI_U32 u32L2S_MAX; + char name[64]; +} K06_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastK06[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunK06_BusInfo[]; +extern CVI_U16 g_au16K06_GainMode[]; +extern CVI_U16 g_au16K06_L2SMode[]; +extern CVI_U8 k06_i2c_addr; +extern const CVI_U32 k06_addr_byte; +extern const CVI_U32 k06_data_byte; +extern void k06_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void k06_init(VI_PIPE ViPipe); +extern void k06_exit(VI_PIPE ViPipe); +extern void k06_standby(VI_PIPE ViPipe); +extern void k06_restart(VI_PIPE ViPipe); +extern int k06_write_register(VI_PIPE ViPipe, int addr, int data); +extern int k06_read_register(VI_PIPE ViPipe, int addr); +extern int k06_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __K06_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_k06/k06_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/soi_k06/k06_cmos_param.h new file mode 100644 index 000000000..9a1ae21d1 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_k06/k06_cmos_param.h @@ -0,0 +1,122 @@ +#ifndef __K06_CMOS_PARAM_H_ +#define __K06_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "k06_cmos_ex.h" + +static const K06_MODE_S g_astK06_mode[K06_MODE_NUM] = { + [K06_MODE_1440P25] = { + .name = "1440p25", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + .f32MaxFps = 25, + .f32MinFps = 0.57, /* 1500 * 25 / 0xFFFF */ + .u32HtsDef = 4608, + .u32VtsDef = 1500, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1500, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {64, 64, 64, 64, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1040, 1040, 1040, 1040 +#endif + }, + .stAuto = { + {64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, +#endif + }, + }, +}; + +struct combo_dev_attr_s k06_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 1, 3, -1, -1}, + .pn_swap = {0, 0, 0, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 1, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __K06_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_k06/k06_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/soi_k06/k06_sensor_ctl.c new file mode 100644 index 000000000..d97d23e85 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_k06/k06_sensor_ctl.c @@ -0,0 +1,349 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "k06_cmos_ex.h" + +#define K06_CHIP_ID_HI_ADDR 0x0A +#define K06_CHIP_ID_LO_ADDR 0x0B +#define K06_CHIP_ID 0x0852 + +static void k06_linear_1440p25_init(VI_PIPE ViPipe); + +CVI_U8 k06_i2c_addr = 0x40; /* I2C Address of K06 */ +const CVI_U32 k06_addr_byte = 1; +const CVI_U32 k06_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int k06_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunK06_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, k06_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int k06_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int k06_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, k06_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + ret = read(g_fd[ViPipe], buf, k06_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (k06_data_byte == 1) { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int k06_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (k06_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (k06_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, k06_addr_byte + k06_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void k06_standby(VI_PIPE ViPipe) +{ + k06_write_register(ViPipe, 0x12, 0x40); +} + +void k06_restart(VI_PIPE ViPipe) +{ + k06_write_register(ViPipe, 0x12, 0x40); + delay_ms(20); + k06_write_register(ViPipe, 0x12, 0x00); +} + +void k06_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastK06[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + k06_write_register(ViPipe, + g_pastK06[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastK06[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void k06_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = k06_read_register(ViPipe, 0x12) & (~0x30); + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + val |= 0x30; + break; + case ISP_SNS_MIRROR: + val |= (0x1 << 4); + break; + case ISP_SNS_FLIP: + val |= (0x2 << 4); + break; + case ISP_SNS_MIRROR_FLIP: + val &= ~(0x1 << 4); + break; + default: + return; + } + + k06_write_register(ViPipe, 0x12, val); +} + +int k06_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (k06_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = k06_read_register(ViPipe, K06_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = k06_read_register(ViPipe, K06_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != K06_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void k06_init(VI_PIPE ViPipe) +{ + k06_i2c_init(ViPipe); + + k06_linear_1440p25_init(ViPipe); + g_pastK06[ViPipe]->bInit = CVI_TRUE; +} + +void k06_exit(VI_PIPE ViPipe) +{ + k06_i2c_exit(ViPipe); +} + +static void k06_linear_1440p25_init(VI_PIPE ViPipe) +{ + k06_write_register(ViPipe, 0x12, 0x70); + k06_write_register(ViPipe, 0x48, 0x86); + k06_write_register(ViPipe, 0x48, 0x06); + k06_write_register(ViPipe, 0x0E, 0x11); + k06_write_register(ViPipe, 0x0F, 0x04); + k06_write_register(ViPipe, 0x10, 0x48); + k06_write_register(ViPipe, 0x11, 0x80); + k06_write_register(ViPipe, 0x46, 0x08); + k06_write_register(ViPipe, 0x0D, 0xA0); + k06_write_register(ViPipe, 0x57, 0x67); + k06_write_register(ViPipe, 0x58, 0x1F); + k06_write_register(ViPipe, 0x5F, 0x41); + k06_write_register(ViPipe, 0x60, 0x20); + k06_write_register(ViPipe, 0x20, 0x80); + k06_write_register(ViPipe, 0x21, 0x04); + k06_write_register(ViPipe, 0x22, 0xDC); + k06_write_register(ViPipe, 0x23, 0x05); + k06_write_register(ViPipe, 0x24, 0x80); + k06_write_register(ViPipe, 0x25, 0xA0); + k06_write_register(ViPipe, 0x26, 0x52); + k06_write_register(ViPipe, 0x27, 0x27); + k06_write_register(ViPipe, 0x28, 0x15); + k06_write_register(ViPipe, 0x29, 0x04); + k06_write_register(ViPipe, 0x2A, 0x20); + k06_write_register(ViPipe, 0x2B, 0x14); + k06_write_register(ViPipe, 0x2C, 0x00); + k06_write_register(ViPipe, 0x2D, 0x00); + k06_write_register(ViPipe, 0x2E, 0x6E); + k06_write_register(ViPipe, 0x2F, 0x04); + k06_write_register(ViPipe, 0x41, 0x06); + k06_write_register(ViPipe, 0x42, 0x05); + k06_write_register(ViPipe, 0x47, 0x46); + k06_write_register(ViPipe, 0x76, 0x80); + k06_write_register(ViPipe, 0x77, 0x0C); + k06_write_register(ViPipe, 0x80, 0x01); + k06_write_register(ViPipe, 0xAF, 0x12); + k06_write_register(ViPipe, 0xAA, 0x04); + k06_write_register(ViPipe, 0x1D, 0x00); + k06_write_register(ViPipe, 0x1E, 0x04); + k06_write_register(ViPipe, 0x6C, 0x40); + k06_write_register(ViPipe, 0x9E, 0xF8); + k06_write_register(ViPipe, 0x0C, 0x30); + k06_write_register(ViPipe, 0x6F, 0x80); + k06_write_register(ViPipe, 0x6E, 0x2C); + k06_write_register(ViPipe, 0x70, 0xF9); + k06_write_register(ViPipe, 0x71, 0xDD); + k06_write_register(ViPipe, 0x72, 0xD5); + k06_write_register(ViPipe, 0x73, 0x5A); + k06_write_register(ViPipe, 0x74, 0x02); + k06_write_register(ViPipe, 0x78, 0x1D); + k06_write_register(ViPipe, 0x89, 0x01); + k06_write_register(ViPipe, 0x6B, 0x20); + k06_write_register(ViPipe, 0x86, 0x40); + k06_write_register(ViPipe, 0x30, 0x8D); + k06_write_register(ViPipe, 0x31, 0x08); + k06_write_register(ViPipe, 0x32, 0x20); + k06_write_register(ViPipe, 0x33, 0x5C); + k06_write_register(ViPipe, 0x34, 0x30); + k06_write_register(ViPipe, 0x35, 0x30); + k06_write_register(ViPipe, 0x3A, 0xB6); + k06_write_register(ViPipe, 0x56, 0x92); + k06_write_register(ViPipe, 0x59, 0x48); + k06_write_register(ViPipe, 0x5A, 0x01); + k06_write_register(ViPipe, 0x61, 0x00); + k06_write_register(ViPipe, 0x64, 0xC0); + k06_write_register(ViPipe, 0x7F, 0x46); + k06_write_register(ViPipe, 0x85, 0x44); + k06_write_register(ViPipe, 0x8A, 0x00); + k06_write_register(ViPipe, 0x91, 0x58); + k06_write_register(ViPipe, 0x94, 0xE0); + k06_write_register(ViPipe, 0x9B, 0x8F); + k06_write_register(ViPipe, 0xA6, 0x02); + k06_write_register(ViPipe, 0xA7, 0xA0); + k06_write_register(ViPipe, 0xA9, 0x48); + k06_write_register(ViPipe, 0x45, 0x09); + k06_write_register(ViPipe, 0x5B, 0xA5); + k06_write_register(ViPipe, 0x5C, 0x8C); + k06_write_register(ViPipe, 0x5D, 0x97); + k06_write_register(ViPipe, 0x5E, 0x48); + k06_write_register(ViPipe, 0x65, 0x32); + k06_write_register(ViPipe, 0x66, 0x80); + k06_write_register(ViPipe, 0x67, 0x44); + k06_write_register(ViPipe, 0x68, 0x00); + k06_write_register(ViPipe, 0x69, 0x74); + k06_write_register(ViPipe, 0x6A, 0x2B); + k06_write_register(ViPipe, 0x7A, 0x82); + k06_write_register(ViPipe, 0x8D, 0x6F); + k06_write_register(ViPipe, 0x8F, 0x90); + k06_write_register(ViPipe, 0xA4, 0xC7); + k06_write_register(ViPipe, 0xA5, 0xAF); + k06_write_register(ViPipe, 0xB7, 0x21); + k06_write_register(ViPipe, 0x97, 0x20); + k06_write_register(ViPipe, 0x13, 0x81); + k06_write_register(ViPipe, 0x96, 0x84); + k06_write_register(ViPipe, 0x4A, 0x01); + k06_write_register(ViPipe, 0x7E, 0x4C); + k06_write_register(ViPipe, 0x50, 0x02); + k06_write_register(ViPipe, 0x93, 0xC0); + k06_write_register(ViPipe, 0xB5, 0x4C); + k06_write_register(ViPipe, 0xB1, 0x00); + k06_write_register(ViPipe, 0xA1, 0x0F); + k06_write_register(ViPipe, 0xA3, 0x40); + k06_write_register(ViPipe, 0x49, 0x10); + k06_write_register(ViPipe, 0x8C, 0xFF); + k06_write_register(ViPipe, 0x8E, 0x00); + k06_write_register(ViPipe, 0x8B, 0x01); + k06_write_register(ViPipe, 0xBC, 0x11); + k06_write_register(ViPipe, 0x82, 0x00); + k06_write_register(ViPipe, 0x9F, 0x50); + k06_write_register(ViPipe, 0x19, 0x20); + k06_write_register(ViPipe, 0x1B, 0x4F); + + k06_default_reg_init(ViPipe); +// k06_write_register(ViPipe, 0x12, 0x00); + k06_write_register(ViPipe, 0x12, 0x30); + k06_write_register(ViPipe, 0x48, 0x86); + k06_write_register(ViPipe, 0x48, 0x06); + printf("ViPipe:%d,===K06 1440P 25fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_q03/Makefile b/middleware/v2/component/isp/sensor/cv181x/soi_q03/Makefile new file mode 100644 index 000000000..16b0c3f0c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_q03/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_q03.a +TARGET_SO = $(MW_LIB)/libsns_q03.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_q03/q03_cmos.c b/middleware/v2/component/isp/sensor/cv181x/soi_q03/q03_cmos.c new file mode 100644 index 000000000..d661e2724 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_q03/q03_cmos.c @@ -0,0 +1,848 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "q03_cmos_ex.h" +#include "q03_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define Q03_ID 03 +#define Q03_I2C_ADDR_1 0x40 +#define Q03_I2C_ADDR_2 0x42 +#define Q03_I2C_ADDR_3 0x44 +#define Q03_I2C_ADDR_4 0x46 +#define Q03_I2C_ADDR_IS_VALID(addr) ((addr) == Q03_I2C_ADDR_1 || (addr) == Q03_I2C_ADDR_2 \ + || (addr) == Q03_I2C_ADDR_3 || (addr) == Q03_I2C_ADDR_4) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastQ03[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define Q03_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastQ03[dev]) +#define Q03_SENSOR_SET_CTX(dev, pstCtx) (g_pastQ03[dev] = pstCtx) +#define Q03_SENSOR_RESET_CTX(dev) (g_pastQ03[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunQ03_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Q03_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Q03_L2SMode[VI_MAX_PIPE_NUM] = {0}; +//Q03_STATE_S g_astQ03_State[VI_MAX_PIPE_NUM] = {{0}}; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeQ03_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Q03 Lines Range*****/ +#define Q03_FULL_LINES_MAX (0xFFFF) + +/*****F35 Register Address*****/ +#define Q03_SHS1_ADDR 0x01 +#define Q03_GAIN_ADDR 0x00 +#define Q03_VMAX_ADDR 0x22 +#define Q03_TABLE_END 0xff + +#define Q03_RES_IS_1296P(w, h) ((w) <= 2304 && (h) <= 1296) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const Q03_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astQ03_mode[pstSnsState->u8ImgMode]; +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = Q03_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 2; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_DB; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 0; + pstAeSnsDft->enBlcType = AE_BLC_TYPE_LADDER; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = pstMode->f32MaxFps; + pstAeSnsDft->f32MinFps = pstMode->f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max; + pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max; + pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + pstAeSnsDft->u32AEResponseFrame = 4; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astQ03_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astQ03_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astQ03_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case Q03_MODE_1296P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > Q03_FULL_LINES_MAX) ? Q03_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + pstSnsState->u32FLStd = u32VMAX; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_DATA].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_DATA].u32Data = ((u32VMAX & 0xFF00) >> 8); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 5; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if ((u32IntTime[0] + 5) > pstSnsState->au32FL[0]) { + CVI_TRACE_SNS(CVI_DBG_ERR, "inttime over spec [%u, %u]\n", + u32IntTime[0], + pstSnsState->au32FL[0]); + return CVI_FAILURE; + } + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_DATA].u32Data = (u32IntTime[0] & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_DATA].u32Data = ((u32IntTime[0] & 0xFF00) >> 8); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[64] = { + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, 2176, 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, + 3328, 3456, 3584, 3712, 3840, 3968, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8704, 9216, 9728, + 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, + 15872 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[63]) { + *pu32AgainLin = gain_table[63]; + *pu32AgainDb = 63; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + *pu32DgainLin = 1024; + *pu32DgainDb = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + u32Again = pu32Again[0]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_DATA].u32Data = (u32Again & 0xFF); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const Q03_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astQ03_mode[pstSnsState->u8ImgMode]; + + + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = Q03_MODE_1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astQ03_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2) +{ + if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance) + goto _mismatch; + if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length) + goto _mismatch; + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunQ03_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = q03_i2c_addr; + pstI2c_data[i].u32AddrByteNum = q03_addr_byte; + pstI2c_data[i].u32DataByteNum = q03_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_DATA].u32RegAddr = Q03_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1_DATA].u32RegAddr = Q03_SHS1_ADDR + 1; + pstI2c_data[LINEAR_AGAIN_DATA].u32RegAddr = Q03_GAIN_ADDR; + pstI2c_data[LINEAR_VMAX_0_DATA].u32RegAddr = Q03_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_0_DATA].u8DelayFrmNum = 2; + pstI2c_data[LINEAR_VMAX_1_DATA].u32RegAddr = Q03_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_1_DATA].u8DelayFrmNum = 2; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode); + return CVI_FAILURE; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + /* check update cif wdr manual or not */ + pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (Q03_RES_IS_1296P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = Q03_MODE_1296P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeQ03_MirrorFip[ViPipe] != eSnsMirrorFlip) { + q03_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeQ03_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const Q03_MODE_S *pstMode = CVI_NULL; + + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = Q03_MODE_1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astQ03_mode[pstSnsState->u8ImgMode]; + pstSnsState->u32FLStd = pstMode->u32VtsDef; + pstSnsState->au32FL[0] = pstMode->u32VtsDef; + pstSnsState->au32FL[1] = pstMode->u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + Q03_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &q03_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astQ03_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astQ03_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &q03_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = q03_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = q03_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (Q03_I2C_ADDR_IS_VALID(s32I2cAddr)) + q03_i2c_addr = s32I2cAddr; +} + +static CVI_S32 q03_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunQ03_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + Q03_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + Q03_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + Q03_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + Q03_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = Q03_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, Q03_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, Q03_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, Q03_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Q03_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Q03_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsQ03_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = q03_standby, + .pfnRestart = q03_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = q03_write_register, + .pfnReadReg = q03_read_register, + .pfnSetBusInfo = q03_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = q03_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_q03/q03_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/soi_q03/q03_cmos_ex.h new file mode 100644 index 000000000..05a431c19 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_q03/q03_cmos_ex.h @@ -0,0 +1,82 @@ +#ifndef __Q03_CMOS_EX_H_ +#define __Q03_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum q03_linear_regs_e { + LINEAR_SHS1_0_DATA, + LINEAR_SHS1_1_DATA, + LINEAR_AGAIN_DATA, + LINEAR_VMAX_0_DATA, + LINEAR_VMAX_1_DATA, + LINEAR_REGS_NUM +}; + +typedef enum _Q03_MODE_E { + Q03_MODE_1296P30 = 0, + Q03_MODE_LINEAR_NUM, + Q03_MODE_1296P30_WDR = Q03_MODE_LINEAR_NUM, + Q03_MODE_NUM +} Q03_MODE_E; + +typedef struct _Q03_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U8 u8DgainReg; + CVI_U32 u32L2S_MAX; + char name[64]; +} Q03_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastQ03[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunQ03_BusInfo[]; +extern CVI_U16 g_au16Q03_GainMode[]; +extern CVI_U16 g_au16Q03_L2SMode[]; +extern CVI_U8 q03_i2c_addr; +extern const CVI_U32 q03_addr_byte; +extern const CVI_U32 q03_data_byte; +extern void q03_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void q03_init(VI_PIPE ViPipe); +extern void q03_exit(VI_PIPE ViPipe); +extern void q03_standby(VI_PIPE ViPipe); +extern void q03_restart(VI_PIPE ViPipe); +extern int q03_write_register(VI_PIPE ViPipe, int addr, int data); +extern int q03_read_register(VI_PIPE ViPipe, int addr); +extern int q03_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __Q03_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_q03/q03_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/soi_q03/q03_cmos_param.h new file mode 100644 index 000000000..f64924528 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_q03/q03_cmos_param.h @@ -0,0 +1,122 @@ +#ifndef __Q03_CMOS_PARAM_H_ +#define __Q03_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "q03_cmos_ex.h" + +static const Q03_MODE_S g_astQ03_mode[Q03_MODE_NUM] = { + [Q03_MODE_1296P30] = { + .name = "1296p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2312, + .u32Height = 1296, + }, + .stWndRect = { + .s32X = 4, + .s32Y = 0, + .u32Width = 2304, + .u32Height = 1296, + }, + .stMaxSize = { + .u32Width = 2312, + .u32Height = 1296, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.61, /* 1350 * 30 / 0xFFFF */ + .u32HtsDef = 3600, + .u32VtsDef = 1350, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1350, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 1024, + .u16Def = 1024, + .u16Step = 1, + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {64, 64, 64, 64, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1040, 1040, 1040, 1040 +#endif + }, + .stAuto = { + {64, 64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + /*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, +#endif + }, + }, +}; + +struct combo_dev_attr_s q03_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {0, 1, 2, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __Q03_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/soi_q03/q03_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/soi_q03/q03_sensor_ctl.c new file mode 100644 index 000000000..5f340ff82 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/soi_q03/q03_sensor_ctl.c @@ -0,0 +1,348 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "q03_cmos_ex.h" + +#define Q03_CHIP_ID_HI_ADDR 0x0A +#define Q03_CHIP_ID_LO_ADDR 0x0B +#define Q03_CHIP_ID 0x0507 + +static void q03_linear_1296p30_init(VI_PIPE ViPipe); + +CVI_U8 q03_i2c_addr = 0x46; /* I2C Address of Q03 */ +const CVI_U32 q03_addr_byte = 1; +const CVI_U32 q03_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int q03_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunQ03_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, q03_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int q03_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int q03_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, q03_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + ret = read(g_fd[ViPipe], buf, q03_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (q03_data_byte == 1) { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int q03_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (q03_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + + if (q03_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, q03_addr_byte + q03_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void q03_standby(VI_PIPE ViPipe) +{ + q03_write_register(ViPipe, 0x12, 0x40); +} + +void q03_restart(VI_PIPE ViPipe) +{ + q03_write_register(ViPipe, 0x12, 0x40); + delay_ms(20); + q03_write_register(ViPipe, 0x12, 0x00); +} + +void q03_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastQ03[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + q03_write_register(ViPipe, + g_pastQ03[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastQ03[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void q03_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = q03_read_register(ViPipe, 0x12) & ~0x30; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x20; + break; + case ISP_SNS_FLIP: + val |= 0x10; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x30; + break; + default: + return; + } + + q03_write_register(ViPipe, 0x12, val); +} + +int q03_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + delay_ms(4); + if (q03_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = q03_read_register(ViPipe, Q03_CHIP_ID_HI_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id = (nVal & 0xFF) << 8; + nVal = q03_read_register(ViPipe, Q03_CHIP_ID_LO_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + chip_id |= (nVal & 0xFF); + + if (chip_id != Q03_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void q03_init(VI_PIPE ViPipe) +{ + q03_i2c_init(ViPipe); + + q03_linear_1296p30_init(ViPipe); + + g_pastQ03[ViPipe]->bInit = CVI_TRUE; +} + +void q03_exit(VI_PIPE ViPipe) +{ + q03_i2c_exit(ViPipe); +} + +static void q03_linear_1296p30_init(VI_PIPE ViPipe) +{ + q03_write_register(ViPipe, 0x12, 0x40); + q03_write_register(ViPipe, 0x48, 0x96); + q03_write_register(ViPipe, 0x48, 0x16); + q03_write_register(ViPipe, 0x0E, 0x11); + q03_write_register(ViPipe, 0x0F, 0x14); + q03_write_register(ViPipe, 0x10, 0x36); + q03_write_register(ViPipe, 0x11, 0x80); + q03_write_register(ViPipe, 0x0D, 0xB0); + q03_write_register(ViPipe, 0x5F, 0x42); + q03_write_register(ViPipe, 0x60, 0x2B); + q03_write_register(ViPipe, 0x58, 0x1A); + q03_write_register(ViPipe, 0x57, 0x60); + q03_write_register(ViPipe, 0x20, 0x84); + q03_write_register(ViPipe, 0x21, 0x03); + q03_write_register(ViPipe, 0x22, 0x46); + q03_write_register(ViPipe, 0x23, 0x05); + q03_write_register(ViPipe, 0x24, 0x42); + q03_write_register(ViPipe, 0x25, 0x10); + q03_write_register(ViPipe, 0x26, 0x52); + q03_write_register(ViPipe, 0x27, 0x53); + q03_write_register(ViPipe, 0x28, 0x15); + q03_write_register(ViPipe, 0x29, 0x03); + q03_write_register(ViPipe, 0x2A, 0x4E); + q03_write_register(ViPipe, 0x2B, 0x13); + q03_write_register(ViPipe, 0x2C, 0x00); + q03_write_register(ViPipe, 0x2D, 0x00); + q03_write_register(ViPipe, 0x2E, 0x4A); + q03_write_register(ViPipe, 0x2F, 0x64); + q03_write_register(ViPipe, 0x41, 0x8A); + q03_write_register(ViPipe, 0x42, 0x14); + q03_write_register(ViPipe, 0x47, 0x42); + q03_write_register(ViPipe, 0x76, 0x4A); + q03_write_register(ViPipe, 0x77, 0x0B); + q03_write_register(ViPipe, 0x80, 0x00); + q03_write_register(ViPipe, 0xAF, 0x22); + q03_write_register(ViPipe, 0xAB, 0x00); + q03_write_register(ViPipe, 0x46, 0x00); + q03_write_register(ViPipe, 0x1D, 0x00); + q03_write_register(ViPipe, 0x1E, 0x04); + q03_write_register(ViPipe, 0x6C, 0x40); + q03_write_register(ViPipe, 0x6E, 0x2C); + q03_write_register(ViPipe, 0x70, 0xD9); + q03_write_register(ViPipe, 0x71, 0xD0); + q03_write_register(ViPipe, 0x72, 0xD5); + q03_write_register(ViPipe, 0x73, 0x59); + q03_write_register(ViPipe, 0x74, 0x02); + q03_write_register(ViPipe, 0x78, 0x96); + q03_write_register(ViPipe, 0x89, 0x01); + q03_write_register(ViPipe, 0x6B, 0x20); + q03_write_register(ViPipe, 0x86, 0x40); + q03_write_register(ViPipe, 0x31, 0x0A); + q03_write_register(ViPipe, 0x32, 0x21); + q03_write_register(ViPipe, 0x33, 0x5C); + q03_write_register(ViPipe, 0x34, 0x44); + q03_write_register(ViPipe, 0x35, 0x40); + q03_write_register(ViPipe, 0x3A, 0xA0); + q03_write_register(ViPipe, 0x3B, 0x38); + q03_write_register(ViPipe, 0x3C, 0x50); + q03_write_register(ViPipe, 0x3D, 0x5B); + q03_write_register(ViPipe, 0x3E, 0xFF); + q03_write_register(ViPipe, 0x3F, 0x54); + q03_write_register(ViPipe, 0x40, 0xFF); + q03_write_register(ViPipe, 0x56, 0xB2); + q03_write_register(ViPipe, 0x59, 0x50); + q03_write_register(ViPipe, 0x5A, 0x04); + q03_write_register(ViPipe, 0x85, 0x34); + q03_write_register(ViPipe, 0x8A, 0x04); + q03_write_register(ViPipe, 0x91, 0x08); + q03_write_register(ViPipe, 0xA9, 0x08); + q03_write_register(ViPipe, 0x9C, 0xE1); + q03_write_register(ViPipe, 0x5B, 0xA0); + q03_write_register(ViPipe, 0x5C, 0x80); + q03_write_register(ViPipe, 0x5D, 0xEF); + q03_write_register(ViPipe, 0x5E, 0x14); + q03_write_register(ViPipe, 0x64, 0xE0); + q03_write_register(ViPipe, 0x66, 0x04); + q03_write_register(ViPipe, 0x67, 0x77); + q03_write_register(ViPipe, 0x68, 0x00); + q03_write_register(ViPipe, 0x69, 0x41); + q03_write_register(ViPipe, 0x7A, 0xA0); + q03_write_register(ViPipe, 0x8F, 0x91); + q03_write_register(ViPipe, 0x9D, 0x70); + q03_write_register(ViPipe, 0xAE, 0x30); + q03_write_register(ViPipe, 0x13, 0x81); + q03_write_register(ViPipe, 0x96, 0x04); + q03_write_register(ViPipe, 0x4A, 0x01); + q03_write_register(ViPipe, 0x7E, 0xC9); + q03_write_register(ViPipe, 0x50, 0x02); + q03_write_register(ViPipe, 0x49, 0x10); + q03_write_register(ViPipe, 0x7B, 0x4A); + q03_write_register(ViPipe, 0x7C, 0x0F); + q03_write_register(ViPipe, 0x7F, 0x57); + q03_write_register(ViPipe, 0x62, 0x21); + q03_write_register(ViPipe, 0x90, 0x00); + q03_write_register(ViPipe, 0x8C, 0xFF); + q03_write_register(ViPipe, 0x8D, 0xC7); + q03_write_register(ViPipe, 0x8E, 0x00); + q03_write_register(ViPipe, 0x8B, 0x01); + q03_write_register(ViPipe, 0x0C, 0x00); + q03_write_register(ViPipe, 0xBB, 0x11); + q03_write_register(ViPipe, 0x6A, 0x12); + q03_write_register(ViPipe, 0x65, 0x32); + q03_write_register(ViPipe, 0x82, 0x01); + q03_write_register(ViPipe, 0xA3, 0x20); + q03_write_register(ViPipe, 0xA0, 0x01); + q03_write_register(ViPipe, 0x81, 0x74); + q03_write_register(ViPipe, 0xA2, 0xFF); + q03_write_register(ViPipe, 0x19, 0x20); + + q03_default_reg_init(ViPipe); + + q03_write_register(ViPipe, 0x12, 0x00); + q03_write_register(ViPipe, 0x48, 0x96); + q03_write_register(ViPipe, 0x48, 0x16); + + printf("ViPipe:%d,===Q03 1296P 30fps 10bit LINE FPGA Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx307/Makefile b/middleware/v2/component/isp/sensor/cv181x/sony_imx307/Makefile new file mode 100644 index 000000000..e89c0e113 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx307/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx307.a +TARGET_SO = $(MW_LIB)/libsns_imx307.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx307/imx307_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx307/imx307_cmos.c new file mode 100644 index 000000000..19bf4d83d --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx307/imx307_cmos.c @@ -0,0 +1,1186 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_ae.h" +#include "cvi_isp.h" + +#include "imx307_cmos_ex.h" +#include "imx307_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX307_ID 307 +#define SENSOR_IMX307_WIDTH 1920 +#define SENSOR_IMX307_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx307[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX307_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx307[dev]) +#define IMX307_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx307[dev] = pstCtx) +#define IMX307_SENSOR_RESET_CTX(dev) (g_pastImx307[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunImx307_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx307_GainMode[VI_MAX_PIPE_NUM] = {0}; + +IMX307_STATE_S g_astImx307_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx307_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx307 Lines Range*****/ +#define IMX307_FULL_LINES_MAX (0x3FFFF) +#define IMX307_FULL_LINES_MAX_2TO1_WDR (0x3FFFF) // considering the YOUT_SIZE and bad frame +#define IMX307_VMAX_1080P30_LINEAR 1125 + +/*****Imx307 Register Address*****/ +#define IMX307_HOLD_ADDR 0x3001 +#define IMX307_SHS1_ADDR 0x3020 +#define IMX307_SHS2_ADDR 0x3024 +#define IMX307_GAIN_ADDR 0x3014 +#define IMX307_GAIN1_ADDR 0x30F2 +#define IMX307_HCG_ADDR 0x3009 +#define IMX307_VMAX_ADDR 0x3018 +#define IMX307_YOUT_ADDR 0x3418 +#define IMX307_RHS1_ADDR 0x3030 +#define IMX307_TABLE_END 0xffff + +#define IMX307_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX307_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->enWDRGainMode = SNS_GAIN_MODE_WDR_2F; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astImx307_mode[IMX307_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx307_mode[IMX307_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 45740; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astImx307_mode[IMX307_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx307_mode[IMX307_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 45740; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = IMX307_VMAX_1080P30_LINEAR; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astImx307_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx307_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx307_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case IMX307_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX307_FULL_LINES_MAX_2TO1_WDR) ? IMX307_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case IMX307_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX307_FULL_LINES_MAX) ? IMX307_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } else { + pstSnsRegsInfo->astI2cData[DOL2_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx307_State[ViPipe].u32RHS1_MAX = (u32VMAX - g_astImx307_State[ViPipe].u32BRL) * 2 - 21; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHS1 = 0; + CVI_U32 u32SHS2 = 0; + CVI_U32 u32YOUTSIZE; + CVI_U32 u16BRL = 0; + + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u16BRL = g_astImx307_mode[pstSnsState->u8ImgMode].u16BRL; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[0] < u32LongIntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], u32LongIntTime - 1); + return CVI_FAILURE; + } + u32SHS2 = pstSnsState->au32FL[0] - u32LongIntTime - 1; + + u32SHS1 = (u32ShortIntTime % 2) + 2; + u32RHS1 = u32ShortIntTime + u32SHS1 + 1; + g_astImx307_State[ViPipe].u32RHS1 = u32RHS1; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - (u32SHS1 + 1); + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[0] - (u32SHS2 + 1); + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + u32YOUTSIZE = (u16BRL + (u32RHS1 - 1) / 2) * 2; + u32YOUTSIZE = (u32YOUTSIZE >= 0x1FFF) ? 0x1FFF : u32YOUTSIZE; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHS1 = %d\n", u32ShortIntTime, u32SHS1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d u32YOUTSIZE = %d\n", ViPipe, u32RHS1, u32YOUTSIZE); + + pstSnsRegsInfo->astI2cData[DOL2_SHS1_0].u32Data = (u32SHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_1].u32Data = ((u32SHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_2].u32Data = ((u32SHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHS2_0].u32Data = (u32SHS2 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_1].u32Data = ((u32SHS2 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_2].u32Data = ((u32SHS2 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_0].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_1].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_2].u32Data = ((u32RHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_0].u32Data = (u32YOUTSIZE & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_1].u32Data = ((u32YOUTSIZE & 0x1F00) >> 8); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if (pstSnsState->au32FL[0] < *u32IntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], *u32IntTime - 1); + return CVI_FAILURE; + } + u32Value = pstSnsState->au32FL[0] - *u32IntTime - 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2].u32Data = ((u32Value & 0x30000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 327567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32HCG = g_astImx307_State[ViPipe].u8Hcg; + CVI_U32 u16Mode = g_au16Imx307_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 20) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 20; + } + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = (u32HCG & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + CVI_U8 bEnableHCG = 0; + + if (pu32Again[0] >= 20 && pu32Again[1] >= 20) { + /* hcg bit[4]*/ + u32HCG |= 0x10; + bEnableHCG = 1; + } + + u32Again = pu32Again[1] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + + u32Again = pu32Again[0] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN1].u32Data = (u32Tmp & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 20) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 20; + } + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 2 : 2; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 10; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx307_State[ViPipe].u32RHS1_MAX - 3)) ? + (g_astImx307_State[ViPipe].u32RHS1_MAX - 3) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} +#if 0 +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} +#endif +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX307_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx307_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX307_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = IMX307_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx307_mode[pstSnsState->u8ImgMode].u32VtsDef; + g_astImx307_State[ViPipe].u8Hcg = 0x2; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX307_MODE_1080P30) + pstSnsState->u8ImgMode = IMX307_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + g_astImx307_State[ViPipe].u8Hcg = 0x1; + if (pstSnsState->u8ImgMode == IMX307_MODE_1080P30_WDR) { + pstSnsState->u32FLStd = g_astImx307_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx307_State[ViPipe].u32BRL = g_astImx307_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1080p\n"); + } + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx307_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 2; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx307_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx307_addr_byte; + pstI2c_data[i].u32DataByteNum = imx307_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_HOLD].u32RegAddr = IMX307_HOLD_ADDR; + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_SHS1_0].u32RegAddr = IMX307_SHS1_ADDR; + pstI2c_data[DOL2_SHS1_1].u32RegAddr = IMX307_SHS1_ADDR + 1; + pstI2c_data[DOL2_SHS1_2].u32RegAddr = IMX307_SHS1_ADDR + 2; + + pstI2c_data[DOL2_GAIN].u32RegAddr = IMX307_GAIN_ADDR; + pstI2c_data[DOL2_HCG].u32RegAddr = IMX307_HCG_ADDR; + pstI2c_data[DOL2_HCG].u8DelayFrmNum = 1; + pstI2c_data[DOL2_GAIN1].u32RegAddr = IMX307_GAIN1_ADDR; + pstI2c_data[DOL2_RHS1_0].u32RegAddr = IMX307_RHS1_ADDR; + pstI2c_data[DOL2_RHS1_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_1].u32RegAddr = IMX307_RHS1_ADDR + 1; + pstI2c_data[DOL2_RHS1_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_2].u32RegAddr = IMX307_RHS1_ADDR + 2; + pstI2c_data[DOL2_RHS1_2].u8DelayFrmNum = 1; + pstI2c_data[DOL2_SHS2_0].u32RegAddr = IMX307_SHS2_ADDR; + pstI2c_data[DOL2_SHS2_1].u32RegAddr = IMX307_SHS2_ADDR + 1; + pstI2c_data[DOL2_SHS2_2].u32RegAddr = IMX307_SHS2_ADDR + 2; + pstI2c_data[DOL2_VMAX_0].u32RegAddr = IMX307_VMAX_ADDR; + pstI2c_data[DOL2_VMAX_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_1].u32RegAddr = IMX307_VMAX_ADDR + 1; + pstI2c_data[DOL2_VMAX_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_2].u32RegAddr = IMX307_VMAX_ADDR + 2; + pstI2c_data[DOL2_VMAX_2].u8DelayFrmNum = 1; + + pstI2c_data[DOL2_YOUT_SIZE_0].u32RegAddr = IMX307_YOUT_ADDR; + pstI2c_data[DOL2_YOUT_SIZE_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u32RegAddr = IMX307_YOUT_ADDR + 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_REL].u32RegAddr = IMX307_HOLD_ADDR; + pstI2c_data[DOL2_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 1; + break; + default: + pstI2c_data[LINEAR_HOLD].u32RegAddr = IMX307_HOLD_ADDR; + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_SHS1_0].u32RegAddr = IMX307_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1].u32RegAddr = IMX307_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2].u32RegAddr = IMX307_SHS1_ADDR + 2; + pstI2c_data[LINEAR_GAIN].u32RegAddr = IMX307_GAIN_ADDR; + pstI2c_data[LINEAR_HCG].u32RegAddr = IMX307_HCG_ADDR; + pstI2c_data[LINEAR_HCG].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VMAX_0].u32RegAddr = IMX307_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1].u32RegAddr = IMX307_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_2].u32RegAddr = IMX307_VMAX_ADDR + 2; + pstI2c_data[LINEAR_REL].u32RegAddr = IMX307_HOLD_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[DOL2_REL].u32Data = 0; + pstI2c_data[DOL2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX307_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX307_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX307_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX307_MODE_1080P30_WDR; + g_astImx307_State[ViPipe].u32BRL = 1109; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx307_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx307_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx307_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = IMX307_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = IMX307_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[0] = IMX307_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[1] = IMX307_VMAX_1080P30_LINEAR; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx307_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx307_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx307_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx307_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx307_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx307_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx307_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx307_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX307_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX307_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX307_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX307_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + //AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX307_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } +#if 0 + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stSnsExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } +#endif + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX307_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX307_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } +#if 0 + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX307_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } +#endif + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx307_GainMode[ViPipe] = SNS_GAIN_MODE_WDR_2F; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return imx307_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsImx307_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx307_standby, + .pfnRestart = imx307_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx307_write_register, + .pfnReadReg = imx307_read_register, + .pfnSetBusInfo = imx307_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx307/imx307_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx307/imx307_cmos_ex.h new file mode 100644 index 000000000..f1405f88c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx307/imx307_cmos_ex.h @@ -0,0 +1,124 @@ +#ifndef __IMX307_CMOS_EX_H_ +#define __IMX307_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +/* [TODO] ======== Temporarily definitions start ========*/ +typedef struct _AWB_SENSOR_DEFAULT_S { + CVI_U16 u16InitRgain; /*Init WB gain*/ + CVI_U16 u16InitGgain; + CVI_U16 u16InitBgain; + CVI_U8 u8AWBRunInterval; /*RW;AWB Run Interval*/ +} AWB_SENSOR_DEFAULT_S; + +/* [TODO] ======== Temporarily definitions end ========*/ +enum imx307_linear_regs_e { + LINEAR_HOLD = 0, + LINEAR_SHS1_0, + LINEAR_SHS1_1, + LINEAR_SHS1_2, + LINEAR_GAIN, + LINEAR_HCG, + LINEAR_VMAX_0, + LINEAR_VMAX_1, + LINEAR_VMAX_2, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum imx307_dol2_regs_e { + DOL2_HOLD = 0, + DOL2_SHS1_0, + DOL2_SHS1_1, + DOL2_SHS1_2, + DOL2_GAIN, + DOL2_HCG, + DOL2_GAIN1, + DOL2_RHS1_0, + DOL2_RHS1_1, + DOL2_RHS1_2, + DOL2_SHS2_0, + DOL2_SHS2_1, + DOL2_SHS2_2, + DOL2_VMAX_0, + DOL2_VMAX_1, + DOL2_VMAX_2, + DOL2_YOUT_SIZE_0, + DOL2_YOUT_SIZE_1, + DOL2_REL, + DOL2_REGS_NUM +}; + +typedef enum _IMX307_MODE_E { + IMX307_MODE_1080P30 = 0, + IMX307_MODE_LINEAR_NUM, + IMX307_MODE_1080P30_WDR = IMX307_MODE_LINEAR_NUM, + IMX307_MODE_NUM +} IMX307_MODE_E; + +typedef struct _IMX307_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX307_STATE_S; + +typedef struct _IMX307_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX307_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx307[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx307_BusInfo[]; +extern CVI_U16 g_au16Imx307_GainMode[]; +extern const CVI_U8 imx307_i2c_addr; +extern const CVI_U32 imx307_addr_byte; +extern const CVI_U32 imx307_data_byte; +extern void imx307_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void imx307_init(VI_PIPE ViPipe); +extern void imx307_exit(VI_PIPE ViPipe); +extern void imx307_standby(VI_PIPE ViPipe); +extern void imx307_restart(VI_PIPE ViPipe); +extern int imx307_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx307_read_register(VI_PIPE ViPipe, int addr); +extern int imx307_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX307_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx307/imx307_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx307/imx307_cmos_param.h new file mode 100644 index 000000000..967cebe99 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx307/imx307_cmos_param.h @@ -0,0 +1,308 @@ +#ifndef __IMX307_CMOS_PARAM_H_ +#define __IMX307_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx307_cmos_ex.h" + +static const IMX307_MODE_S g_astImx307_mode[IMX307_MODE_NUM] = { + [IMX307_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x1130, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX307_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 8, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 2236, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 7, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.03396590426564216614, 2.31280159950256347656}, //B: slope, intercept + {0.02877708896994590759, 1.99502599239349365234}, //Gb: slope, intercept + {0.02853375114500522614, 1.53825533390045166016}, //Gr: slope, intercept + {0.02940983884036540985, 2.40369534492492675781}, //R: slope, intercept + }, + { //iso 200 + {0.03635194525122642517, 5.70069074630737304688}, //B: slope, intercept + {0.02990435808897018433, 6.70210981369018554688}, //Gb: slope, intercept + {0.03183263540267944336, 4.92136955261230468750}, //Gr: slope, intercept + {0.03145531564950942993, 5.97894525527954101563}, //R: slope, intercept + }, + { //iso 400 + {0.04329251870512962341, 7.09708356857299804688}, //B: slope, intercept + {0.03147880360484123230, 11.36076831817626953125}, //Gb: slope, intercept + {0.03299136087298393250, 8.49763488769531250000}, //Gr: slope, intercept + {0.03585162013769149780, 8.31188583374023437500}, //R: slope, intercept + }, + { //iso 800 + {0.05740678682923316956, 10.93907737731933593750}, //B: slope, intercept + {0.03538244962692260742, 21.53132820129394531250}, //Gb: slope, intercept + {0.04014955088496208191, 14.56391811370849609375}, //Gr: slope, intercept + {0.03907874971628189087, 15.16305541992187500000}, //R: slope, intercept + }, + { //iso 1600 + {0.05417122691869735718, 23.33716773986816406250}, //B: slope, intercept + {0.02816017158329486847, 55.33533859252929687500}, //Gb: slope, intercept + {0.03809726238250732422, 30.80285072326660156250}, //Gr: slope, intercept + {0.04028835147619247437, 31.24934768676757812500}, //R: slope, intercept + }, + { //iso 3200 + {0.07438381761312484741, 33.81318664550781250000}, //B: slope, intercept + {0.02690842747688293457, 95.65101623535156250000}, //Gb: slope, intercept + {0.05132644250988960266, 46.27661132812500000000}, //Gr: slope, intercept + {0.05343631654977798462, 44.67097473144531250000}, //R: slope, intercept + }, + { //iso 6400 + {0.10831451416015625000, 49.42535018920898437500}, //B: slope, intercept + {0.04577258601784706116, 122.51580810546875000000}, //Gb: slope, intercept + {0.06677398085594177246, 69.54801177978515625000}, //Gr: slope, intercept + {0.07670628279447555542, 63.47140884399414062500}, //R: slope, intercept + }, + { //iso 12800 + {0.15062870085239410400, 68.36373138427734375000}, //B: slope, intercept + {0.07762257009744644165, 146.30807495117187500000}, //Gb: slope, intercept + {0.09608269482851028442, 96.59751892089843750000}, //Gr: slope, intercept + {0.10346080362796783447, 96.64923095703125000000}, //R: slope, intercept + }, + { //iso 25600 + {0.21278673410415649414, 107.37140655517578125000}, //B: slope, intercept + {0.12505164742469787598, 179.24717712402343750000}, //Gb: slope, intercept + {0.14927712082862854004, 140.71289062500000000000}, //Gr: slope, intercept + {0.15530782938003540039, 139.79985046386718750000}, //R: slope, intercept + }, + { //iso 51200 + {0.32940942049026489258, 149.26779174804687500000}, //B: slope, intercept + {0.18958723545074462891, 247.18806457519531250000}, //Gb: slope, intercept + {0.19027391076087951660, 230.56108093261718750000}, //Gr: slope, intercept + {0.23455394804477691650, 192.10685729980468750000}, //R: slope, intercept + }, + { //iso 102400 + {0.48793542385101318359, 210.41285705566406250000}, //B: slope, intercept + {0.24973315000534057617, 372.87121582031250000000}, //Gb: slope, intercept + {0.23015110194683074951, 402.12283325195312500000}, //Gr: slope, intercept + {0.35159105062484741211, 294.27154541015625000000}, //R: slope, intercept + }, + { //iso 204800 + {0.60629695653915405273, 340.77212524414062500000}, //B: slope, intercept + {0.39248645305633544922, 481.49472045898437500000}, //Gb: slope, intercept + {0.33751612901687622070, 544.22698974609375000000}, //Gr: slope, intercept + {0.43583938479423522949, 458.90490722656250000000}, //R: slope, intercept + }, + { //iso 409600 + {0.71151763200759887695, 544.37280273437500000000}, //B: slope, intercept + {0.47628879547119140625, 697.04498291015625000000}, //Gb: slope, intercept + {0.38568580150604248047, 794.64263916015625000000}, //Gr: slope, intercept + {0.54425776004791259766, 658.77343750000000000000}, //R: slope, intercept + }, + { //iso 819200 + {0.61085152626037597656, 821.67352294921875000000}, //B: slope, intercept + {0.38012877106666564941, 1050.61950683593750000000}, //Gb: slope, intercept + {0.38677954673767089844, 1049.79968261718750000000}, //Gr: slope, intercept + {0.54386067390441894531, 875.86968994140625000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.88969016075134277344, 635.22283935546875000000}, //B: slope, intercept + {0.71133875846862792969, 754.16796875000000000000}, //Gb: slope, intercept + {0.66038286685943603516, 765.11163330078125000000}, //Gr: slope, intercept + {0.61520493030548095703, 817.94128417968750000000}, //R: slope, intercept + }, + { //iso 3276800 + {1.43259191513061523438, 263.03683471679687500000}, //B: slope, intercept + {0.87281060218811035156, 624.04595947265625000000}, //Gb: slope, intercept + {0.81407910585403442383, 666.59527587890625000000}, //Gr: slope, intercept + {0.87593811750411987305, 608.70275878906250000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {239, 239, 239, 239, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1087, 1087, 1087, 1087 +#endif + }, + .stAuto = { + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/243, 252, 290, 395, 681, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1228, 1365, 1365, 1365}, +#endif + }, + }, +}; + +struct combo_dev_attr_s imx307_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {2, 3, 1, 4, 0}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_DOL, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX307_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx307/imx307_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx307/imx307_sensor_ctl.c new file mode 100644 index 000000000..c76af0526 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx307/imx307_sensor_ctl.c @@ -0,0 +1,416 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx307_cmos_ex.h" + +static void imx307_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void imx307_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 imx307_i2c_addr = 0x1A; +const CVI_U32 imx307_addr_byte = 2; +const CVI_U32 imx307_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx307_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx307_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx307_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int imx307_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx307_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (imx307_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, imx307_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, imx307_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (imx307_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int imx307_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx307_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx307_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx307_addr_byte + imx307_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx307_standby(VI_PIPE ViPipe) +{ + imx307_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx307_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ +} + +void imx307_restart(VI_PIPE ViPipe) +{ + imx307_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx307_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx307_write_register(ViPipe, 0x304b, 0x0a); +} + +void imx307_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx307[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx307_write_register(ViPipe, + g_pastImx307[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx307[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define IMX307_CHIP_ID_ADDR 0x31dc +#define IMX307_CHIP_ID 0x4 +#define IMX307_CHIP_ID_MASK 0x6 + +void imx307_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = imx307_read_register(ViPipe, 0x3007) & ~0x3; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + imx307_write_register(ViPipe, 0x3007, val); +} + +int imx307_probe(VI_PIPE ViPipe) +{ + int nVal; + + usleep(100); + if (imx307_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = imx307_read_register(ViPipe, IMX307_CHIP_ID_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((nVal & IMX307_CHIP_ID_MASK) != IMX307_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void imx307_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastImx307[ViPipe]->enWDRMode; + u8ImgMode = g_pastImx307[ViPipe]->u8ImgMode; + + imx307_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == IMX307_MODE_1080P30_WDR) { + imx307_wdr_1080p30_2to1_init(ViPipe); + } + } else { + imx307_linear_1080p30_init(ViPipe); + } + g_pastImx307[ViPipe]->bInit = CVI_TRUE; +} + +void imx307_exit(VI_PIPE ViPipe) +{ + imx307_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void imx307_linear_1080p30_init(VI_PIPE ViPipe) +{ + imx307_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx307_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx307_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx307_write_register(ViPipe, 0x3005, 0x01); /* ADBIT 10bit*/ + imx307_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx307_write_register(ViPipe, 0x3009, 0x02); /**/ + imx307_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx307_write_register(ViPipe, 0x3010, 0x21); + imx307_write_register(ViPipe, 0x3011, 0x0A); + imx307_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx307_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx307_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx307_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx307_write_register(ViPipe, 0x301C, 0x30); /* HMAX[7:0], TBD*/ + imx307_write_register(ViPipe, 0x301D, 0x11); /* HMAX[15:8]*/ + imx307_write_register(ViPipe, 0x3020, 0x8C); /* SHS[7:0], TBD*/ + imx307_write_register(ViPipe, 0x3021, 0x01); /* SHS[15:8]*/ + imx307_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx307_write_register(ViPipe, 0x3046, 0x01); + imx307_write_register(ViPipe, 0x304B, 0x0A); + imx307_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx307_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx307_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx307_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx307_write_register(ViPipe, 0x309E, 0x4A); + imx307_write_register(ViPipe, 0x309F, 0x4A); + imx307_write_register(ViPipe, 0x311C, 0x0E); + imx307_write_register(ViPipe, 0x3128, 0x04); + imx307_write_register(ViPipe, 0x3129, 0x00); + imx307_write_register(ViPipe, 0x313B, 0x41); + imx307_write_register(ViPipe, 0x315E, 0x1A); + imx307_write_register(ViPipe, 0x3164, 0x1A); + imx307_write_register(ViPipe, 0x317C, 0x00); + imx307_write_register(ViPipe, 0x31EC, 0x0E); + imx307_write_register(ViPipe, 0x3405, 0x20); /* Repetition*/ + imx307_write_register(ViPipe, 0x3407, 0x03); /* physical_lane_nl*/ + imx307_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx307_write_register(ViPipe, 0x3418, 0x49); /* y_out_size*/ + imx307_write_register(ViPipe, 0x3419, 0x04); /* y_out_size*/ + imx307_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx307_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx307_write_register(ViPipe, 0x3443, 0x03); /* csi_lane_mode*/ + imx307_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx307_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx307_write_register(ViPipe, 0x3446, 0x47); /* tclkpost*/ + imx307_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx307_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx307_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx307_write_register(ViPipe, 0x344A, 0x17); /* thsprepare*/ + imx307_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx307_write_register(ViPipe, 0x344C, 0x0F); /* tclktrail*/ + imx307_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx307_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx307_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx307_write_register(ViPipe, 0x3450, 0x47); /* tclkzero*/ + imx307_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx307_write_register(ViPipe, 0x3452, 0x0F); /* tclkprepare*/ + imx307_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx307_write_register(ViPipe, 0x3454, 0x0F); /* tlpx*/ + imx307_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx307_write_register(ViPipe, 0x3472, 0x9C); /* x_out_size*/ + imx307_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx307_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx307_default_reg_init(ViPipe); + + imx307_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx307_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx307_write_register(ViPipe, 0x304b, 0x0a); + + printf("ViPipe:%d,===IMX307 1080P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void imx307_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + imx307_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx307_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx307_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx307_write_register(ViPipe, 0x3005, 0x01); /* ADBIT*/ + imx307_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx307_write_register(ViPipe, 0x3009, 0x01); /**/ + imx307_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx307_write_register(ViPipe, 0x300C, 0x11); /* WDMODE [0] 0:Normal, 1:DOL, WDSEL [5:4] 1:DOL 2 frames*/ + imx307_write_register(ViPipe, 0x3011, 0x0A); + imx307_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx307_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx307_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx307_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx307_write_register(ViPipe, 0x301C, 0x98); /* HMAX[7:0], TBD*/ + imx307_write_register(ViPipe, 0x301D, 0x08); /* HMAX[15:8]*/ + imx307_write_register(ViPipe, 0x3020, 0x02); /* SHS[7:0], TBD*/ + imx307_write_register(ViPipe, 0x3021, 0x00); /* SHS[15:8]*/ + imx307_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx307_write_register(ViPipe, 0x3024, 0xC9); /* SHS2[7:0], TBD*/ + imx307_write_register(ViPipe, 0x3025, 0x07); /* SHS2[15:8]*/ + imx307_write_register(ViPipe, 0x3026, 0x00); /* SHS2[19:16]*/ + imx307_write_register(ViPipe, 0x3030, 0x0B); /* RHS1[7:0], TBD*/ + imx307_write_register(ViPipe, 0x3031, 0x00); /* RHS1[15:8]*/ + imx307_write_register(ViPipe, 0x3032, 0x00); /* RHS1[19:16]*/ + imx307_write_register(ViPipe, 0x3045, 0x05); /* DOLSCDEN [0] 1: pattern1 0: pattern2*/ + imx307_write_register(ViPipe, 0x3046, 0x01); + imx307_write_register(ViPipe, 0x304B, 0x0A); + imx307_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx307_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx307_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx307_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx307_write_register(ViPipe, 0x309E, 0x4A); + imx307_write_register(ViPipe, 0x309F, 0x4A); + imx307_write_register(ViPipe, 0x3106, 0x11); /*DOLHBFIXEN[7] 0: pattern1 1: pattern2*/ + imx307_write_register(ViPipe, 0x311C, 0x0E); + imx307_write_register(ViPipe, 0x3128, 0x04); + imx307_write_register(ViPipe, 0x3129, 0x00); + imx307_write_register(ViPipe, 0x313B, 0x41); + imx307_write_register(ViPipe, 0x315E, 0x1A); + imx307_write_register(ViPipe, 0x3164, 0x1A); + imx307_write_register(ViPipe, 0x317C, 0x00); + imx307_write_register(ViPipe, 0x31EC, 0x0E); + imx307_write_register(ViPipe, 0x3405, 0x10); /* Repetition*/ + imx307_write_register(ViPipe, 0x3407, 0x03); /* physical_lane_nl*/ + imx307_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx307_write_register(ViPipe, 0x3415, 0x00); /* NULL0_SIZE_V, set to 00h when DOL*/ + imx307_write_register(ViPipe, 0x3418, 0xB4); /* y_out_size*/ + imx307_write_register(ViPipe, 0x3419, 0x08); /* y_out_size*/ + imx307_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx307_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx307_write_register(ViPipe, 0x3443, 0x03); /* csi_lane_mode*/ + imx307_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx307_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx307_write_register(ViPipe, 0x3446, 0x57); /* tclkpost*/ + imx307_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx307_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx307_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx307_write_register(ViPipe, 0x344A, 0x1F); /* thsprepare*/ + imx307_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx307_write_register(ViPipe, 0x344C, 0x1F); /* tclktrail*/ + imx307_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx307_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx307_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx307_write_register(ViPipe, 0x3450, 0x77); /* tclkzero*/ + imx307_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx307_write_register(ViPipe, 0x3452, 0x1F); /* tclkprepare*/ + imx307_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx307_write_register(ViPipe, 0x3454, 0x17); /* tlpx*/ + imx307_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx307_write_register(ViPipe, 0x3472, 0xA0); /* x_out_size*/ + imx307_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx307_write_register(ViPipe, 0x347B, 0x23); /**/ + imx307_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx307_default_reg_init(ViPipe); + + if (g_au16Imx307_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + imx307_write_register(ViPipe, 0x30F0, 0xF0); + imx307_write_register(ViPipe, 0x3010, 0x21); + } else { + imx307_write_register(ViPipe, 0x30F0, 0x64); + imx307_write_register(ViPipe, 0x3010, 0x61); + } + + imx307_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx307_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx307_write_register(ViPipe, 0x304b, 0x0a); + + printf("===Imx307 sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx307_2L/Makefile b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_2L/Makefile new file mode 100644 index 000000000..304509b36 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_2L/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx307_2l.a +TARGET_SO = $(MW_LIB)/libsns_imx307_2l.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx307_2L/imx307_2l_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_2L/imx307_2l_cmos.c new file mode 100644 index 000000000..4ea605bc1 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_2L/imx307_2l_cmos.c @@ -0,0 +1,1181 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_ae.h" +#include "cvi_isp.h" + +#include "imx307_2l_cmos_ex.h" +#include "imx307_2l_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX307_2L_ID 307 +#define SENSOR_IMX307_2L_WIDTH 1920 +#define SENSOR_IMX307_2L_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx307_2l[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX307_2L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx307_2l[dev]) +#define IMX307_2L_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx307_2l[dev] = pstCtx) +#define IMX307_2L_SENSOR_RESET_CTX(dev) (g_pastImx307_2l[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunImx307_2l_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx307_2l_GainMode[VI_MAX_PIPE_NUM] = {0}; + +IMX307_2L_STATE_S g_astImx307_2l_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx307_2l_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx307 Lines Range*****/ +#define IMX307_2L_FULL_LINES_MAX (0x3FFFF) +#define IMX307_2L_FULL_LINES_MAX_2TO1_WDR (0x3FFFF) // considering the YOUT_SIZE and bad frame +#define IMX307_2L_VMAX_1080P30_LINEAR 1125 + +/*****Imx307 Register Address*****/ +#define IMX307_2L_HOLD_ADDR 0x3001 +#define IMX307_2L_SHS1_ADDR 0x3020 +#define IMX307_2L_SHS2_ADDR 0x3024 +#define IMX307_2L_GAIN_ADDR 0x3014 +#define IMX307_2L_GAIN1_ADDR 0x30F2 +#define IMX307_2L_HCG_ADDR 0x3009 +#define IMX307_2L_VMAX_ADDR 0x3018 +#define IMX307_2L_YOUT_ADDR 0x3418 +#define IMX307_2L_RHS1_ADDR 0x3030 +#define IMX307_2L_TABLE_END 0xffff + +#define IMX307_2L_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX307_2L_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astImx307_2l_mode[IMX307_2L_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx307_2l_mode[IMX307_2L_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 45740; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astImx307_2l_mode[IMX307_2L_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx307_2l_mode[IMX307_2L_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 45740; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = IMX307_2L_VMAX_1080P30_LINEAR; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astImx307_2l_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx307_2l_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx307_2l_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case IMX307_2L_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX307_2L_FULL_LINES_MAX_2TO1_WDR) ? IMX307_2L_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case IMX307_2L_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX307_2L_FULL_LINES_MAX) ? IMX307_2L_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } else { + pstSnsRegsInfo->astI2cData[DOL2_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx307_2l_State[ViPipe].u32RHS1_MAX = (u32VMAX - g_astImx307_2l_State[ViPipe].u32BRL) * 2 - 21; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHS1 = 0; + CVI_U32 u32SHS2 = 0; + CVI_U32 u32YOUTSIZE; + CVI_U32 u16BRL = 0; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u16BRL = g_astImx307_2l_mode[pstSnsState->u8ImgMode].u16BRL; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[0] < u32LongIntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], u32LongIntTime - 1); + return CVI_FAILURE; + } + u32SHS2 = pstSnsState->au32FL[0] - u32LongIntTime - 1; + + u32SHS1 = (u32ShortIntTime % 2) + 2; + u32RHS1 = u32ShortIntTime + u32SHS1 + 1; + g_astImx307_2l_State[ViPipe].u32RHS1 = u32RHS1; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - (u32SHS1 + 1); + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[0] - (u32SHS2 + 1); + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + u32YOUTSIZE = (u16BRL + (u32RHS1 - 1) / 2) * 2; + u32YOUTSIZE = (u32YOUTSIZE >= 0x1FFF) ? 0x1FFF : u32YOUTSIZE; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHS1 = %d\n", u32ShortIntTime, u32SHS1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d u32YOUTSIZE = %d\n", ViPipe, u32RHS1, u32YOUTSIZE); + + pstSnsRegsInfo->astI2cData[DOL2_SHS1_0].u32Data = (u32SHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_1].u32Data = ((u32SHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_2].u32Data = ((u32SHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHS2_0].u32Data = (u32SHS2 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_1].u32Data = ((u32SHS2 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_2].u32Data = ((u32SHS2 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_0].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_1].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_2].u32Data = ((u32RHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_0].u32Data = (u32YOUTSIZE & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_1].u32Data = ((u32YOUTSIZE & 0x1F00) >> 8); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if (pstSnsState->au32FL[0] < *u32IntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], *u32IntTime - 1); + return CVI_FAILURE; + } + u32Value = pstSnsState->au32FL[0] - *u32IntTime - 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2].u32Data = ((u32Value & 0x30000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 327567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32HCG = g_astImx307_2l_State[ViPipe].u8Hcg; + CVI_U32 u16Mode = g_au16Imx307_2l_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 20) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 20; + } + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = (u32HCG & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + CVI_U8 bEnableHCG = 0; + + if (pu32Again[0] >= 20 && pu32Again[1] >= 20) { + /* hcg bit[4]*/ + u32HCG |= 0x10; + bEnableHCG = 1; + } + + u32Again = pu32Again[1] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + + u32Again = pu32Again[0] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN1].u32Data = (u32Tmp & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 20) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 20; + } + + u32Tmp = u32Again + u32Dgain; + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 2 : 2; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 10; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx307_2l_State[ViPipe].u32RHS1_MAX - 3)) ? + (g_astImx307_2l_State[ViPipe].u32RHS1_MAX - 3) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} +#if 0 +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} +#endif +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX307_2L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx307_2l_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX307_2L_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = IMX307_2L_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx307_2l_mode[pstSnsState->u8ImgMode].u32VtsDef; + g_astImx307_2l_State[ViPipe].u8Hcg = 0x2; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX307_2L_MODE_1080P30) + pstSnsState->u8ImgMode = IMX307_2L_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + g_astImx307_2l_State[ViPipe].u8Hcg = 0x1; + if (pstSnsState->u8ImgMode == IMX307_2L_MODE_1080P30_WDR) { + pstSnsState->u32FLStd = g_astImx307_2l_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx307_2l_State[ViPipe].u32BRL = g_astImx307_2l_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1080p\n"); + } + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx307_2l_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 2; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx307_2l_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx307_2l_addr_byte; + pstI2c_data[i].u32DataByteNum = imx307_2l_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_HOLD].u32RegAddr = IMX307_2L_HOLD_ADDR; + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_SHS1_0].u32RegAddr = IMX307_2L_SHS1_ADDR; + pstI2c_data[DOL2_SHS1_1].u32RegAddr = IMX307_2L_SHS1_ADDR + 1; + pstI2c_data[DOL2_SHS1_2].u32RegAddr = IMX307_2L_SHS1_ADDR + 2; + + pstI2c_data[DOL2_GAIN].u32RegAddr = IMX307_2L_GAIN_ADDR; + pstI2c_data[DOL2_HCG].u32RegAddr = IMX307_2L_HCG_ADDR; + pstI2c_data[DOL2_HCG].u8DelayFrmNum = 1; + pstI2c_data[DOL2_GAIN1].u32RegAddr = IMX307_2L_GAIN1_ADDR; + pstI2c_data[DOL2_RHS1_0].u32RegAddr = IMX307_2L_RHS1_ADDR; + pstI2c_data[DOL2_RHS1_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_1].u32RegAddr = IMX307_2L_RHS1_ADDR + 1; + pstI2c_data[DOL2_RHS1_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_2].u32RegAddr = IMX307_2L_RHS1_ADDR + 2; + pstI2c_data[DOL2_RHS1_2].u8DelayFrmNum = 1; + pstI2c_data[DOL2_SHS2_0].u32RegAddr = IMX307_2L_SHS2_ADDR; + pstI2c_data[DOL2_SHS2_1].u32RegAddr = IMX307_2L_SHS2_ADDR + 1; + pstI2c_data[DOL2_SHS2_2].u32RegAddr = IMX307_2L_SHS2_ADDR + 2; + pstI2c_data[DOL2_VMAX_0].u32RegAddr = IMX307_2L_VMAX_ADDR; + pstI2c_data[DOL2_VMAX_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_1].u32RegAddr = IMX307_2L_VMAX_ADDR + 1; + pstI2c_data[DOL2_VMAX_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_2].u32RegAddr = IMX307_2L_VMAX_ADDR + 2; + pstI2c_data[DOL2_VMAX_2].u8DelayFrmNum = 1; + + pstI2c_data[DOL2_YOUT_SIZE_0].u32RegAddr = IMX307_2L_YOUT_ADDR; + pstI2c_data[DOL2_YOUT_SIZE_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u32RegAddr = IMX307_2L_YOUT_ADDR + 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_REL].u32RegAddr = IMX307_2L_HOLD_ADDR; + pstI2c_data[DOL2_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 1; + break; + default: + pstI2c_data[LINEAR_HOLD].u32RegAddr = IMX307_2L_HOLD_ADDR; + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_SHS1_0].u32RegAddr = IMX307_2L_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1].u32RegAddr = IMX307_2L_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2].u32RegAddr = IMX307_2L_SHS1_ADDR + 2; + pstI2c_data[LINEAR_GAIN].u32RegAddr = IMX307_2L_GAIN_ADDR; + pstI2c_data[LINEAR_HCG].u32RegAddr = IMX307_2L_HCG_ADDR; + pstI2c_data[LINEAR_HCG].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VMAX_0].u32RegAddr = IMX307_2L_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1].u32RegAddr = IMX307_2L_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_2].u32RegAddr = IMX307_2L_VMAX_ADDR + 2; + pstI2c_data[LINEAR_REL].u32RegAddr = IMX307_2L_HOLD_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[DOL2_REL].u32Data = 0; + pstI2c_data[DOL2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX307_2L_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX307_2L_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX307_2L_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX307_2L_MODE_1080P30_WDR; + g_astImx307_2l_State[ViPipe].u32BRL = 1109; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx307_2l_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx307_2l_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx307_2l_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = IMX307_2L_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = IMX307_2L_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[0] = IMX307_2L_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[1] = IMX307_2L_VMAX_1080P30_LINEAR; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx307_2l_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx307_2l_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx307_2l_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx307_2l_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx307_2l_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx307_2l_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx307_2l_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx307_2l_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX307_2L_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX307_2L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX307_2L_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + //AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX307_2L_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } +#if 0 + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stSnsExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } +#endif + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX307_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX307_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } +#if 0 + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX307_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } +#endif + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx307_2l_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return imx307_2l_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsImx307_2l_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx307_2l_standby, + .pfnRestart = imx307_2l_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx307_2l_write_register, + .pfnReadReg = imx307_2l_read_register, + .pfnSetBusInfo = imx307_2l_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx307_2L/imx307_2l_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_2L/imx307_2l_cmos_ex.h new file mode 100644 index 000000000..abdddde7c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_2L/imx307_2l_cmos_ex.h @@ -0,0 +1,124 @@ +#ifndef __IMX307_2L_CMOS_EX_H_ +#define __IMX307_2L_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +/* [TODO] ======== Temporarily definitions start ========*/ +typedef struct _AWB_SENSOR_DEFAULT_S { + CVI_U16 u16InitRgain; /*Init WB gain*/ + CVI_U16 u16InitGgain; + CVI_U16 u16InitBgain; + CVI_U8 u8AWBRunInterval; /*RW;AWB Run Interval*/ +} AWB_SENSOR_DEFAULT_S; + +/* [TODO] ======== Temporarily definitions end ========*/ +enum imx307_2l_linear_regs_e { + LINEAR_HOLD = 0, + LINEAR_SHS1_0, + LINEAR_SHS1_1, + LINEAR_SHS1_2, + LINEAR_GAIN, + LINEAR_HCG, + LINEAR_VMAX_0, + LINEAR_VMAX_1, + LINEAR_VMAX_2, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum imx307_2l_dol2_regs_e { + DOL2_HOLD = 0, + DOL2_SHS1_0, + DOL2_SHS1_1, + DOL2_SHS1_2, + DOL2_GAIN, + DOL2_HCG, + DOL2_GAIN1, + DOL2_RHS1_0, + DOL2_RHS1_1, + DOL2_RHS1_2, + DOL2_SHS2_0, + DOL2_SHS2_1, + DOL2_SHS2_2, + DOL2_VMAX_0, + DOL2_VMAX_1, + DOL2_VMAX_2, + DOL2_YOUT_SIZE_0, + DOL2_YOUT_SIZE_1, + DOL2_REL, + DOL2_REGS_NUM +}; + +typedef enum _IMX307_2L_MODE_E { + IMX307_2L_MODE_1080P30 = 0, + IMX307_2L_MODE_LINEAR_NUM, + IMX307_2L_MODE_1080P30_WDR = IMX307_2L_MODE_LINEAR_NUM, + IMX307_2L_MODE_NUM +} IMX307_2L_MODE_E; + +typedef struct _IMX307_2L_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX307_2L_STATE_S; + +typedef struct _IMX307_2L_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX307_2L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx307_2l[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx307_2l_BusInfo[]; +extern CVI_U16 g_au16Imx307_2l_GainMode[]; +extern const CVI_U8 imx307_2l_i2c_addr; +extern const CVI_U32 imx307_2l_addr_byte; +extern const CVI_U32 imx307_2l_data_byte; +extern void imx307_2l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void imx307_2l_init(VI_PIPE ViPipe); +extern void imx307_2l_exit(VI_PIPE ViPipe); +extern void imx307_2l_standby(VI_PIPE ViPipe); +extern void imx307_2l_restart(VI_PIPE ViPipe); +extern int imx307_2l_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx307_2l_read_register(VI_PIPE ViPipe, int addr); +extern int imx307_2l_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX307_2L_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx307_2L/imx307_2l_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_2L/imx307_2l_cmos_param.h new file mode 100644 index 000000000..ad2475a18 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_2L/imx307_2l_cmos_param.h @@ -0,0 +1,308 @@ +#ifndef __IMX307_2L_CMOS_PARAM_H_ +#define __IMX307_2L_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx307_2l_cmos_ex.h" + +static const IMX307_2L_MODE_S g_astImx307_2l_mode[IMX307_2L_MODE_NUM] = { + [IMX307_2L_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x1130, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX307_2L_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 8, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 2236, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 7, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.03396590426564216614, 2.31280159950256347656}, //B: slope, intercept + {0.02877708896994590759, 1.99502599239349365234}, //Gb: slope, intercept + {0.02853375114500522614, 1.53825533390045166016}, //Gr: slope, intercept + {0.02940983884036540985, 2.40369534492492675781}, //R: slope, intercept + }, + { //iso 200 + {0.03635194525122642517, 5.70069074630737304688}, //B: slope, intercept + {0.02990435808897018433, 6.70210981369018554688}, //Gb: slope, intercept + {0.03183263540267944336, 4.92136955261230468750}, //Gr: slope, intercept + {0.03145531564950942993, 5.97894525527954101563}, //R: slope, intercept + }, + { //iso 400 + {0.04329251870512962341, 7.09708356857299804688}, //B: slope, intercept + {0.03147880360484123230, 11.36076831817626953125}, //Gb: slope, intercept + {0.03299136087298393250, 8.49763488769531250000}, //Gr: slope, intercept + {0.03585162013769149780, 8.31188583374023437500}, //R: slope, intercept + }, + { //iso 800 + {0.05740678682923316956, 10.93907737731933593750}, //B: slope, intercept + {0.03538244962692260742, 21.53132820129394531250}, //Gb: slope, intercept + {0.04014955088496208191, 14.56391811370849609375}, //Gr: slope, intercept + {0.03907874971628189087, 15.16305541992187500000}, //R: slope, intercept + }, + { //iso 1600 + {0.05417122691869735718, 23.33716773986816406250}, //B: slope, intercept + {0.02816017158329486847, 55.33533859252929687500}, //Gb: slope, intercept + {0.03809726238250732422, 30.80285072326660156250}, //Gr: slope, intercept + {0.04028835147619247437, 31.24934768676757812500}, //R: slope, intercept + }, + { //iso 3200 + {0.07438381761312484741, 33.81318664550781250000}, //B: slope, intercept + {0.02690842747688293457, 95.65101623535156250000}, //Gb: slope, intercept + {0.05132644250988960266, 46.27661132812500000000}, //Gr: slope, intercept + {0.05343631654977798462, 44.67097473144531250000}, //R: slope, intercept + }, + { //iso 6400 + {0.10831451416015625000, 49.42535018920898437500}, //B: slope, intercept + {0.04577258601784706116, 122.51580810546875000000}, //Gb: slope, intercept + {0.06677398085594177246, 69.54801177978515625000}, //Gr: slope, intercept + {0.07670628279447555542, 63.47140884399414062500}, //R: slope, intercept + }, + { //iso 12800 + {0.15062870085239410400, 68.36373138427734375000}, //B: slope, intercept + {0.07762257009744644165, 146.30807495117187500000}, //Gb: slope, intercept + {0.09608269482851028442, 96.59751892089843750000}, //Gr: slope, intercept + {0.10346080362796783447, 96.64923095703125000000}, //R: slope, intercept + }, + { //iso 25600 + {0.21278673410415649414, 107.37140655517578125000}, //B: slope, intercept + {0.12505164742469787598, 179.24717712402343750000}, //Gb: slope, intercept + {0.14927712082862854004, 140.71289062500000000000}, //Gr: slope, intercept + {0.15530782938003540039, 139.79985046386718750000}, //R: slope, intercept + }, + { //iso 51200 + {0.32940942049026489258, 149.26779174804687500000}, //B: slope, intercept + {0.18958723545074462891, 247.18806457519531250000}, //Gb: slope, intercept + {0.19027391076087951660, 230.56108093261718750000}, //Gr: slope, intercept + {0.23455394804477691650, 192.10685729980468750000}, //R: slope, intercept + }, + { //iso 102400 + {0.48793542385101318359, 210.41285705566406250000}, //B: slope, intercept + {0.24973315000534057617, 372.87121582031250000000}, //Gb: slope, intercept + {0.23015110194683074951, 402.12283325195312500000}, //Gr: slope, intercept + {0.35159105062484741211, 294.27154541015625000000}, //R: slope, intercept + }, + { //iso 204800 + {0.60629695653915405273, 340.77212524414062500000}, //B: slope, intercept + {0.39248645305633544922, 481.49472045898437500000}, //Gb: slope, intercept + {0.33751612901687622070, 544.22698974609375000000}, //Gr: slope, intercept + {0.43583938479423522949, 458.90490722656250000000}, //R: slope, intercept + }, + { //iso 409600 + {0.71151763200759887695, 544.37280273437500000000}, //B: slope, intercept + {0.47628879547119140625, 697.04498291015625000000}, //Gb: slope, intercept + {0.38568580150604248047, 794.64263916015625000000}, //Gr: slope, intercept + {0.54425776004791259766, 658.77343750000000000000}, //R: slope, intercept + }, + { //iso 819200 + {0.61085152626037597656, 821.67352294921875000000}, //B: slope, intercept + {0.38012877106666564941, 1050.61950683593750000000}, //Gb: slope, intercept + {0.38677954673767089844, 1049.79968261718750000000}, //Gr: slope, intercept + {0.54386067390441894531, 875.86968994140625000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.88969016075134277344, 635.22283935546875000000}, //B: slope, intercept + {0.71133875846862792969, 754.16796875000000000000}, //Gb: slope, intercept + {0.66038286685943603516, 765.11163330078125000000}, //Gr: slope, intercept + {0.61520493030548095703, 817.94128417968750000000}, //R: slope, intercept + }, + { //iso 3276800 + {1.43259191513061523438, 263.03683471679687500000}, //B: slope, intercept + {0.87281060218811035156, 624.04595947265625000000}, //Gb: slope, intercept + {0.81407910585403442383, 666.59527587890625000000}, //Gr: slope, intercept + {0.87593811750411987305, 608.70275878906250000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {239, 239, 239, 239, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1087, 1087, 1087, 1087 +#endif + }, + .stAuto = { + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/243, 252, 290, 395, 681, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1228, 1365, 1365, 1365}, +#endif + }, + }, +}; + +struct combo_dev_attr_s imx307_2l_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {2, 1, 0, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_DOL, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX307_2L_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx307_2L/imx307_2l_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_2L/imx307_2l_sensor_ctl.c new file mode 100644 index 000000000..3a6a472eb --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_2L/imx307_2l_sensor_ctl.c @@ -0,0 +1,417 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx307_2l_cmos_ex.h" + +static void imx307_2l_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void imx307_2l_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 imx307_2l_i2c_addr = 0x1A; +const CVI_U32 imx307_2l_addr_byte = 2; +const CVI_U32 imx307_2l_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx307_2l_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx307_2l_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx307_2l_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int imx307_2l_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx307_2l_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (imx307_2l_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, imx307_2l_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, imx307_2l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (imx307_2l_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int imx307_2l_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx307_2l_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx307_2l_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx307_2l_addr_byte + imx307_2l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx307_2l_standby(VI_PIPE ViPipe) +{ + imx307_2l_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx307_2l_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ +} + +void imx307_2l_restart(VI_PIPE ViPipe) +{ + imx307_2l_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx307_2l_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx307_2l_write_register(ViPipe, 0x304b, 0x0a); +} + +void imx307_2l_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx307_2l[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx307_2l_write_register(ViPipe, + g_pastImx307_2l[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx307_2l[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define IMX307_CHIP_ID_ADDR 0x31dc +#define IMX307_CHIP_ID 0x4 +#define IMX307_CHIP_ID_MASK 0x6 + +void imx307_2l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = imx307_2l_read_register(ViPipe, 0x3007) & ~0x3; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + imx307_2l_write_register(ViPipe, 0x3007, val); +} + +int imx307_2l_probe(VI_PIPE ViPipe) +{ + int nVal; + + usleep(100); + if (imx307_2l_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = imx307_2l_read_register(ViPipe, IMX307_CHIP_ID_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((nVal & IMX307_CHIP_ID_MASK) != IMX307_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void imx307_2l_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastImx307_2l[ViPipe]->enWDRMode; + u8ImgMode = g_pastImx307_2l[ViPipe]->u8ImgMode; + + imx307_2l_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == IMX307_2L_MODE_1080P30_WDR) { + imx307_2l_wdr_1080p30_2to1_init(ViPipe); + } + } else { + imx307_2l_linear_1080p30_init(ViPipe); + } + g_pastImx307_2l[ViPipe]->bInit = CVI_TRUE; +} + +void imx307_2l_exit(VI_PIPE ViPipe) +{ + imx307_2l_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void imx307_2l_linear_1080p30_init(VI_PIPE ViPipe) +{ + imx307_2l_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx307_2l_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx307_2l_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx307_2l_write_register(ViPipe, 0x3005, 0x01); /* ADBIT 10bit*/ + imx307_2l_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx307_2l_write_register(ViPipe, 0x3009, 0x02); /**/ + imx307_2l_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx307_2l_write_register(ViPipe, 0x3011, 0x0A); + imx307_2l_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx307_2l_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx307_2l_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx307_2l_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx307_2l_write_register(ViPipe, 0x301C, 0x30); /* HMAX[7:0], TBD*/ + imx307_2l_write_register(ViPipe, 0x301D, 0x11); /* HMAX[15:8]*/ + imx307_2l_write_register(ViPipe, 0x3020, 0x8C); /* SHS[7:0], TBD*/ + imx307_2l_write_register(ViPipe, 0x3021, 0x01); /* SHS[15:8]*/ + imx307_2l_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx307_2l_write_register(ViPipe, 0x3046, 0x01); + imx307_2l_write_register(ViPipe, 0x304B, 0x0A); + imx307_2l_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx307_2l_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx307_2l_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx307_2l_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx307_2l_write_register(ViPipe, 0x309E, 0x4A); + imx307_2l_write_register(ViPipe, 0x309F, 0x4A); + imx307_2l_write_register(ViPipe, 0x311C, 0x0E); + imx307_2l_write_register(ViPipe, 0x3128, 0x04); + imx307_2l_write_register(ViPipe, 0x3129, 0x00); + imx307_2l_write_register(ViPipe, 0x313B, 0x41); + imx307_2l_write_register(ViPipe, 0x315E, 0x1A); + imx307_2l_write_register(ViPipe, 0x3164, 0x1A); + imx307_2l_write_register(ViPipe, 0x317C, 0x00); + imx307_2l_write_register(ViPipe, 0x31EC, 0x0E); + imx307_2l_write_register(ViPipe, 0x3405, 0x10); /* Repetition*/ + imx307_2l_write_register(ViPipe, 0x3407, 0x01); /* physical_lane_nl*/ + imx307_2l_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx307_2l_write_register(ViPipe, 0x3418, 0x49); /* y_out_size*/ + imx307_2l_write_register(ViPipe, 0x3419, 0x04); /* y_out_size*/ + imx307_2l_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx307_2l_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx307_2l_write_register(ViPipe, 0x3443, 0x01); /* csi_lane_mode*/ + imx307_2l_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx307_2l_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx307_2l_write_register(ViPipe, 0x3446, 0x57); /* tclkpost*/ + imx307_2l_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + //imx307_2l_write_register(ViPipe, 0x3448, 0x37); /* thszero*/ + imx307_2l_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx307_2l_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx307_2l_write_register(ViPipe, 0x344A, 0x1F); /* thsprepare*/ + imx307_2l_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx307_2l_write_register(ViPipe, 0x344C, 0x1F); /* tclktrail*/ + imx307_2l_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + //imx307_2l_write_register(ViPipe, 0x344E, 0x1F); /* thstrail*/ + imx307_2l_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx307_2l_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx307_2l_write_register(ViPipe, 0x3450, 0x77); /* tclkzero*/ + imx307_2l_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx307_2l_write_register(ViPipe, 0x3452, 0x1F); /* tclkprepare*/ + imx307_2l_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx307_2l_write_register(ViPipe, 0x3454, 0x17); /* tlpx*/ + imx307_2l_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx307_2l_write_register(ViPipe, 0x3472, 0x9C); /* x_out_size*/ + imx307_2l_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx307_2l_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx307_2l_default_reg_init(ViPipe); + + imx307_2l_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx307_2l_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx307_2l_write_register(ViPipe, 0x304b, 0x0a); + + printf("ViPipe:%d,===IMX307 1080P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void imx307_2l_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + imx307_2l_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx307_2l_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx307_2l_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx307_2l_write_register(ViPipe, 0x3005, 0x01); /* ADBIT*/ + imx307_2l_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx307_2l_write_register(ViPipe, 0x3009, 0x01); /**/ + imx307_2l_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx307_2l_write_register(ViPipe, 0x300C, 0x11); /* WDMODE [0] 0:Normal, 1:DOL, WDSEL [5:4] 1:DOL 2 frames*/ + imx307_2l_write_register(ViPipe, 0x3011, 0x0A); + imx307_2l_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx307_2l_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx307_2l_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx307_2l_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx307_2l_write_register(ViPipe, 0x301C, 0x98); /* HMAX[7:0], TBD*/ + imx307_2l_write_register(ViPipe, 0x301D, 0x08); /* HMAX[15:8]*/ + imx307_2l_write_register(ViPipe, 0x3020, 0x02); /* SHS[7:0], TBD*/ + imx307_2l_write_register(ViPipe, 0x3021, 0x00); /* SHS[15:8]*/ + imx307_2l_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx307_2l_write_register(ViPipe, 0x3024, 0xC9); /* SHS2[7:0], TBD*/ + imx307_2l_write_register(ViPipe, 0x3025, 0x07); /* SHS2[15:8]*/ + imx307_2l_write_register(ViPipe, 0x3026, 0x00); /* SHS2[19:16]*/ + imx307_2l_write_register(ViPipe, 0x3030, 0x0B); /* RHS1[7:0], TBD*/ + imx307_2l_write_register(ViPipe, 0x3031, 0x00); /* RHS1[15:8]*/ + imx307_2l_write_register(ViPipe, 0x3032, 0x00); /* RHS1[19:16]*/ + imx307_2l_write_register(ViPipe, 0x3045, 0x05); /* DOLSCDEN [0] 1: pattern1 0: pattern2*/ + imx307_2l_write_register(ViPipe, 0x3046, 0x01); + imx307_2l_write_register(ViPipe, 0x304B, 0x0A); + imx307_2l_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx307_2l_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx307_2l_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx307_2l_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx307_2l_write_register(ViPipe, 0x309E, 0x4A); + imx307_2l_write_register(ViPipe, 0x309F, 0x4A); + imx307_2l_write_register(ViPipe, 0x3106, 0x15); /*DOLHBFIXEN[7] 0: pattern1 1: pattern2*/ + imx307_2l_write_register(ViPipe, 0x311C, 0x0E); + imx307_2l_write_register(ViPipe, 0x3128, 0x04); + imx307_2l_write_register(ViPipe, 0x3129, 0x00); + imx307_2l_write_register(ViPipe, 0x313B, 0x41); + imx307_2l_write_register(ViPipe, 0x315E, 0x1A); + imx307_2l_write_register(ViPipe, 0x3164, 0x1A); + imx307_2l_write_register(ViPipe, 0x317C, 0x00); + imx307_2l_write_register(ViPipe, 0x31EC, 0x0E); + imx307_2l_write_register(ViPipe, 0x3405, 0x00); /* Repetition*/ + imx307_2l_write_register(ViPipe, 0x3407, 0x01); /* physical_lane_nl*/ + imx307_2l_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx307_2l_write_register(ViPipe, 0x3415, 0x00); /* NULL0_SIZE_V, set to 00h when DOL*/ + imx307_2l_write_register(ViPipe, 0x3418, 0xB4); /* y_out_size*/ + imx307_2l_write_register(ViPipe, 0x3419, 0x08); /* y_out_size*/ + imx307_2l_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx307_2l_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx307_2l_write_register(ViPipe, 0x3443, 0x01); /* csi_lane_mode*/ + imx307_2l_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx307_2l_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx307_2l_write_register(ViPipe, 0x3446, 0x77); /* tclkpost*/ + imx307_2l_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx307_2l_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx307_2l_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx307_2l_write_register(ViPipe, 0x344A, 0x47); /* thsprepare*/ + imx307_2l_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx307_2l_write_register(ViPipe, 0x344C, 0x37); /* tclktrail*/ + imx307_2l_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx307_2l_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx307_2l_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx307_2l_write_register(ViPipe, 0x3450, 0xFF); /* tclkzero*/ + imx307_2l_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx307_2l_write_register(ViPipe, 0x3452, 0x3F); /* tclkprepare*/ + imx307_2l_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx307_2l_write_register(ViPipe, 0x3454, 0x37); /* tlpx*/ + imx307_2l_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx307_2l_write_register(ViPipe, 0x3472, 0xA0); /* x_out_size*/ + imx307_2l_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx307_2l_write_register(ViPipe, 0x347B, 0x23); /**/ + imx307_2l_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx307_2l_default_reg_init(ViPipe); + + if (g_au16Imx307_2l_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + imx307_2l_write_register(ViPipe, 0x30F0, 0xF0); + imx307_2l_write_register(ViPipe, 0x3010, 0x21); + } else { + imx307_2l_write_register(ViPipe, 0x30F0, 0x64); + imx307_2l_write_register(ViPipe, 0x3010, 0x61); + } + + imx307_2l_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx307_2l_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx307_2l_write_register(ViPipe, 0x304b, 0x0a); + + printf("===Imx307 sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx307_slave/Makefile b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_slave/Makefile new file mode 100644 index 000000000..39bacf8ec --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_slave/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx307_slave.a +TARGET_SO = $(MW_LIB)/libsns_imx307_slave.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx307_slave/imx307_slave_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_slave/imx307_slave_cmos.c new file mode 100644 index 000000000..287396783 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_slave/imx307_slave_cmos.c @@ -0,0 +1,1185 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_ae.h" +#include "cvi_isp.h" + +#include "imx307_slave_cmos_ex.h" +#include "imx307_slave_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX307_SLAVE_ID 307 +#define SENSOR_IMX307_SLAVE_WIDTH 1920 +#define SENSOR_IMX307_SLAVE_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx307_Slave[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX307_SLAVE_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx307_Slave[dev]) +#define IMX307_SLAVE_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx307_Slave[dev] = pstCtx) +#define IMX307_SLAVE_SENSOR_RESET_CTX(dev) (g_pastImx307_Slave[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunImx307_Slave_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx307_Slave_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Imx307_Slave_UseHwSync[VI_MAX_PIPE_NUM] = {0}; + +IMX307_SLAVE_STATE_S g_astImx307_Slave_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx307_Slave_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx307 Lines Range*****/ +#define IMX307_SLAVE_FULL_LINES_MAX (0x3FFFF) +#define IMX307_SLAVE_FULL_LINES_MAX_2TO1_WDR (0x3FFFF) // considering the YOUT_SIZE and bad frame +#define IMX307_SLAVE_VMAX_1080P30_LINEAR 1125 + +/*****Imx307 Register Address*****/ +#define IMX307_SLAVE_HOLD_ADDR 0x3001 +#define IMX307_SLAVE_SHS1_ADDR 0x3020 +#define IMX307_SLAVE_SHS2_ADDR 0x3024 +#define IMX307_SLAVE_GAIN_ADDR 0x3014 +#define IMX307_SLAVE_GAIN1_ADDR 0x30F2 +#define IMX307_SLAVE_HCG_ADDR 0x3009 +#define IMX307_SLAVE_VMAX_ADDR 0x3018 +#define IMX307_SLAVE_YOUT_ADDR 0x3418 +#define IMX307_SLAVE_RHS1_ADDR 0x3030 +#define IMX307_SLAVE_TABLE_END 0xffff + +#define IMX307_SLAVE_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX307_SLAVE_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astImx307_Slave_mode[IMX307_SLAVE_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx307_Slave_mode[IMX307_SLAVE_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 45740; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astImx307_Slave_mode[IMX307_SLAVE_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx307_Slave_mode[IMX307_SLAVE_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 45740; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = IMX307_SLAVE_VMAX_1080P30_LINEAR; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case IMX307_SLAVE_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX307_SLAVE_FULL_LINES_MAX_2TO1_WDR) ? + IMX307_SLAVE_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case IMX307_SLAVE_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX307_SLAVE_FULL_LINES_MAX) ? IMX307_SLAVE_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } else { + pstSnsRegsInfo->astI2cData[DOL2_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx307_Slave_State[ViPipe].u32RHS1_MAX = + (u32VMAX - g_astImx307_Slave_State[ViPipe].u32BRL) * 2 - 21; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHS1 = 0; + CVI_U32 u32SHS2 = 0; + CVI_U32 u32YOUTSIZE; + CVI_U32 u16BRL = 0; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u16BRL = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].u16BRL; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[0] < u32LongIntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], u32LongIntTime - 1); + return CVI_FAILURE; + } + u32SHS2 = pstSnsState->au32FL[0] - u32LongIntTime - 1; + + u32SHS1 = (u32ShortIntTime % 2) + 2; + u32RHS1 = u32ShortIntTime + u32SHS1 + 1; + g_astImx307_Slave_State[ViPipe].u32RHS1 = u32RHS1; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - (u32SHS1 + 1); + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[0] - (u32SHS2 + 1); + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + u32YOUTSIZE = (u16BRL + (u32RHS1 - 1) / 2) * 2; + u32YOUTSIZE = (u32YOUTSIZE >= 0x1FFF) ? 0x1FFF : u32YOUTSIZE; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHS1 = %d\n", u32ShortIntTime, u32SHS1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d u32YOUTSIZE = %d\n", ViPipe, u32RHS1, u32YOUTSIZE); + + pstSnsRegsInfo->astI2cData[DOL2_SHS1_0].u32Data = (u32SHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_1].u32Data = ((u32SHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_2].u32Data = ((u32SHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHS2_0].u32Data = (u32SHS2 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_1].u32Data = ((u32SHS2 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_2].u32Data = ((u32SHS2 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_0].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_1].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_2].u32Data = ((u32RHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_0].u32Data = (u32YOUTSIZE & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_1].u32Data = ((u32YOUTSIZE & 0x1F00) >> 8); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if (pstSnsState->au32FL[0] < *u32IntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], *u32IntTime - 1); + return CVI_FAILURE; + } + u32Value = pstSnsState->au32FL[0] - *u32IntTime - 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2].u32Data = ((u32Value & 0x30000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 327567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32HCG = g_astImx307_Slave_State[ViPipe].u8Hcg; + CVI_U32 u16Mode = g_au16Imx307_Slave_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 20) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 20; + } + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = (u32HCG & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + CVI_U8 bEnableHCG = 0; + + if (pu32Again[0] >= 20 && pu32Again[1] >= 20) { + /* hcg bit[4]*/ + u32HCG |= 0x10; + bEnableHCG = 1; + } + + u32Again = pu32Again[1] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + + u32Again = pu32Again[0] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN1].u32Data = (u32Tmp & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 20) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 20; + } + + u32Tmp = u32Again + u32Dgain; + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 2 : 2; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 10; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx307_Slave_State[ViPipe].u32RHS1_MAX - 3)) ? + (g_astImx307_Slave_State[ViPipe].u32RHS1_MAX - 3) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} +#if 0 +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} +#endif +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX307_SLAVE_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx307_Slave_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX307_SLAVE_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = IMX307_SLAVE_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].u32VtsDef; + g_astImx307_Slave_State[ViPipe].u8Hcg = 0x2; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX307_SLAVE_MODE_1080P30) + pstSnsState->u8ImgMode = IMX307_SLAVE_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + g_astImx307_Slave_State[ViPipe].u8Hcg = 0x1; + if (pstSnsState->u8ImgMode == IMX307_SLAVE_MODE_1080P30_WDR) { + pstSnsState->u32FLStd = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx307_Slave_State[ViPipe].u32BRL = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1080p\n"); + } + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx307_Slave_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx307_slave_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx307_slave_addr_byte; + pstI2c_data[i].u32DataByteNum = imx307_slave_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_HOLD].u32RegAddr = IMX307_SLAVE_HOLD_ADDR; + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_SHS1_0].u32RegAddr = IMX307_SLAVE_SHS1_ADDR; + pstI2c_data[DOL2_SHS1_1].u32RegAddr = IMX307_SLAVE_SHS1_ADDR + 1; + pstI2c_data[DOL2_SHS1_2].u32RegAddr = IMX307_SLAVE_SHS1_ADDR + 2; + + pstI2c_data[DOL2_GAIN].u32RegAddr = IMX307_SLAVE_GAIN_ADDR; + pstI2c_data[DOL2_HCG].u32RegAddr = IMX307_SLAVE_HCG_ADDR; + pstI2c_data[DOL2_HCG].u8DelayFrmNum = 1; + pstI2c_data[DOL2_GAIN1].u32RegAddr = IMX307_SLAVE_GAIN1_ADDR; + pstI2c_data[DOL2_RHS1_0].u32RegAddr = IMX307_SLAVE_RHS1_ADDR; + pstI2c_data[DOL2_RHS1_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_1].u32RegAddr = IMX307_SLAVE_RHS1_ADDR + 1; + pstI2c_data[DOL2_RHS1_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_2].u32RegAddr = IMX307_SLAVE_RHS1_ADDR + 2; + pstI2c_data[DOL2_RHS1_2].u8DelayFrmNum = 1; + pstI2c_data[DOL2_SHS2_0].u32RegAddr = IMX307_SLAVE_SHS2_ADDR; + pstI2c_data[DOL2_SHS2_1].u32RegAddr = IMX307_SLAVE_SHS2_ADDR + 1; + pstI2c_data[DOL2_SHS2_2].u32RegAddr = IMX307_SLAVE_SHS2_ADDR + 2; + pstI2c_data[DOL2_VMAX_0].u32RegAddr = IMX307_SLAVE_VMAX_ADDR; + pstI2c_data[DOL2_VMAX_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_1].u32RegAddr = IMX307_SLAVE_VMAX_ADDR + 1; + pstI2c_data[DOL2_VMAX_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_2].u32RegAddr = IMX307_SLAVE_VMAX_ADDR + 2; + pstI2c_data[DOL2_VMAX_2].u8DelayFrmNum = 1; + + pstI2c_data[DOL2_YOUT_SIZE_0].u32RegAddr = IMX307_SLAVE_YOUT_ADDR; + pstI2c_data[DOL2_YOUT_SIZE_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u32RegAddr = IMX307_SLAVE_YOUT_ADDR + 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_REL].u32RegAddr = IMX307_SLAVE_HOLD_ADDR; + pstI2c_data[DOL2_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 1; + break; + default: + pstI2c_data[LINEAR_HOLD].u32RegAddr = IMX307_SLAVE_HOLD_ADDR; + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_SHS1_0].u32RegAddr = IMX307_SLAVE_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1].u32RegAddr = IMX307_SLAVE_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2].u32RegAddr = IMX307_SLAVE_SHS1_ADDR + 2; + pstI2c_data[LINEAR_GAIN].u32RegAddr = IMX307_SLAVE_GAIN_ADDR; + pstI2c_data[LINEAR_HCG].u32RegAddr = IMX307_SLAVE_HCG_ADDR; + pstI2c_data[LINEAR_HCG].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VMAX_0].u32RegAddr = IMX307_SLAVE_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1].u32RegAddr = IMX307_SLAVE_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_2].u32RegAddr = IMX307_SLAVE_VMAX_ADDR + 2; + pstI2c_data[LINEAR_REL].u32RegAddr = IMX307_SLAVE_HOLD_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[DOL2_REL].u32Data = 0; + pstI2c_data[DOL2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX307_SLAVE_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX307_SLAVE_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX307_SLAVE_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX307_SLAVE_MODE_1080P30_WDR; + g_astImx307_Slave_State[ViPipe].u32BRL = 1109; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx307_Slave_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx307_slave_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx307_Slave_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = IMX307_SLAVE_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = IMX307_SLAVE_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[0] = IMX307_SLAVE_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[1] = IMX307_SLAVE_VMAX_1080P30_LINEAR; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx307_slave_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx307_Slave_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx307_slave_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx307_slave_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx307_slave_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx307_slave_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx307_Slave_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX307_SLAVE_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX307_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX307_SLAVE_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + //AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX307_SLAVE_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } +#if 0 + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stSnsExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } +#endif + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX307_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX307_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } +#if 0 + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX307_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } +#endif + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx307_Slave_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Imx307_Slave_UseHwSync[ViPipe] = pstInitAttr->u16UseHwSync; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return imx307_slave_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsImx307_Slave_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx307_slave_standby, + .pfnRestart = imx307_slave_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx307_slave_write_register, + .pfnReadReg = imx307_slave_read_register, + .pfnSetBusInfo = imx307_slave_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx307_slave/imx307_slave_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_slave/imx307_slave_cmos_ex.h new file mode 100644 index 000000000..bfcc7b475 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_slave/imx307_slave_cmos_ex.h @@ -0,0 +1,125 @@ +#ifndef __IMX307_SLAVE_CMOS_EX_H_ +#define __IMX307_SLAVE_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +/* [TODO] ======== Temporarily definitions start ========*/ +typedef struct _AWB_SENSOR_DEFAULT_S { + CVI_U16 u16InitRgain; /*Init WB gain*/ + CVI_U16 u16InitGgain; + CVI_U16 u16InitBgain; + CVI_U8 u8AWBRunInterval; /*RW;AWB Run Interval*/ +} AWB_SENSOR_DEFAULT_S; + +/* [TODO] ======== Temporarily definitions end ========*/ +enum imx307_slave_linear_regs_e { + LINEAR_HOLD = 0, + LINEAR_SHS1_0, + LINEAR_SHS1_1, + LINEAR_SHS1_2, + LINEAR_GAIN, + LINEAR_HCG, + LINEAR_VMAX_0, + LINEAR_VMAX_1, + LINEAR_VMAX_2, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum imx307_slave_dol2_regs_e { + DOL2_HOLD = 0, + DOL2_SHS1_0, + DOL2_SHS1_1, + DOL2_SHS1_2, + DOL2_GAIN, + DOL2_HCG, + DOL2_GAIN1, + DOL2_RHS1_0, + DOL2_RHS1_1, + DOL2_RHS1_2, + DOL2_SHS2_0, + DOL2_SHS2_1, + DOL2_SHS2_2, + DOL2_VMAX_0, + DOL2_VMAX_1, + DOL2_VMAX_2, + DOL2_YOUT_SIZE_0, + DOL2_YOUT_SIZE_1, + DOL2_REL, + DOL2_REGS_NUM +}; + +typedef enum _IMX307_SLAVE_MODE_E { + IMX307_SLAVE_MODE_1080P30 = 0, + IMX307_SLAVE_MODE_LINEAR_NUM, + IMX307_SLAVE_MODE_1080P30_WDR = IMX307_SLAVE_MODE_LINEAR_NUM, + IMX307_SLAVE_MODE_NUM +} IMX307_SLAVE_MODE_E; + +typedef struct _IMX307_SLAVE_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX307_SLAVE_STATE_S; + +typedef struct _IMX307_SLAVE_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX307_SLAVE_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx307_Slave[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx307_Slave_BusInfo[]; +extern CVI_U16 g_au16Imx307_Slave_UseHwSync[]; +extern CVI_U16 g_au16Imx307_Slave_GainMode[]; +extern const CVI_U8 imx307_slave_i2c_addr; +extern const CVI_U32 imx307_slave_addr_byte; +extern const CVI_U32 imx307_slave_data_byte; +extern void imx307_slave_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void imx307_slave_init(VI_PIPE ViPipe); +extern void imx307_slave_exit(VI_PIPE ViPipe); +extern void imx307_slave_standby(VI_PIPE ViPipe); +extern void imx307_slave_restart(VI_PIPE ViPipe); +extern int imx307_slave_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx307_slave_read_register(VI_PIPE ViPipe, int addr); +extern int imx307_slave_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX307_SLAVE_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx307_slave/imx307_slave_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_slave/imx307_slave_cmos_param.h new file mode 100644 index 000000000..558cdd93c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_slave/imx307_slave_cmos_param.h @@ -0,0 +1,307 @@ +#ifndef __IMX307_SLAVE_CMOS_PARAM_H_ +#define __IMX307_SLAVE_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx307_slave_cmos_ex.h" + +static const IMX307_SLAVE_MODE_S g_astImx307_Slave_mode[IMX307_SLAVE_MODE_NUM] = { + [IMX307_SLAVE_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x1130, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX307_SLAVE_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 8, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 2236, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.03396590426564216614, 2.31280159950256347656}, //B: slope, intercept + {0.02877708896994590759, 1.99502599239349365234}, //Gb: slope, intercept + {0.02853375114500522614, 1.53825533390045166016}, //Gr: slope, intercept + {0.02940983884036540985, 2.40369534492492675781}, //R: slope, intercept + }, + { //iso 200 + {0.03635194525122642517, 5.70069074630737304688}, //B: slope, intercept + {0.02990435808897018433, 6.70210981369018554688}, //Gb: slope, intercept + {0.03183263540267944336, 4.92136955261230468750}, //Gr: slope, intercept + {0.03145531564950942993, 5.97894525527954101563}, //R: slope, intercept + }, + { //iso 400 + {0.04329251870512962341, 7.09708356857299804688}, //B: slope, intercept + {0.03147880360484123230, 11.36076831817626953125}, //Gb: slope, intercept + {0.03299136087298393250, 8.49763488769531250000}, //Gr: slope, intercept + {0.03585162013769149780, 8.31188583374023437500}, //R: slope, intercept + }, + { //iso 800 + {0.05740678682923316956, 10.93907737731933593750}, //B: slope, intercept + {0.03538244962692260742, 21.53132820129394531250}, //Gb: slope, intercept + {0.04014955088496208191, 14.56391811370849609375}, //Gr: slope, intercept + {0.03907874971628189087, 15.16305541992187500000}, //R: slope, intercept + }, + { //iso 1600 + {0.05417122691869735718, 23.33716773986816406250}, //B: slope, intercept + {0.02816017158329486847, 55.33533859252929687500}, //Gb: slope, intercept + {0.03809726238250732422, 30.80285072326660156250}, //Gr: slope, intercept + {0.04028835147619247437, 31.24934768676757812500}, //R: slope, intercept + }, + { //iso 3200 + {0.07438381761312484741, 33.81318664550781250000}, //B: slope, intercept + {0.02690842747688293457, 95.65101623535156250000}, //Gb: slope, intercept + {0.05132644250988960266, 46.27661132812500000000}, //Gr: slope, intercept + {0.05343631654977798462, 44.67097473144531250000}, //R: slope, intercept + }, + { //iso 6400 + {0.10831451416015625000, 49.42535018920898437500}, //B: slope, intercept + {0.04577258601784706116, 122.51580810546875000000}, //Gb: slope, intercept + {0.06677398085594177246, 69.54801177978515625000}, //Gr: slope, intercept + {0.07670628279447555542, 63.47140884399414062500}, //R: slope, intercept + }, + { //iso 12800 + {0.15062870085239410400, 68.36373138427734375000}, //B: slope, intercept + {0.07762257009744644165, 146.30807495117187500000}, //Gb: slope, intercept + {0.09608269482851028442, 96.59751892089843750000}, //Gr: slope, intercept + {0.10346080362796783447, 96.64923095703125000000}, //R: slope, intercept + }, + { //iso 25600 + {0.21278673410415649414, 107.37140655517578125000}, //B: slope, intercept + {0.12505164742469787598, 179.24717712402343750000}, //Gb: slope, intercept + {0.14927712082862854004, 140.71289062500000000000}, //Gr: slope, intercept + {0.15530782938003540039, 139.79985046386718750000}, //R: slope, intercept + }, + { //iso 51200 + {0.32940942049026489258, 149.26779174804687500000}, //B: slope, intercept + {0.18958723545074462891, 247.18806457519531250000}, //Gb: slope, intercept + {0.19027391076087951660, 230.56108093261718750000}, //Gr: slope, intercept + {0.23455394804477691650, 192.10685729980468750000}, //R: slope, intercept + }, + { //iso 102400 + {0.48793542385101318359, 210.41285705566406250000}, //B: slope, intercept + {0.24973315000534057617, 372.87121582031250000000}, //Gb: slope, intercept + {0.23015110194683074951, 402.12283325195312500000}, //Gr: slope, intercept + {0.35159105062484741211, 294.27154541015625000000}, //R: slope, intercept + }, + { //iso 204800 + {0.60629695653915405273, 340.77212524414062500000}, //B: slope, intercept + {0.39248645305633544922, 481.49472045898437500000}, //Gb: slope, intercept + {0.33751612901687622070, 544.22698974609375000000}, //Gr: slope, intercept + {0.43583938479423522949, 458.90490722656250000000}, //R: slope, intercept + }, + { //iso 409600 + {0.71151763200759887695, 544.37280273437500000000}, //B: slope, intercept + {0.47628879547119140625, 697.04498291015625000000}, //Gb: slope, intercept + {0.38568580150604248047, 794.64263916015625000000}, //Gr: slope, intercept + {0.54425776004791259766, 658.77343750000000000000}, //R: slope, intercept + }, + { //iso 819200 + {0.61085152626037597656, 821.67352294921875000000}, //B: slope, intercept + {0.38012877106666564941, 1050.61950683593750000000}, //Gb: slope, intercept + {0.38677954673767089844, 1049.79968261718750000000}, //Gr: slope, intercept + {0.54386067390441894531, 875.86968994140625000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.88969016075134277344, 635.22283935546875000000}, //B: slope, intercept + {0.71133875846862792969, 754.16796875000000000000}, //Gb: slope, intercept + {0.66038286685943603516, 765.11163330078125000000}, //Gr: slope, intercept + {0.61520493030548095703, 817.94128417968750000000}, //R: slope, intercept + }, + { //iso 3276800 + {1.43259191513061523438, 263.03683471679687500000}, //B: slope, intercept + {0.87281060218811035156, 624.04595947265625000000}, //Gb: slope, intercept + {0.81407910585403442383, 666.59527587890625000000}, //Gr: slope, intercept + {0.87593811750411987305, 608.70275878906250000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {239, 239, 239, 239, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1087, 1087, 1087, 1087 +#endif + }, + .stAuto = { + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/244, 252, 290, 395, 683, 1023, 1023, 1023}, + {239, 240, 240, 241, 241, 241, 241, 244, /*8*/243, 252, 290, 395, 681, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1229, 1365, 1365, 1365}, + {1087, 1088, 1088, 1088, 1088, 1088, 1088, 1089, + /*8*/1089, 1091, 1102, 1133, 1228, 1365, 1365, 1365}, +#endif + }, + }, +}; + +struct combo_dev_attr_s imx307_slave_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {4, 3, 5, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_DOL, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 1, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX307_SLAVE_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx307_slave/imx307_slave_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_slave/imx307_slave_sensor_ctl.c new file mode 100644 index 000000000..d925384c7 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx307_slave/imx307_slave_sensor_ctl.c @@ -0,0 +1,420 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx307_slave_cmos_ex.h" + +static void imx307_slave_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void imx307_slave_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 imx307_slave_i2c_addr = 0x1A; +const CVI_U32 imx307_slave_addr_byte = 2; +const CVI_U32 imx307_slave_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx307_slave_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx307_Slave_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx307_slave_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int imx307_slave_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx307_slave_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (imx307_slave_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, imx307_slave_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, imx307_slave_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (imx307_slave_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int imx307_slave_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx307_slave_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx307_slave_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx307_slave_addr_byte + imx307_slave_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx307_slave_standby(VI_PIPE ViPipe) +{ + imx307_slave_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ +} + +void imx307_slave_restart(VI_PIPE ViPipe) +{ + imx307_slave_write_register(ViPipe, 0x3000, 0x00); /* standby */ +} + +void imx307_slave_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx307_Slave[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx307_slave_write_register(ViPipe, + g_pastImx307_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx307_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define IMX307_CHIP_ID_ADDR 0x31dc +#define IMX307_CHIP_ID 0x4 +#define IMX307_CHIP_ID_MASK 0x6 + +void imx307_slave_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = imx307_slave_read_register(ViPipe, 0x3007) & ~0x3; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + imx307_slave_write_register(ViPipe, 0x3007, val); +} + +int imx307_slave_probe(VI_PIPE ViPipe) +{ + int nVal; + + usleep(100); + if (imx307_slave_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = imx307_slave_read_register(ViPipe, IMX307_CHIP_ID_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((nVal & IMX307_CHIP_ID_MASK) != IMX307_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void imx307_slave_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastImx307_Slave[ViPipe]->enWDRMode; + u8ImgMode = g_pastImx307_Slave[ViPipe]->u8ImgMode; + + imx307_slave_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == IMX307_SLAVE_MODE_1080P30_WDR) { + imx307_slave_wdr_1080p30_2to1_init(ViPipe); + } + } else { + imx307_slave_linear_1080p30_init(ViPipe); + } + g_pastImx307_Slave[ViPipe]->bInit = CVI_TRUE; +} + +void imx307_slave_exit(VI_PIPE ViPipe) +{ + imx307_slave_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void imx307_slave_linear_1080p30_init(VI_PIPE ViPipe) +{ + imx307_slave_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx307_slave_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx307_slave_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx307_slave_write_register(ViPipe, 0x3005, 0x01); /* ADBIT 10bit*/ + imx307_slave_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx307_slave_write_register(ViPipe, 0x3009, 0x02); /**/ + imx307_slave_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx307_slave_write_register(ViPipe, 0x3011, 0x0A); + imx307_slave_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx307_slave_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx307_slave_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx307_slave_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx307_slave_write_register(ViPipe, 0x301C, 0x30); /* HMAX[7:0], TBD*/ + imx307_slave_write_register(ViPipe, 0x301D, 0x11); /* HMAX[15:8]*/ + imx307_slave_write_register(ViPipe, 0x3020, 0x8C); /* SHS[7:0], TBD*/ + imx307_slave_write_register(ViPipe, 0x3021, 0x01); /* SHS[15:8]*/ + imx307_slave_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx307_slave_write_register(ViPipe, 0x3046, 0x01); + imx307_slave_write_register(ViPipe, 0x304B, 0x00); + imx307_slave_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx307_slave_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx307_slave_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx307_slave_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx307_slave_write_register(ViPipe, 0x309E, 0x4A); + imx307_slave_write_register(ViPipe, 0x309F, 0x4A); + imx307_slave_write_register(ViPipe, 0x311C, 0x0E); + imx307_slave_write_register(ViPipe, 0x3128, 0x04); + imx307_slave_write_register(ViPipe, 0x3129, 0x00); + imx307_slave_write_register(ViPipe, 0x313B, 0x41); + imx307_slave_write_register(ViPipe, 0x315E, 0x1A); + imx307_slave_write_register(ViPipe, 0x3164, 0x1A); + imx307_slave_write_register(ViPipe, 0x317C, 0x00); + imx307_slave_write_register(ViPipe, 0x31EC, 0x0E); + imx307_slave_write_register(ViPipe, 0x3405, 0x10); /* Repetition*/ + imx307_slave_write_register(ViPipe, 0x3407, 0x01); /* physical_lane_nl*/ + imx307_slave_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx307_slave_write_register(ViPipe, 0x3418, 0x49); /* y_out_size*/ + imx307_slave_write_register(ViPipe, 0x3419, 0x04); /* y_out_size*/ + imx307_slave_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx307_slave_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx307_slave_write_register(ViPipe, 0x3443, 0x01); /* csi_lane_mode*/ + imx307_slave_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx307_slave_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx307_slave_write_register(ViPipe, 0x3446, 0x57); /* tclkpost*/ + imx307_slave_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + //imx307_slave_write_register(ViPipe, 0x3448, 0x37); /* thszero*/ + imx307_slave_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx307_slave_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx307_slave_write_register(ViPipe, 0x344A, 0x1F); /* thsprepare*/ + imx307_slave_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx307_slave_write_register(ViPipe, 0x344C, 0x1F); /* tclktrail*/ + imx307_slave_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + //imx307_slave_write_register(ViPipe, 0x344E, 0x1F); /* thstrail*/ + imx307_slave_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx307_slave_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx307_slave_write_register(ViPipe, 0x3450, 0x77); /* tclkzero*/ + imx307_slave_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx307_slave_write_register(ViPipe, 0x3452, 0x1F); /* tclkprepare*/ + imx307_slave_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx307_slave_write_register(ViPipe, 0x3454, 0x17); /* tlpx*/ + imx307_slave_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx307_slave_write_register(ViPipe, 0x3472, 0x9C); /* x_out_size*/ + imx307_slave_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx307_slave_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx307_slave_default_reg_init(ViPipe); + + imx307_slave_write_register(ViPipe, 0x3000, 0x00); /* standby */ + + if (!g_au16Imx307_Slave_UseHwSync[ViPipe]) { + delay_ms(20); + imx307_slave_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx307_slave_write_register(ViPipe, 0x304b, 0x0a); + } + + printf("ViPipe:%d,===IMX307 1080P 30fps 12bit LINE Slave Init OK!===\n", ViPipe); +} + +static void imx307_slave_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + imx307_slave_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx307_slave_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx307_slave_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx307_slave_write_register(ViPipe, 0x3005, 0x01); /* ADBIT*/ + imx307_slave_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx307_slave_write_register(ViPipe, 0x3009, 0x01); /**/ + imx307_slave_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx307_slave_write_register(ViPipe, 0x300C, 0x11); /* WDMODE [0] 0:Normal, 1:DOL, WDSEL [5:4] 1:DOL 2 frames*/ + imx307_slave_write_register(ViPipe, 0x3011, 0x0A); + imx307_slave_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx307_slave_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx307_slave_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx307_slave_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx307_slave_write_register(ViPipe, 0x301C, 0x98); /* HMAX[7:0], TBD*/ + imx307_slave_write_register(ViPipe, 0x301D, 0x08); /* HMAX[15:8]*/ + imx307_slave_write_register(ViPipe, 0x3020, 0x02); /* SHS[7:0], TBD*/ + imx307_slave_write_register(ViPipe, 0x3021, 0x00); /* SHS[15:8]*/ + imx307_slave_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx307_slave_write_register(ViPipe, 0x3024, 0xC9); /* SHS2[7:0], TBD*/ + imx307_slave_write_register(ViPipe, 0x3025, 0x07); /* SHS2[15:8]*/ + imx307_slave_write_register(ViPipe, 0x3026, 0x00); /* SHS2[19:16]*/ + imx307_slave_write_register(ViPipe, 0x3030, 0x0B); /* RHS1[7:0], TBD*/ + imx307_slave_write_register(ViPipe, 0x3031, 0x00); /* RHS1[15:8]*/ + imx307_slave_write_register(ViPipe, 0x3032, 0x00); /* RHS1[19:16]*/ + imx307_slave_write_register(ViPipe, 0x3045, 0x05); /* DOLSCDEN [0] 1: pattern1 0: pattern2*/ + imx307_slave_write_register(ViPipe, 0x3046, 0x01); + imx307_slave_write_register(ViPipe, 0x304B, 0x00); + imx307_slave_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx307_slave_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx307_slave_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx307_slave_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx307_slave_write_register(ViPipe, 0x309E, 0x4A); + imx307_slave_write_register(ViPipe, 0x309F, 0x4A); + imx307_slave_write_register(ViPipe, 0x3106, 0x11); /*DOLHBFIXEN[7] 0: pattern1 1: pattern2*/ + imx307_slave_write_register(ViPipe, 0x311C, 0x0E); + imx307_slave_write_register(ViPipe, 0x3128, 0x04); + imx307_slave_write_register(ViPipe, 0x3129, 0x00); + imx307_slave_write_register(ViPipe, 0x313B, 0x41); + imx307_slave_write_register(ViPipe, 0x315E, 0x1A); + imx307_slave_write_register(ViPipe, 0x3164, 0x1A); + imx307_slave_write_register(ViPipe, 0x317C, 0x00); + imx307_slave_write_register(ViPipe, 0x31EC, 0x0E); + imx307_slave_write_register(ViPipe, 0x3405, 0x00); /* Repetition*/ + imx307_slave_write_register(ViPipe, 0x3407, 0x01); /* physical_lane_nl*/ + imx307_slave_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx307_slave_write_register(ViPipe, 0x3415, 0x00); /* NULL0_SIZE_V, set to 00h when DOL*/ + imx307_slave_write_register(ViPipe, 0x3418, 0xB4); /* y_out_size*/ + imx307_slave_write_register(ViPipe, 0x3419, 0x08); /* y_out_size*/ + imx307_slave_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx307_slave_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx307_slave_write_register(ViPipe, 0x3443, 0x01); /* csi_lane_mode*/ + imx307_slave_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx307_slave_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx307_slave_write_register(ViPipe, 0x3446, 0x77); /* tclkpost*/ + imx307_slave_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx307_slave_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx307_slave_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx307_slave_write_register(ViPipe, 0x344A, 0x47); /* thsprepare*/ + imx307_slave_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx307_slave_write_register(ViPipe, 0x344C, 0x37); /* tclktrail*/ + imx307_slave_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx307_slave_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx307_slave_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx307_slave_write_register(ViPipe, 0x3450, 0xFF); /* tclkzero*/ + imx307_slave_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx307_slave_write_register(ViPipe, 0x3452, 0x3F); /* tclkprepare*/ + imx307_slave_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx307_slave_write_register(ViPipe, 0x3454, 0x37); /* tlpx*/ + imx307_slave_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx307_slave_write_register(ViPipe, 0x3472, 0xA0); /* x_out_size*/ + imx307_slave_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx307_slave_write_register(ViPipe, 0x347B, 0x23); /**/ + imx307_slave_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx307_slave_default_reg_init(ViPipe); + + if (g_au16Imx307_Slave_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + imx307_slave_write_register(ViPipe, 0x30F0, 0xF0); + imx307_slave_write_register(ViPipe, 0x3010, 0x21); + } else { + imx307_slave_write_register(ViPipe, 0x30F0, 0x64); + imx307_slave_write_register(ViPipe, 0x3010, 0x61); + } + + imx307_slave_write_register(ViPipe, 0x3000, 0x00); /* standby */ + + if (!g_au16Imx307_Slave_UseHwSync[ViPipe]) { + delay_ms(20); + imx307_slave_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx307_slave_write_register(ViPipe, 0x304b, 0x0a); + } else + imx307_slave_write_register(ViPipe, 0x3106, 0x40); /* XVS/XHS sub-sampling */ + + printf("===Imx307 sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) Slave init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327/Makefile b/middleware/v2/component/isp/sensor/cv181x/sony_imx327/Makefile new file mode 100644 index 000000000..c0d94bc4a --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx327.a +TARGET_SO = $(MW_LIB)/libsns_imx327.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327/imx327_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx327/imx327_cmos.c new file mode 100644 index 000000000..adf621d8e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327/imx327_cmos.c @@ -0,0 +1,1206 @@ +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "imx327_cmos_ex.h" +#include "imx327_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX327_ID 327 +#define SENSOR_IMX327_WIDTH 1920 +#define SENSOR_IMX327_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx327[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX327_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx327[dev]) +#define IMX327_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx327[dev] = pstCtx) +#define IMX327_SENSOR_RESET_CTX(dev) (g_pastImx327[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunImx327_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx327_GainMode[VI_MAX_PIPE_NUM] = {0}; + +IMX327_STATE_S g_astImx327_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx327_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx327 Lines Range*****/ +#define IMX327_FULL_LINES_MAX (0x3FFFF) +#define IMX327_FULL_LINES_MAX_2TO1_WDR (0x3FFFF) // considering the YOUT_SIZE and bad frame +#define IMX327_VMAX_1080P30_LINEAR 1125 + +/*****Imx327 Register Address*****/ +#define IMX327_HOLD_ADDR 0x3001 +#define IMX327_SHS1_ADDR 0x3020 +#define IMX327_SHS2_ADDR 0x3024 +#define IMX327_GAIN_ADDR 0x3014 +#define IMX327_GAIN1_ADDR 0x30F2 +#define IMX327_HCG_ADDR 0x3009 +#define IMX327_VMAX_ADDR 0x3018 +#define IMX327_YOUT_ADDR 0x3418 +#define IMX327_RHS1_ADDR 0x3030 +#define IMX327_TABLE_END 0xffff + +#define IMX327_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 fps = 30; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + if (pstSnsState->u8ImgMode == IMX327_MODE_1080P60) + fps = 60; + +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX327_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * fps); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * fps / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + if (pstSnsState->u8ImgMode == IMX327_MODE_1080P60) { + pstAeSnsDft->f32Fps = g_astImx327_mode[IMX327_MODE_1080P60].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_mode[IMX327_MODE_1080P60].f32MinFps; + } else { + pstAeSnsDft->f32Fps = g_astImx327_mode[IMX327_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_mode[IMX327_MODE_1080P30].f32MinFps; + } + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astImx327_mode[IMX327_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_mode[IMX327_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = IMX327_VMAX_1080P30_LINEAR; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astImx327_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx327_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx327_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case IMX327_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_FULL_LINES_MAX_2TO1_WDR) ? IMX327_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case IMX327_MODE_1080P30: + case IMX327_MODE_1080P60: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_FULL_LINES_MAX) ? IMX327_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } else { + pstSnsRegsInfo->astI2cData[DOL2_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx327_State[ViPipe].u32RHS1_MAX = (u32VMAX - g_astImx327_State[ViPipe].u32BRL) * 2 - 21; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHS1 = 0; + CVI_U32 u32SHS2 = 0; + CVI_U32 u32YOUTSIZE; + CVI_U32 u16BRL = 0; + + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u16BRL = g_astImx327_mode[pstSnsState->u8ImgMode].u16BRL; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[0] < u32LongIntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], u32LongIntTime - 1); + return CVI_FAILURE; + } + u32SHS2 = pstSnsState->au32FL[0] - u32LongIntTime - 1; + + u32SHS1 = (u32ShortIntTime % 2) + 2; + u32RHS1 = u32ShortIntTime + u32SHS1 + 1; + g_astImx327_State[ViPipe].u32RHS1 = u32RHS1; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - (u32SHS1 + 1); + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[0] - (u32SHS2 + 1); + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + u32YOUTSIZE = (u16BRL + (u32RHS1 - 1) / 2) * 2; + u32YOUTSIZE = (u32YOUTSIZE >= 0x1FFF) ? 0x1FFF : u32YOUTSIZE; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHS1 = %d\n", u32ShortIntTime, u32SHS1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d u32YOUTSIZE = %d\n", ViPipe, u32RHS1, u32YOUTSIZE); + + pstSnsRegsInfo->astI2cData[DOL2_SHS1_0].u32Data = (u32SHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_1].u32Data = ((u32SHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_2].u32Data = ((u32SHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHS2_0].u32Data = (u32SHS2 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_1].u32Data = ((u32SHS2 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_2].u32Data = ((u32SHS2 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_0].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_1].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_2].u32Data = ((u32RHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_0].u32Data = (u32YOUTSIZE & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_1].u32Data = ((u32YOUTSIZE & 0x1F00) >> 8); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if (pstSnsState->au32FL[0] < *u32IntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], *u32IntTime - 1); + return CVI_FAILURE; + } + u32Value = pstSnsState->au32FL[0] - *u32IntTime - 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2].u32Data = ((u32Value & 0x30000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 327567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32HCG = g_astImx327_State[ViPipe].u8Hcg; + CVI_U32 u16Mode = g_au16Imx327_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = (u32HCG & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + CVI_U8 bEnableHCG = 0; + + if (pu32Again[0] >= 20 && pu32Again[1] >= 20) { + /* hcg bit[4]*/ + u32HCG |= 0x10; + bEnableHCG = 1; + } + + u32Again = pu32Again[1] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + + u32Again = pu32Again[0] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN1].u32Data = (u32Tmp & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + if (u32HCG > 0xFF) { + u32HCG = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 2 : 2; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 10; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx327_State[ViPipe].u32RHS1_MAX - 3)) ? + (g_astImx327_State[ViPipe].u32RHS1_MAX - 3) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX327_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx327_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX327_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = IMX327_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx327_mode[pstSnsState->u8ImgMode].u32VtsDef; + if (pstSnsState->u8ImgMode == IMX327_MODE_1080P60) + g_astImx327_State[ViPipe].u8Hcg = 0x1; + else + g_astImx327_State[ViPipe].u8Hcg = 0x2; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX327_MODE_1080P30) + pstSnsState->u8ImgMode = IMX327_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + g_astImx327_State[ViPipe].u8Hcg = 0x1; + if (pstSnsState->u8ImgMode == IMX327_MODE_1080P30_WDR) { + pstSnsState->u32FLStd = g_astImx327_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx327_State[ViPipe].u32BRL = g_astImx327_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1080p\n"); + } + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx327_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 2; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx327_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx327_addr_byte; + pstI2c_data[i].u32DataByteNum = imx327_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_HOLD].u32RegAddr = IMX327_HOLD_ADDR; + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_SHS1_0].u32RegAddr = IMX327_SHS1_ADDR; + pstI2c_data[DOL2_SHS1_1].u32RegAddr = IMX327_SHS1_ADDR + 1; + pstI2c_data[DOL2_SHS1_2].u32RegAddr = IMX327_SHS1_ADDR + 2; + + pstI2c_data[DOL2_GAIN].u32RegAddr = IMX327_GAIN_ADDR; + pstI2c_data[DOL2_HCG].u32RegAddr = IMX327_HCG_ADDR; + pstI2c_data[DOL2_HCG].u8DelayFrmNum = 1; + pstI2c_data[DOL2_GAIN1].u32RegAddr = IMX327_GAIN1_ADDR; + pstI2c_data[DOL2_RHS1_0].u32RegAddr = IMX327_RHS1_ADDR; + pstI2c_data[DOL2_RHS1_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_1].u32RegAddr = IMX327_RHS1_ADDR + 1; + pstI2c_data[DOL2_RHS1_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_2].u32RegAddr = IMX327_RHS1_ADDR + 2; + pstI2c_data[DOL2_RHS1_2].u8DelayFrmNum = 1; + pstI2c_data[DOL2_SHS2_0].u32RegAddr = IMX327_SHS2_ADDR; + pstI2c_data[DOL2_SHS2_1].u32RegAddr = IMX327_SHS2_ADDR + 1; + pstI2c_data[DOL2_SHS2_2].u32RegAddr = IMX327_SHS2_ADDR + 2; + pstI2c_data[DOL2_VMAX_0].u32RegAddr = IMX327_VMAX_ADDR; + pstI2c_data[DOL2_VMAX_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_1].u32RegAddr = IMX327_VMAX_ADDR + 1; + pstI2c_data[DOL2_VMAX_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_2].u32RegAddr = IMX327_VMAX_ADDR + 2; + pstI2c_data[DOL2_VMAX_2].u8DelayFrmNum = 1; + + pstI2c_data[DOL2_YOUT_SIZE_0].u32RegAddr = IMX327_YOUT_ADDR; + pstI2c_data[DOL2_YOUT_SIZE_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u32RegAddr = IMX327_YOUT_ADDR + 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_REL].u32RegAddr = IMX327_HOLD_ADDR; + pstI2c_data[DOL2_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 1; + break; + default: + pstI2c_data[LINEAR_HOLD].u32RegAddr = IMX327_HOLD_ADDR; + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_SHS1_0].u32RegAddr = IMX327_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1].u32RegAddr = IMX327_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2].u32RegAddr = IMX327_SHS1_ADDR + 2; + pstI2c_data[LINEAR_GAIN].u32RegAddr = IMX327_GAIN_ADDR; + pstI2c_data[LINEAR_HCG].u32RegAddr = IMX327_HCG_ADDR; + pstI2c_data[LINEAR_HCG].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VMAX_0].u32RegAddr = IMX327_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1].u32RegAddr = IMX327_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_2].u32RegAddr = IMX327_VMAX_ADDR + 2; + pstI2c_data[LINEAR_REL].u32RegAddr = IMX327_HOLD_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[DOL2_REL].u32Data = 0; + pstI2c_data[DOL2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX327_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX327_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_MODE_1080P30_WDR; + g_astImx327_State[ViPipe].u32BRL = 1109; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSensorImageMode->f32Fps <= 60) { + u8SensorImageMode = IMX327_MODE_1080P60; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx327_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx327_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx327_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = IMX327_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = IMX327_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[0] = IMX327_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[1] = IMX327_VMAX_1080P30_LINEAR; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx327_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx327_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx327_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx327_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx327_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx327_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx327_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx327_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX327_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX327_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX327_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX327_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX327_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX327_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx327_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return imx327_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsImx327_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx327_standby, + .pfnRestart = imx327_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx327_write_register, + .pfnReadReg = imx327_read_register, + .pfnSetBusInfo = imx327_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327/imx327_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx327/imx327_cmos_ex.h new file mode 100644 index 000000000..22f02af1e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327/imx327_cmos_ex.h @@ -0,0 +1,117 @@ +#ifndef __IMX327_CMOS_EX_H_ +#define __IMX327_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum imx327_linear_regs_e { + LINEAR_HOLD = 0, + LINEAR_SHS1_0, + LINEAR_SHS1_1, + LINEAR_SHS1_2, + LINEAR_GAIN, + LINEAR_HCG, + LINEAR_VMAX_0, + LINEAR_VMAX_1, + LINEAR_VMAX_2, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum imx327_dol2_regs_e { + DOL2_HOLD = 0, + DOL2_SHS1_0, + DOL2_SHS1_1, + DOL2_SHS1_2, + DOL2_GAIN, + DOL2_HCG, + DOL2_GAIN1, + DOL2_RHS1_0, + DOL2_RHS1_1, + DOL2_RHS1_2, + DOL2_SHS2_0, + DOL2_SHS2_1, + DOL2_SHS2_2, + DOL2_VMAX_0, + DOL2_VMAX_1, + DOL2_VMAX_2, + DOL2_YOUT_SIZE_0, + DOL2_YOUT_SIZE_1, + DOL2_REL, + DOL2_REGS_NUM +}; + +typedef enum _IMX327_MODE_E { + IMX327_MODE_1080P30 = 0, + IMX327_MODE_1080P60, + IMX327_MODE_LINEAR_NUM, + IMX327_MODE_1080P30_WDR = IMX327_MODE_LINEAR_NUM, + IMX327_MODE_NUM +} IMX327_MODE_E; + +typedef struct _IMX327_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX327_STATE_S; + +typedef struct _IMX327_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX327_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx327[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx327_BusInfo[]; +extern CVI_U16 g_au16Imx327_GainMode[]; +extern const CVI_U8 imx327_i2c_addr; +extern const CVI_U32 imx327_addr_byte; +extern const CVI_U32 imx327_data_byte; +extern void imx327_init(VI_PIPE ViPipe); +extern void imx327_exit(VI_PIPE ViPipe); +extern void imx327_standby(VI_PIPE ViPipe); +extern void imx327_restart(VI_PIPE ViPipe); +extern int imx327_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx327_read_register(VI_PIPE ViPipe, int addr); +extern void imx327_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int imx327_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327/imx327_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx327/imx327_cmos_param.h new file mode 100644 index 000000000..30ca7f88b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327/imx327_cmos_param.h @@ -0,0 +1,465 @@ +#ifndef __IMX327_CMOS_PARAM_H_ +#define __IMX327_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_cmos_ex.h" + +static const IMX327_MODE_S g_astImx327_mode[IMX327_MODE_NUM] = { + [IMX327_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x1130, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX327_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 8, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 2236, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 7, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX327_MODE_1080P60] = { + .name = "1080p60", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 60, + .f32MinFps = 0.26, /* 1125 * 60 / 0x3FFFF */ + .u32HtsDef = 0x898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, +}; + +// F1.8 Lens +#ifdef F18 +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = { + /*************Calibration LUT Table*************/ + .CalibrationCoef = { + { //iso 100 + {0.03243722766637802, 3.855583906173706}, //B: slope, intercept + {0.024103811010718346, 3.9538209438323975}, //Gb: slope, intercept + {0.022307759150862694, 4.970882892608643}, //Gr: slope, intercept + {0.02794046327471733, 3.1342978477478027}, //R: slope, intercept + }, + { //iso 200 + {0.03799639642238617, 5.526010990142822}, //B: slope, intercept + {0.02662081830203533, 7.61380672454834}, //Gb: slope, intercept + {0.025447502732276917, 8.231551170349121}, //Gr: slope, intercept + {0.032776281237602234, 5.149646282196045}, //R: slope, intercept + }, + { //iso 400 + {0.050715841352939606, 7.763713836669922}, //B: slope, intercept + {0.032093651592731476, 12.182195663452148}, //Gb: slope, intercept + {0.030688125640153885, 12.43420696258545}, //Gr: slope, intercept + {0.040235333144664764, 8.544824600219727}, //R: slope, intercept + }, + { //iso 800 + {0.06888508796691895, 10.970534324645996}, //B: slope, intercept + {0.03813415393233299, 19.28471565246582}, //Gb: slope, intercept + {0.03805641457438469, 19.625152587890625}, //Gr: slope, intercept + {0.04966627061367035, 12.69924545288086}, //R: slope, intercept + }, + { //iso 1600 + {0.08884920179843903, 15.890214920043945}, //B: slope, intercept + {0.046779610216617584, 30.772066116333008}, //Gb: slope, intercept + {0.045214589685201645, 31.489530563354492}, //Gr: slope, intercept + {0.06512749195098877, 20.34792137145996}, //R: slope, intercept + }, + { //iso 3200 + {0.1241341084241867, 20.70075225830078}, //B: slope, intercept + {0.05977431312203407, 45.98811721801758}, //Gb: slope, intercept + {0.05858884006738663, 47.11114501953125}, //Gr: slope, intercept + {0.08636551350355148, 30.561227798461914}, //R: slope, intercept + }, + { //iso 6400 + {0.1791478991508484, 30.803356170654297}, //B: slope, intercept + {0.09205856174230576, 65.60118103027344}, //Gb: slope, intercept + {0.08692053705453873, 69.85540771484375}, //Gr: slope, intercept + {0.12406758964061737, 45.617835998535156}, //R: slope, intercept + }, + { //iso 12800 + {0.2464703917503357, 44.136966705322266}, //B: slope, intercept + {0.11594483256340027, 97.8382797241211}, //Gb: slope, intercept + {0.11075824499130249, 101.47943115234375}, //Gr: slope, intercept + {0.17024046182632446, 66.47021484375}, //R: slope, intercept + }, + { //iso 25600 + {0.3376912772655487, 68.80254364013672}, //B: slope, intercept + {0.15025299787521362, 145.10032653808594}, //Gb: slope, intercept + {0.14386454224586487, 148.1698455810547}, //Gr: slope, intercept + {0.23965470492839813, 96.42337036132812}, //R: slope, intercept + }, + { //iso 51200 + {0.4279725253582001, 117.4070816040039}, //B: slope, intercept + {0.17134547233581543, 243.6494598388672}, //Gb: slope, intercept + {0.16668814420700073, 241.21603393554688}, //Gr: slope, intercept + {0.29862311482429504, 156.05364990234375}, //R: slope, intercept + }, + { //iso 102400 + {0.534967303276062, 181.45118713378906}, //B: slope, intercept + {0.2024478018283844, 365.00177001953125}, //Gb: slope, intercept + {0.20520392060279846, 362.1013488769531}, //Gr: slope, intercept + {0.40533769130706787, 241.33485412597656}, //R: slope, intercept + }, + { //iso 204800 + {0.6578512191772461, 286.16363525390625}, //B: slope, intercept + {0.223756805062294, 551.998779296875}, //Gb: slope, intercept + {0.22110669314861298, 562.9724731445312}, //Gr: slope, intercept + {0.4937806725502014, 371.5768737792969}, //R: slope, intercept + }, + { //iso 409600 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + //------------------------------------------------------------- + { //iso 819200 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + { //iso 1638400 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + { //iso 3276800 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + } + /*********************************************/ +}; +#endif + +// F1.0 Lens +#ifdef F10 +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.038478557020425796517, 2.14561891555786132813}, //B: slope, intercept + {0.03633839637041091919, 0.17788629233837127686}, //Gb: slope, intercept + {0.03592018783092498779, 0.21645727753639221191}, //Gr: slope, intercept + {0.03592239692807197571, 1.48806631565093994141}, //R: slope, intercept + }, + { //iso 200 + {0.04168356582522392273, 4.38879251480102539063}, //B: slope, intercept + {0.03754633292555809021, 3.21502065658569335938}, //Gb: slope, intercept + {0.03759334236383438110, 3.48370814323425292969}, //Gr: slope, intercept + {0.03719408065080642700, 4.63629007339477539063}, //R: slope, intercept + }, + { //iso 400 + {0.05050259083509445190, 6.85188436508178710938}, //B: slope, intercept + {0.04007886722683906555, 8.49916744232177734375}, //Gb: slope, intercept + {0.03934165090322494507, 8.68585968017578125000}, //Gr: slope, intercept + {0.04134147986769676208, 8.89877605438232421875}, //R: slope, intercept + }, + { //iso 800 + {0.04306267201900482178, 15.41853904724121093750}, //B: slope, intercept + {0.03570587188005447388, 18.56583213806152343750}, //Gb: slope, intercept + {0.03533876314759254456, 19.57685661315917968750}, //Gr: slope, intercept + {0.03832129389047622681, 17.90320968627929687500}, //R: slope, intercept + }, + { //iso 1600 + {0.06225715205073356628, 21.87150573730468750000}, //B: slope, intercept + {0.04437549784779548645, 30.87298965454101562500}, //Gb: slope, intercept + {0.04517432302236557007, 29.32084465026855468750}, //Gr: slope, intercept + {0.05255207046866416931, 26.26001358032226562500}, //R: slope, intercept + }, + { //iso 3200 + {0.07859147340059280396, 32.48978424072265625000}, //B: slope, intercept + {0.05918205901980400085, 45.08999633789062500000}, //Gb: slope, intercept + {0.05711782723665237427, 48.86173248291015625000}, //Gr: slope, intercept + {0.07310666143894195557, 36.88227081298828125000}, //R: slope, intercept + }, + { //iso 6400 + {0.11759266257286071777, 45.81345367431640625000}, //B: slope, intercept + {0.07679814100265502930, 69.04325866699218750000}, //Gb: slope, intercept + {0.07774948328733444214, 66.52905273437500000000}, //Gr: slope, intercept + {0.10286796092987060547, 51.73817443847656250000}, //R: slope, intercept + }, + { //iso 12800 + {0.15860086679458618164, 64.15329742431640625000}, //B: slope, intercept + {0.10511043667793273926, 91.36695098876953125000}, //Gb: slope, intercept + {0.10040879994630813599, 92.05632781982421875000}, //Gr: slope, intercept + {0.13499946892261505127, 73.36162567138671875000}, //R: slope, intercept + }, + { //iso 25600 + {0.22810073196887969971, 100.01741027832031250000}, //B: slope, intercept + {0.14736327528953552246, 146.62678527832031250000}, //Gb: slope, intercept + {0.15503610670566558838, 136.06079101562500000000}, //Gr: slope, intercept + {0.20250190794467926025, 112.74269104003906250000}, //R: slope, intercept + }, + { //iso 51200 + {0.29010805487632751465, 155.05882263183593750000}, //B: slope, intercept + {0.20221179723739624023, 210.97210693359375000000}, //Gb: slope, intercept + {0.21603405475616455078, 201.40393066406250000000}, //Gr: slope, intercept + {0.27819159626960754395, 165.48959350585937500000}, //R: slope, intercept + }, + { //iso 102400 + {0.40437409281730651855, 245.11883544921875000000}, //B: slope, intercept + {0.26703724265098571777, 345.62698364257812500000}, //Gb: slope, intercept + {0.27536261081695556641, 318.75701904296875000000}, //Gr: slope, intercept + {0.44441288709640502930, 222.47651672363281250000}, //R: slope, intercept + }, + { //iso 204800 + {0.48959052562713623047, 383.21560668945312500000}, //B: slope, intercept + {0.37694901227951049805, 442.55813598632812500000}, //Gb: slope, intercept + {0.38724529743194580078, 449.72384643554687500000}, //Gr: slope, intercept + {0.60220617055892944336, 318.92291259765625000000}, //R: slope, intercept + }, + { //iso 409600 + {0.59899300336837768555, 580.43414306640625000000}, //B: slope, intercept + {0.43681395053863525391, 700.22204589843750000000}, //Gb: slope, intercept + {0.50216537714004516602, 633.89794921875000000000}, //Gr: slope, intercept + {0.77917146682739257813, 453.13076782226562500000}, //R: slope, intercept + }, + { //iso 819200 + {0.54956322908401489258, 871.06585693359375000000}, //B: slope, intercept + {0.38088488578796386719, 1040.72192382812500000000}, //Gb: slope, intercept + {0.47245877981185913086, 937.37445068359375000000}, //Gr: slope, intercept + {0.70387065410614013672, 730.45373535156250000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.67512661218643188477, 797.11108398437500000000}, //B: slope, intercept + {0.50457936525344848633, 962.40740966796875000000}, //Gb: slope, intercept + {0.59857457876205444336, 856.90533447265625000000}, //Gr: slope, intercept + {0.74725526571273803711, 740.04290771484375000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.79927802085876464844, 687.07183837890625000000}, //B: slope, intercept + {0.81719654798507690430, 687.01580810546875000000}, //Gb: slope, intercept + {0.83395677804946899414, 658.91857910156250000000}, //Gr: slope, intercept + {0.72803622484207153320, 746.19427490234375000000}, //R: slope, intercept + }, +} }; +#endif + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {240, 240, 240, 240, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1088, 1088, 1088, 1088 +#endif + }, + .stAuto = { + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, +#endif + }, + }, +}; + + +struct combo_dev_attr_s imx327_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {2, 3, 1, 4, 0}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_DOL, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327/imx327_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx327/imx327_sensor_ctl.c new file mode 100644 index 000000000..542170ca1 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327/imx327_sensor_ctl.c @@ -0,0 +1,499 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_cmos_ex.h" + +static void imx327_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void imx327_linear_1080p30_init(VI_PIPE ViPipe); +static void imx327_linear_1080p60_init(VI_PIPE ViPipe); + +const CVI_U8 imx327_i2c_addr = 0x1A; +const CVI_U32 imx327_addr_byte = 2; +const CVI_U32 imx327_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx327_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx327_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx327_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int imx327_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx327_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (imx327_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, imx327_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, imx327_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (imx327_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int imx327_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx327_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx327_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx327_addr_byte + imx327_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx327_standby(VI_PIPE ViPipe) +{ + imx327_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ +} + +void imx327_restart(VI_PIPE ViPipe) +{ + imx327_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_write_register(ViPipe, 0x304b, 0x0a); +} + +void imx327_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx327[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx327_write_register(ViPipe, + g_pastImx327[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx327[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define IMX327_CHIP_ID_ADDR 0x31dc +#define IMX327_CHIP_ID 0x6 +#define IMX327_CHIP_ID_MASK 0x6 + +void imx327_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = imx327_read_register(ViPipe, 0x3007) & ~0x3; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + imx327_write_register(ViPipe, 0x3007, val); +} + +int imx327_probe(VI_PIPE ViPipe) +{ + int nVal; + + usleep(100); + if (imx327_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = imx327_read_register(ViPipe, IMX327_CHIP_ID_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((nVal & IMX327_CHIP_ID_MASK) != IMX327_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void imx327_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastImx327[ViPipe]->enWDRMode; + u8ImgMode = g_pastImx327[ViPipe]->u8ImgMode; + + imx327_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == IMX327_MODE_1080P30_WDR) { + imx327_wdr_1080p30_2to1_init(ViPipe); + } + } else { + if (u8ImgMode == IMX327_MODE_1080P60) + imx327_linear_1080p60_init(ViPipe); + else + imx327_linear_1080p30_init(ViPipe); + } + g_pastImx327[ViPipe]->bInit = CVI_TRUE; +} + +void imx327_exit(VI_PIPE ViPipe) +{ + imx327_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void imx327_linear_1080p30_init(VI_PIPE ViPipe) +{ + imx327_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx327_write_register(ViPipe, 0x3005, 0x01); /* ADBIT 10bit*/ + imx327_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx327_write_register(ViPipe, 0x3009, 0x02); /**/ + imx327_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx327_write_register(ViPipe, 0x3010, 0x21); + imx327_write_register(ViPipe, 0x3011, 0x02); + imx327_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx327_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx327_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx327_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx327_write_register(ViPipe, 0x301C, 0x30); /* HMAX[7:0], TBD*/ + imx327_write_register(ViPipe, 0x301D, 0x11); /* HMAX[15:8]*/ + imx327_write_register(ViPipe, 0x3020, 0x8C); /* SHS[7:0], TBD*/ + imx327_write_register(ViPipe, 0x3021, 0x01); /* SHS[15:8]*/ + imx327_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx327_write_register(ViPipe, 0x3046, 0x01); + imx327_write_register(ViPipe, 0x304B, 0x0A); + imx327_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx327_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx327_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx327_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx327_write_register(ViPipe, 0x309E, 0x4A); + imx327_write_register(ViPipe, 0x309F, 0x4A); + imx327_write_register(ViPipe, 0x30D2, 0x19); + imx327_write_register(ViPipe, 0x30D7, 0x03); + imx327_write_register(ViPipe, 0x3129, 0x00); + imx327_write_register(ViPipe, 0x313B, 0x61); + imx327_write_register(ViPipe, 0x315E, 0x1A); + imx327_write_register(ViPipe, 0x3164, 0x1A); + imx327_write_register(ViPipe, 0x317C, 0x00); + imx327_write_register(ViPipe, 0x31EC, 0x0E); + imx327_write_register(ViPipe, 0x3405, 0x20); /* Repetition*/ + imx327_write_register(ViPipe, 0x3407, 0x03); /* physical_lane_nl*/ + imx327_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx327_write_register(ViPipe, 0x3418, 0x49); /* y_out_size*/ + imx327_write_register(ViPipe, 0x3419, 0x04); /* y_out_size*/ + imx327_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx327_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx327_write_register(ViPipe, 0x3443, 0x03); /* csi_lane_mode*/ + imx327_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx327_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx327_write_register(ViPipe, 0x3446, 0x47); /* tclkpost*/ + imx327_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx327_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx327_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx327_write_register(ViPipe, 0x344A, 0x17); /* thsprepare*/ + imx327_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx327_write_register(ViPipe, 0x344C, 0x0F); /* tclktrail*/ + imx327_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx327_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx327_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx327_write_register(ViPipe, 0x3450, 0x47); /* tclkzero*/ + imx327_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx327_write_register(ViPipe, 0x3452, 0x0F); /* tclkprepare*/ + imx327_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx327_write_register(ViPipe, 0x3454, 0x0F); /* tlpx*/ + imx327_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx327_write_register(ViPipe, 0x3472, 0x9C); /* x_out_size*/ + imx327_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx327_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx327_default_reg_init(ViPipe); + + imx327_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_write_register(ViPipe, 0x304b, 0x0a); + + printf("ViPipe:%d,===IMX327 1080P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void imx327_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + imx327_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx327_write_register(ViPipe, 0x3005, 0x01); /* ADBIT*/ + imx327_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx327_write_register(ViPipe, 0x3009, 0x01); /**/ + imx327_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx327_write_register(ViPipe, 0x300C, 0x11); /* WDMODE [0] 0:Normal, 1:DOL, WDSEL [5:4] 1:DOL 2 frames*/ + imx327_write_register(ViPipe, 0x3011, 0x02); + imx327_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx327_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx327_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx327_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx327_write_register(ViPipe, 0x301C, 0x98); /* HMAX[7:0], TBD*/ + imx327_write_register(ViPipe, 0x301D, 0x08); /* HMAX[15:8]*/ + imx327_write_register(ViPipe, 0x3020, 0x02); /* SHS[7:0], TBD*/ + imx327_write_register(ViPipe, 0x3021, 0x00); /* SHS[15:8]*/ + imx327_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx327_write_register(ViPipe, 0x3024, 0xC9); /* SHS2[7:0], TBD*/ + imx327_write_register(ViPipe, 0x3025, 0x07); /* SHS2[15:8]*/ + imx327_write_register(ViPipe, 0x3026, 0x00); /* SHS2[19:16]*/ + imx327_write_register(ViPipe, 0x3030, 0x0B); /* RHS1[7:0], TBD*/ + imx327_write_register(ViPipe, 0x3031, 0x00); /* RHS1[15:8]*/ + imx327_write_register(ViPipe, 0x3032, 0x00); /* RHS1[19:16]*/ + imx327_write_register(ViPipe, 0x3045, 0x05); /* DOLSCDEN [0] 1: pattern1 0: pattern2*/ + imx327_write_register(ViPipe, 0x3046, 0x01); + imx327_write_register(ViPipe, 0x304B, 0x0A); + imx327_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx327_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx327_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx327_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx327_write_register(ViPipe, 0x309E, 0x4A); + imx327_write_register(ViPipe, 0x309F, 0x4A); + imx327_write_register(ViPipe, 0x30D2, 0x19); + imx327_write_register(ViPipe, 0x30D7, 0x03); + imx327_write_register(ViPipe, 0x3106, 0x11); /*DOLHBFIXEN[7] 0: pattern1 1: pattern2*/ + imx327_write_register(ViPipe, 0x3129, 0x00); + imx327_write_register(ViPipe, 0x313B, 0x61); + imx327_write_register(ViPipe, 0x315E, 0x1A); + imx327_write_register(ViPipe, 0x3164, 0x1A); + imx327_write_register(ViPipe, 0x317C, 0x00); + imx327_write_register(ViPipe, 0x31EC, 0x0E); + imx327_write_register(ViPipe, 0x3405, 0x10); /* Repetition*/ + imx327_write_register(ViPipe, 0x3407, 0x03); /* physical_lane_nl*/ + imx327_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx327_write_register(ViPipe, 0x3415, 0x00); /* NULL0_SIZE_V, set to 00h when DOL*/ + imx327_write_register(ViPipe, 0x3418, 0xB4); /* y_out_size*/ + imx327_write_register(ViPipe, 0x3419, 0x08); /* y_out_size*/ + imx327_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx327_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx327_write_register(ViPipe, 0x3443, 0x03); /* csi_lane_mode*/ + imx327_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx327_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx327_write_register(ViPipe, 0x3446, 0x57); /* tclkpost*/ + imx327_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx327_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx327_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx327_write_register(ViPipe, 0x344A, 0x1F); /* thsprepare*/ + imx327_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx327_write_register(ViPipe, 0x344C, 0x1F); /* tclktrail*/ + imx327_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx327_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx327_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx327_write_register(ViPipe, 0x3450, 0x77); /* tclkzero*/ + imx327_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx327_write_register(ViPipe, 0x3452, 0x1F); /* tclkprepare*/ + imx327_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx327_write_register(ViPipe, 0x3454, 0x17); /* tlpx*/ + imx327_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx327_write_register(ViPipe, 0x3472, 0xA0); /* x_out_size*/ + imx327_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx327_write_register(ViPipe, 0x347B, 0x23); /**/ + imx327_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx327_default_reg_init(ViPipe); + + if (g_au16Imx327_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + imx327_write_register(ViPipe, 0x30F0, 0xF0); + imx327_write_register(ViPipe, 0x3010, 0x21); + } else { + imx327_write_register(ViPipe, 0x30F0, 0x64); + imx327_write_register(ViPipe, 0x3010, 0x61); + } + + imx327_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_write_register(ViPipe, 0x304b, 0x0a); + + printf("===Imx327 sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} + +/* 1080P60 and 1080P50 */ +static void imx327_linear_1080p60_init(VI_PIPE ViPipe) +{ + imx327_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx327_write_register(ViPipe, 0x3005, 0x01); /* ADBIT 10bit*/ + imx327_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx327_write_register(ViPipe, 0x3009, 0x01); /**/ + imx327_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx327_write_register(ViPipe, 0x3010, 0x21); + imx327_write_register(ViPipe, 0x3011, 0x00); + imx327_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx327_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx327_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx327_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx327_write_register(ViPipe, 0x301C, 0x98); /* HMAX[7:0], TBD*/ + imx327_write_register(ViPipe, 0x301D, 0x08); /* HMAX[15:8]*/ + imx327_write_register(ViPipe, 0x3020, 0x8C); /* SHS[7:0], TBD*/ + imx327_write_register(ViPipe, 0x3021, 0x01); /* SHS[15:8]*/ + imx327_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx327_write_register(ViPipe, 0x3046, 0x01); + imx327_write_register(ViPipe, 0x304B, 0x0A); + imx327_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx327_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx327_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx327_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx327_write_register(ViPipe, 0x309E, 0x4A); + imx327_write_register(ViPipe, 0x309F, 0x4A); + imx327_write_register(ViPipe, 0x30D2, 0x19); + imx327_write_register(ViPipe, 0x30D7, 0x03); + imx327_write_register(ViPipe, 0x3129, 0x00); + imx327_write_register(ViPipe, 0x313B, 0x61); + imx327_write_register(ViPipe, 0x315E, 0x1A); + imx327_write_register(ViPipe, 0x3164, 0x1A); + imx327_write_register(ViPipe, 0x317C, 0x00); + imx327_write_register(ViPipe, 0x31EC, 0x0E); + imx327_write_register(ViPipe, 0x3405, 0x10); /* Repetition*/ + imx327_write_register(ViPipe, 0x3407, 0x03); /* physical_lane_nl*/ + imx327_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx327_write_register(ViPipe, 0x3418, 0x49); /* y_out_size*/ + imx327_write_register(ViPipe, 0x3419, 0x04); /* y_out_size*/ + imx327_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx327_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx327_write_register(ViPipe, 0x3443, 0x03); /* csi_lane_mode*/ + imx327_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx327_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx327_write_register(ViPipe, 0x3446, 0x57); /* tclkpost*/ + imx327_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx327_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx327_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx327_write_register(ViPipe, 0x344A, 0x1F); /* thsprepare*/ + imx327_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx327_write_register(ViPipe, 0x344C, 0x1F); /* tclktrail*/ + imx327_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx327_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx327_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx327_write_register(ViPipe, 0x3450, 0x77); /* tclkzero*/ + imx327_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx327_write_register(ViPipe, 0x3452, 0x1F); /* tclkprepare*/ + imx327_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx327_write_register(ViPipe, 0x3454, 0x17); /* tlpx*/ + imx327_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx327_write_register(ViPipe, 0x3472, 0x9C); /* x_out_size*/ + imx327_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx327_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx327_default_reg_init(ViPipe); + + imx327_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_write_register(ViPipe, 0x304b, 0x0a); + + printf("ViPipe:%d,===IMX327 1080P 60fps 12bit LINE Init OK!===\n", ViPipe); +} + diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_2L/Makefile b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_2L/Makefile new file mode 100644 index 000000000..7570d61b7 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_2L/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx327_2l.a +TARGET_SO = $(MW_LIB)/libsns_imx327_2l.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_2L/imx327_2l_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_2L/imx327_2l_cmos.c new file mode 100644 index 000000000..c20f4fad6 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_2L/imx327_2l_cmos.c @@ -0,0 +1,1194 @@ +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "imx327_2l_cmos_ex.h" +#include "imx327_2l_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX327_2L_ID 327 +#define SENSOR_IMX327_2L_WIDTH 1920 +#define SENSOR_IMX327_2L_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx327_2l[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX327_2L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx327_2l[dev]) +#define IMX327_2L_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx327_2l[dev] = pstCtx) +#define IMX327_2L_SENSOR_RESET_CTX(dev) (g_pastImx327_2l[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunImx327_2l_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx327_2l_GainMode[VI_MAX_PIPE_NUM] = {0}; + +IMX327_2L_STATE_S g_astImx327_2l_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx327_2l_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx327 Lines Range*****/ +#define IMX327_2L_FULL_LINES_MAX (0x3FFFF) +#define IMX327_2L_FULL_LINES_MAX_2TO1_WDR (0x3FFFF) // considering the YOUT_SIZE and bad frame +#define IMX327_2L_VMAX_1080P30_LINEAR 1125 + +/*****Imx327 Register Address*****/ +#define IMX327_2L_HOLD_ADDR 0x3001 +#define IMX327_2L_SHS1_ADDR 0x3020 +#define IMX327_2L_SHS2_ADDR 0x3024 +#define IMX327_2L_GAIN_ADDR 0x3014 +#define IMX327_2L_GAIN1_ADDR 0x30F2 +#define IMX327_2L_HCG_ADDR 0x3009 +#define IMX327_2L_VMAX_ADDR 0x3018 +#define IMX327_2L_YOUT_ADDR 0x3418 +#define IMX327_2L_RHS1_ADDR 0x3030 +#define IMX327_2L_TABLE_END 0xffff + +#define IMX327_2L_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX327_2L_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astImx327_2l_mode[IMX327_2L_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_2l_mode[IMX327_2L_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astImx327_2l_mode[IMX327_2L_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_2l_mode[IMX327_2L_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = IMX327_2L_VMAX_1080P30_LINEAR; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astImx327_2l_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx327_2l_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx327_2l_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case IMX327_2L_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_2L_FULL_LINES_MAX_2TO1_WDR) ? IMX327_2L_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case IMX327_2L_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_2L_FULL_LINES_MAX) ? IMX327_2L_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } else { + pstSnsRegsInfo->astI2cData[DOL2_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx327_2l_State[ViPipe].u32RHS1_MAX = (u32VMAX - g_astImx327_2l_State[ViPipe].u32BRL) * 2 - 21; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHS1 = 0; + CVI_U32 u32SHS2 = 0; + CVI_U32 u32YOUTSIZE; + CVI_U32 u16BRL = 0; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u16BRL = g_astImx327_2l_mode[pstSnsState->u8ImgMode].u16BRL; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[0] < u32LongIntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], u32LongIntTime - 1); + return CVI_FAILURE; + } + u32SHS2 = pstSnsState->au32FL[0] - u32LongIntTime - 1; + + u32SHS1 = (u32ShortIntTime % 2) + 2; + u32RHS1 = u32ShortIntTime + u32SHS1 + 1; + g_astImx327_2l_State[ViPipe].u32RHS1 = u32RHS1; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - (u32SHS1 + 1); + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[0] - (u32SHS2 + 1); + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + u32YOUTSIZE = (u16BRL + (u32RHS1 - 1) / 2) * 2; + u32YOUTSIZE = (u32YOUTSIZE >= 0x1FFF) ? 0x1FFF : u32YOUTSIZE; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHS1 = %d\n", u32ShortIntTime, u32SHS1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d u32YOUTSIZE = %d\n", ViPipe, u32RHS1, u32YOUTSIZE); + + pstSnsRegsInfo->astI2cData[DOL2_SHS1_0].u32Data = (u32SHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_1].u32Data = ((u32SHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_2].u32Data = ((u32SHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHS2_0].u32Data = (u32SHS2 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_1].u32Data = ((u32SHS2 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_2].u32Data = ((u32SHS2 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_0].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_1].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_2].u32Data = ((u32RHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_0].u32Data = (u32YOUTSIZE & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_1].u32Data = ((u32YOUTSIZE & 0x1F00) >> 8); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if (pstSnsState->au32FL[0] < *u32IntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], *u32IntTime - 1); + return CVI_FAILURE; + } + u32Value = pstSnsState->au32FL[0] - *u32IntTime - 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2].u32Data = ((u32Value & 0x30000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 327567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32HCG = g_astImx327_2l_State[ViPipe].u8Hcg; + CVI_U32 u16Mode = g_au16Imx327_2l_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = (u32HCG & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + CVI_U8 bEnableHCG = 0; + + if (pu32Again[0] >= 20 && pu32Again[1] >= 20) { + /* hcg bit[4]*/ + u32HCG |= 0x10; + bEnableHCG = 1; + } + + u32Again = pu32Again[1] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + + u32Again = pu32Again[0] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN1].u32Data = (u32Tmp & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + if (u32HCG > 0xFF) { + u32HCG = 0xFF; + } + + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 2 : 2; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 10; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx327_2l_State[ViPipe].u32RHS1_MAX - 3)) ? + (g_astImx327_2l_State[ViPipe].u32RHS1_MAX - 3) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX327_2L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx327_2l_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX327_2L_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = IMX327_2L_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx327_2l_mode[pstSnsState->u8ImgMode].u32VtsDef; + g_astImx327_2l_State[ViPipe].u8Hcg = 0x2; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX327_2L_MODE_1080P30) + pstSnsState->u8ImgMode = IMX327_2L_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + g_astImx327_2l_State[ViPipe].u8Hcg = 0x1; + if (pstSnsState->u8ImgMode == IMX327_2L_MODE_1080P30_WDR) { + pstSnsState->u32FLStd = g_astImx327_2l_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx327_2l_State[ViPipe].u32BRL = g_astImx327_2l_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1080p\n"); + } + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx327_2l_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 2; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx327_2l_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx327_2l_addr_byte; + pstI2c_data[i].u32DataByteNum = imx327_2l_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_HOLD].u32RegAddr = IMX327_2L_HOLD_ADDR; + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_SHS1_0].u32RegAddr = IMX327_2L_SHS1_ADDR; + pstI2c_data[DOL2_SHS1_1].u32RegAddr = IMX327_2L_SHS1_ADDR + 1; + pstI2c_data[DOL2_SHS1_2].u32RegAddr = IMX327_2L_SHS1_ADDR + 2; + + pstI2c_data[DOL2_GAIN].u32RegAddr = IMX327_2L_GAIN_ADDR; + pstI2c_data[DOL2_HCG].u32RegAddr = IMX327_2L_HCG_ADDR; + pstI2c_data[DOL2_HCG].u8DelayFrmNum = 1; + pstI2c_data[DOL2_GAIN1].u32RegAddr = IMX327_2L_GAIN1_ADDR; + pstI2c_data[DOL2_RHS1_0].u32RegAddr = IMX327_2L_RHS1_ADDR; + pstI2c_data[DOL2_RHS1_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_1].u32RegAddr = IMX327_2L_RHS1_ADDR + 1; + pstI2c_data[DOL2_RHS1_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_2].u32RegAddr = IMX327_2L_RHS1_ADDR + 2; + pstI2c_data[DOL2_RHS1_2].u8DelayFrmNum = 1; + pstI2c_data[DOL2_SHS2_0].u32RegAddr = IMX327_2L_SHS2_ADDR; + pstI2c_data[DOL2_SHS2_1].u32RegAddr = IMX327_2L_SHS2_ADDR + 1; + pstI2c_data[DOL2_SHS2_2].u32RegAddr = IMX327_2L_SHS2_ADDR + 2; + pstI2c_data[DOL2_VMAX_0].u32RegAddr = IMX327_2L_VMAX_ADDR; + pstI2c_data[DOL2_VMAX_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_1].u32RegAddr = IMX327_2L_VMAX_ADDR + 1; + pstI2c_data[DOL2_VMAX_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_2].u32RegAddr = IMX327_2L_VMAX_ADDR + 2; + pstI2c_data[DOL2_VMAX_2].u8DelayFrmNum = 1; + + pstI2c_data[DOL2_YOUT_SIZE_0].u32RegAddr = IMX327_2L_YOUT_ADDR; + pstI2c_data[DOL2_YOUT_SIZE_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u32RegAddr = IMX327_2L_YOUT_ADDR + 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_REL].u32RegAddr = IMX327_2L_HOLD_ADDR; + pstI2c_data[DOL2_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 1; + break; + default: + pstI2c_data[LINEAR_HOLD].u32RegAddr = IMX327_2L_HOLD_ADDR; + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_SHS1_0].u32RegAddr = IMX327_2L_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1].u32RegAddr = IMX327_2L_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2].u32RegAddr = IMX327_2L_SHS1_ADDR + 2; + pstI2c_data[LINEAR_GAIN].u32RegAddr = IMX327_2L_GAIN_ADDR; + pstI2c_data[LINEAR_HCG].u32RegAddr = IMX327_2L_HCG_ADDR; + pstI2c_data[LINEAR_HCG].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VMAX_0].u32RegAddr = IMX327_2L_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1].u32RegAddr = IMX327_2L_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_2].u32RegAddr = IMX327_2L_VMAX_ADDR + 2; + pstI2c_data[LINEAR_REL].u32RegAddr = IMX327_2L_HOLD_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[DOL2_REL].u32Data = 0; + pstI2c_data[DOL2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX327_2L_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_2L_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX327_2L_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_2L_MODE_1080P30_WDR; + g_astImx327_2l_State[ViPipe].u32BRL = 1109; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx327_2l_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx327_2l_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx327_2l_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = IMX327_2L_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = IMX327_2L_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[0] = IMX327_2L_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[1] = IMX327_2L_VMAX_1080P30_LINEAR; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx327_2l_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx327_2l_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx327_2l_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx327_2l_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx327_2l_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx327_2l_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx327_2l_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx327_2l_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX327_2L_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_2L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX327_2L_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX327_2L_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX327_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX327_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX327_2L_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx327_2l_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return imx327_2l_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsImx327_2l_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx327_2l_standby, + .pfnRestart = imx327_2l_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx327_2l_write_register, + .pfnReadReg = imx327_2l_read_register, + .pfnSetBusInfo = imx327_2l_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_2L/imx327_2l_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_2L/imx327_2l_cmos_ex.h new file mode 100644 index 000000000..7998d0590 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_2L/imx327_2l_cmos_ex.h @@ -0,0 +1,116 @@ +#ifndef __IMX327_2L_CMOS_EX_H_ +#define __IMX327_2L_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + + +enum imx327_2l_linear_regs_e { + LINEAR_HOLD = 0, + LINEAR_SHS1_0, + LINEAR_SHS1_1, + LINEAR_SHS1_2, + LINEAR_GAIN, + LINEAR_HCG, + LINEAR_VMAX_0, + LINEAR_VMAX_1, + LINEAR_VMAX_2, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum imx327_2l_dol2_regs_e { + DOL2_HOLD = 0, + DOL2_SHS1_0, + DOL2_SHS1_1, + DOL2_SHS1_2, + DOL2_GAIN, + DOL2_HCG, + DOL2_GAIN1, + DOL2_RHS1_0, + DOL2_RHS1_1, + DOL2_RHS1_2, + DOL2_SHS2_0, + DOL2_SHS2_1, + DOL2_SHS2_2, + DOL2_VMAX_0, + DOL2_VMAX_1, + DOL2_VMAX_2, + DOL2_YOUT_SIZE_0, + DOL2_YOUT_SIZE_1, + DOL2_REL, + DOL2_REGS_NUM +}; + +typedef enum _IMX327_2L_MODE_E { + IMX327_2L_MODE_1080P30 = 0, + IMX327_2L_MODE_LINEAR_NUM, + IMX327_2L_MODE_1080P30_WDR = IMX327_2L_MODE_LINEAR_NUM, + IMX327_2L_MODE_NUM +} IMX327_2L_MODE_E; + +typedef struct _IMX327_2L_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX327_2L_STATE_S; + +typedef struct _IMX327_2L_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX327_2L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx327_2l[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx327_2l_BusInfo[]; +extern CVI_U16 g_au16Imx327_2l_GainMode[]; +extern const CVI_U8 imx327_2l_i2c_addr; +extern const CVI_U32 imx327_2l_addr_byte; +extern const CVI_U32 imx327_2l_data_byte; +extern void imx327_2l_init(VI_PIPE ViPipe); +extern void imx327_2l_exit(VI_PIPE ViPipe); +extern void imx327_2l_standby(VI_PIPE ViPipe); +extern void imx327_2l_restart(VI_PIPE ViPipe); +extern int imx327_2l_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx327_2l_read_register(VI_PIPE ViPipe, int addr); +extern void imx327_2l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int imx327_2l_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_2L_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_2L/imx327_2l_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_2L/imx327_2l_cmos_param.h new file mode 100644 index 000000000..bef9b2e83 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_2L/imx327_2l_cmos_param.h @@ -0,0 +1,418 @@ +#ifndef __IMX327_2L_CMOS_PARAM_H_ +#define __IMX327_2L_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_2l_cmos_ex.h" + +static const IMX327_2L_MODE_S g_astImx327_2l_mode[IMX327_2L_MODE_NUM] = { + [IMX327_2L_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x1130, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX327_2L_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 8, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 2236, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 7, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, +}; + +// F1.8 Lens +#ifdef F18 +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = { + /*************Calibration LUT Table*************/ + .CalibrationCoef = { + { //iso 100 + {0.03243722766637802, 3.855583906173706}, //B: slope, intercept + {0.024103811010718346, 3.9538209438323975}, //Gb: slope, intercept + {0.022307759150862694, 4.970882892608643}, //Gr: slope, intercept + {0.02794046327471733, 3.1342978477478027}, //R: slope, intercept + }, + { //iso 200 + {0.03799639642238617, 5.526010990142822}, //B: slope, intercept + {0.02662081830203533, 7.61380672454834}, //Gb: slope, intercept + {0.025447502732276917, 8.231551170349121}, //Gr: slope, intercept + {0.032776281237602234, 5.149646282196045}, //R: slope, intercept + }, + { //iso 400 + {0.050715841352939606, 7.763713836669922}, //B: slope, intercept + {0.032093651592731476, 12.182195663452148}, //Gb: slope, intercept + {0.030688125640153885, 12.43420696258545}, //Gr: slope, intercept + {0.040235333144664764, 8.544824600219727}, //R: slope, intercept + }, + { //iso 800 + {0.06888508796691895, 10.970534324645996}, //B: slope, intercept + {0.03813415393233299, 19.28471565246582}, //Gb: slope, intercept + {0.03805641457438469, 19.625152587890625}, //Gr: slope, intercept + {0.04966627061367035, 12.69924545288086}, //R: slope, intercept + }, + { //iso 1600 + {0.08884920179843903, 15.890214920043945}, //B: slope, intercept + {0.046779610216617584, 30.772066116333008}, //Gb: slope, intercept + {0.045214589685201645, 31.489530563354492}, //Gr: slope, intercept + {0.06512749195098877, 20.34792137145996}, //R: slope, intercept + }, + { //iso 3200 + {0.1241341084241867, 20.70075225830078}, //B: slope, intercept + {0.05977431312203407, 45.98811721801758}, //Gb: slope, intercept + {0.05858884006738663, 47.11114501953125}, //Gr: slope, intercept + {0.08636551350355148, 30.561227798461914}, //R: slope, intercept + }, + { //iso 6400 + {0.1791478991508484, 30.803356170654297}, //B: slope, intercept + {0.09205856174230576, 65.60118103027344}, //Gb: slope, intercept + {0.08692053705453873, 69.85540771484375}, //Gr: slope, intercept + {0.12406758964061737, 45.617835998535156}, //R: slope, intercept + }, + { //iso 12800 + {0.2464703917503357, 44.136966705322266}, //B: slope, intercept + {0.11594483256340027, 97.8382797241211}, //Gb: slope, intercept + {0.11075824499130249, 101.47943115234375}, //Gr: slope, intercept + {0.17024046182632446, 66.47021484375}, //R: slope, intercept + }, + { //iso 25600 + {0.3376912772655487, 68.80254364013672}, //B: slope, intercept + {0.15025299787521362, 145.10032653808594}, //Gb: slope, intercept + {0.14386454224586487, 148.1698455810547}, //Gr: slope, intercept + {0.23965470492839813, 96.42337036132812}, //R: slope, intercept + }, + { //iso 51200 + {0.4279725253582001, 117.4070816040039}, //B: slope, intercept + {0.17134547233581543, 243.6494598388672}, //Gb: slope, intercept + {0.16668814420700073, 241.21603393554688}, //Gr: slope, intercept + {0.29862311482429504, 156.05364990234375}, //R: slope, intercept + }, + { //iso 102400 + {0.534967303276062, 181.45118713378906}, //B: slope, intercept + {0.2024478018283844, 365.00177001953125}, //Gb: slope, intercept + {0.20520392060279846, 362.1013488769531}, //Gr: slope, intercept + {0.40533769130706787, 241.33485412597656}, //R: slope, intercept + }, + { //iso 204800 + {0.6578512191772461, 286.16363525390625}, //B: slope, intercept + {0.223756805062294, 551.998779296875}, //Gb: slope, intercept + {0.22110669314861298, 562.9724731445312}, //Gr: slope, intercept + {0.4937806725502014, 371.5768737792969}, //R: slope, intercept + }, + { //iso 409600 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + //------------------------------------------------------------- + { //iso 819200 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + { //iso 1638400 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + { //iso 3276800 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + } + /*********************************************/ +}; +#endif + +// F1.0 Lens +#ifdef F10 +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.038478557020425796517, 2.14561891555786132813}, //B: slope, intercept + {0.03633839637041091919, 0.17788629233837127686}, //Gb: slope, intercept + {0.03592018783092498779, 0.21645727753639221191}, //Gr: slope, intercept + {0.03592239692807197571, 1.48806631565093994141}, //R: slope, intercept + }, + { //iso 200 + {0.04168356582522392273, 4.38879251480102539063}, //B: slope, intercept + {0.03754633292555809021, 3.21502065658569335938}, //Gb: slope, intercept + {0.03759334236383438110, 3.48370814323425292969}, //Gr: slope, intercept + {0.03719408065080642700, 4.63629007339477539063}, //R: slope, intercept + }, + { //iso 400 + {0.05050259083509445190, 6.85188436508178710938}, //B: slope, intercept + {0.04007886722683906555, 8.49916744232177734375}, //Gb: slope, intercept + {0.03934165090322494507, 8.68585968017578125000}, //Gr: slope, intercept + {0.04134147986769676208, 8.89877605438232421875}, //R: slope, intercept + }, + { //iso 800 + {0.04306267201900482178, 15.41853904724121093750}, //B: slope, intercept + {0.03570587188005447388, 18.56583213806152343750}, //Gb: slope, intercept + {0.03533876314759254456, 19.57685661315917968750}, //Gr: slope, intercept + {0.03832129389047622681, 17.90320968627929687500}, //R: slope, intercept + }, + { //iso 1600 + {0.06225715205073356628, 21.87150573730468750000}, //B: slope, intercept + {0.04437549784779548645, 30.87298965454101562500}, //Gb: slope, intercept + {0.04517432302236557007, 29.32084465026855468750}, //Gr: slope, intercept + {0.05255207046866416931, 26.26001358032226562500}, //R: slope, intercept + }, + { //iso 3200 + {0.07859147340059280396, 32.48978424072265625000}, //B: slope, intercept + {0.05918205901980400085, 45.08999633789062500000}, //Gb: slope, intercept + {0.05711782723665237427, 48.86173248291015625000}, //Gr: slope, intercept + {0.07310666143894195557, 36.88227081298828125000}, //R: slope, intercept + }, + { //iso 6400 + {0.11759266257286071777, 45.81345367431640625000}, //B: slope, intercept + {0.07679814100265502930, 69.04325866699218750000}, //Gb: slope, intercept + {0.07774948328733444214, 66.52905273437500000000}, //Gr: slope, intercept + {0.10286796092987060547, 51.73817443847656250000}, //R: slope, intercept + }, + { //iso 12800 + {0.15860086679458618164, 64.15329742431640625000}, //B: slope, intercept + {0.10511043667793273926, 91.36695098876953125000}, //Gb: slope, intercept + {0.10040879994630813599, 92.05632781982421875000}, //Gr: slope, intercept + {0.13499946892261505127, 73.36162567138671875000}, //R: slope, intercept + }, + { //iso 25600 + {0.22810073196887969971, 100.01741027832031250000}, //B: slope, intercept + {0.14736327528953552246, 146.62678527832031250000}, //Gb: slope, intercept + {0.15503610670566558838, 136.06079101562500000000}, //Gr: slope, intercept + {0.20250190794467926025, 112.74269104003906250000}, //R: slope, intercept + }, + { //iso 51200 + {0.29010805487632751465, 155.05882263183593750000}, //B: slope, intercept + {0.20221179723739624023, 210.97210693359375000000}, //Gb: slope, intercept + {0.21603405475616455078, 201.40393066406250000000}, //Gr: slope, intercept + {0.27819159626960754395, 165.48959350585937500000}, //R: slope, intercept + }, + { //iso 102400 + {0.40437409281730651855, 245.11883544921875000000}, //B: slope, intercept + {0.26703724265098571777, 345.62698364257812500000}, //Gb: slope, intercept + {0.27536261081695556641, 318.75701904296875000000}, //Gr: slope, intercept + {0.44441288709640502930, 222.47651672363281250000}, //R: slope, intercept + }, + { //iso 204800 + {0.48959052562713623047, 383.21560668945312500000}, //B: slope, intercept + {0.37694901227951049805, 442.55813598632812500000}, //Gb: slope, intercept + {0.38724529743194580078, 449.72384643554687500000}, //Gr: slope, intercept + {0.60220617055892944336, 318.92291259765625000000}, //R: slope, intercept + }, + { //iso 409600 + {0.59899300336837768555, 580.43414306640625000000}, //B: slope, intercept + {0.43681395053863525391, 700.22204589843750000000}, //Gb: slope, intercept + {0.50216537714004516602, 633.89794921875000000000}, //Gr: slope, intercept + {0.77917146682739257813, 453.13076782226562500000}, //R: slope, intercept + }, + { //iso 819200 + {0.54956322908401489258, 871.06585693359375000000}, //B: slope, intercept + {0.38088488578796386719, 1040.72192382812500000000}, //Gb: slope, intercept + {0.47245877981185913086, 937.37445068359375000000}, //Gr: slope, intercept + {0.70387065410614013672, 730.45373535156250000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.67512661218643188477, 797.11108398437500000000}, //B: slope, intercept + {0.50457936525344848633, 962.40740966796875000000}, //Gb: slope, intercept + {0.59857457876205444336, 856.90533447265625000000}, //Gr: slope, intercept + {0.74725526571273803711, 740.04290771484375000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.79927802085876464844, 687.07183837890625000000}, //B: slope, intercept + {0.81719654798507690430, 687.01580810546875000000}, //Gb: slope, intercept + {0.83395677804946899414, 658.91857910156250000000}, //Gr: slope, intercept + {0.72803622484207153320, 746.19427490234375000000}, //R: slope, intercept + }, +} }; +#endif + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {240, 240, 240, 240, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1088, 1088, 1088, 1088 +#endif + }, + .stAuto = { + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, +#endif + }, + }, +}; + +struct combo_dev_attr_s imx327_2l_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {2, 1, 0, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_DOL, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_2L_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_2L/imx327_2l_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_2L/imx327_2l_sensor_ctl.c new file mode 100644 index 000000000..7f3108481 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_2L/imx327_2l_sensor_ctl.c @@ -0,0 +1,418 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_2l_cmos_ex.h" + +static void imx327_2l_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void imx327_2l_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 imx327_2l_i2c_addr = 0x1A; +const CVI_U32 imx327_2l_addr_byte = 2; +const CVI_U32 imx327_2l_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx327_2l_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx327_2l_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx327_2l_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int imx327_2l_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx327_2l_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (imx327_2l_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, imx327_2l_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, imx327_2l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (imx327_2l_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int imx327_2l_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx327_2l_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx327_2l_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx327_2l_addr_byte + imx327_2l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx327_2l_standby(VI_PIPE ViPipe) +{ + imx327_2l_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_2l_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ +} + +void imx327_2l_restart(VI_PIPE ViPipe) +{ + imx327_2l_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_2l_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_2l_write_register(ViPipe, 0x304b, 0x0a); +} + +void imx327_2l_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx327_2l[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx327_2l_write_register(ViPipe, + g_pastImx327_2l[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx327_2l[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define IMX327_CHIP_ID_ADDR 0x31dc +#define IMX327_CHIP_ID 0x6 +#define IMX327_CHIP_ID_MASK 0x6 + +void imx327_2l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = imx327_2l_read_register(ViPipe, 0x3007) & ~0x3; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + imx327_2l_write_register(ViPipe, 0x3007, val); +} + +int imx327_2l_probe(VI_PIPE ViPipe) +{ + int nVal; + + usleep(100); + if (imx327_2l_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = imx327_2l_read_register(ViPipe, IMX327_CHIP_ID_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((nVal & IMX327_CHIP_ID_MASK) != IMX327_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void imx327_2l_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastImx327_2l[ViPipe]->enWDRMode; + u8ImgMode = g_pastImx327_2l[ViPipe]->u8ImgMode; + + imx327_2l_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == IMX327_2L_MODE_1080P30_WDR) { + imx327_2l_wdr_1080p30_2to1_init(ViPipe); + } + } else { + imx327_2l_linear_1080p30_init(ViPipe); + } + g_pastImx327_2l[ViPipe]->bInit = CVI_TRUE; +} + +void imx327_2l_exit(VI_PIPE ViPipe) +{ + imx327_2l_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void imx327_2l_linear_1080p30_init(VI_PIPE ViPipe) +{ + imx327_2l_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_2l_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_2l_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx327_2l_write_register(ViPipe, 0x3005, 0x01); /* ADBIT 10bit*/ + imx327_2l_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx327_2l_write_register(ViPipe, 0x3009, 0x02); /**/ + imx327_2l_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx327_2l_write_register(ViPipe, 0x3010, 0x21); + imx327_2l_write_register(ViPipe, 0x3011, 0x02); + imx327_2l_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx327_2l_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx327_2l_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx327_2l_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx327_2l_write_register(ViPipe, 0x301C, 0x30); /* HMAX[7:0], TBD*/ + imx327_2l_write_register(ViPipe, 0x301D, 0x11); /* HMAX[15:8]*/ + imx327_2l_write_register(ViPipe, 0x3020, 0x8C); /* SHS[7:0], TBD*/ + imx327_2l_write_register(ViPipe, 0x3021, 0x01); /* SHS[15:8]*/ + imx327_2l_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx327_2l_write_register(ViPipe, 0x3046, 0x01); + imx327_2l_write_register(ViPipe, 0x304B, 0x0A); + imx327_2l_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx327_2l_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx327_2l_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx327_2l_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx327_2l_write_register(ViPipe, 0x309E, 0x4A); + imx327_2l_write_register(ViPipe, 0x309F, 0x4A); + imx327_2l_write_register(ViPipe, 0x30D2, 0x19); + imx327_2l_write_register(ViPipe, 0x30D7, 0x03); + imx327_2l_write_register(ViPipe, 0x3129, 0x00); + imx327_2l_write_register(ViPipe, 0x313B, 0x61); + imx327_2l_write_register(ViPipe, 0x315E, 0x1A); + imx327_2l_write_register(ViPipe, 0x3164, 0x1A); + imx327_2l_write_register(ViPipe, 0x317C, 0x00); + imx327_2l_write_register(ViPipe, 0x31EC, 0x0E); + imx327_2l_write_register(ViPipe, 0x3405, 0x10); /* Repetition*/ + imx327_2l_write_register(ViPipe, 0x3407, 0x01); /* physical_lane_nl*/ + imx327_2l_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx327_2l_write_register(ViPipe, 0x3418, 0x49); /* y_out_size*/ + imx327_2l_write_register(ViPipe, 0x3419, 0x04); /* y_out_size*/ + imx327_2l_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx327_2l_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx327_2l_write_register(ViPipe, 0x3443, 0x01); /* csi_lane_mode*/ + imx327_2l_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx327_2l_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx327_2l_write_register(ViPipe, 0x3446, 0x57); /* tclkpost*/ + imx327_2l_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + //imx327_2l_write_register(ViPipe, 0x3448, 0x37); /* thszero*/ + imx327_2l_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx327_2l_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx327_2l_write_register(ViPipe, 0x344A, 0x1F); /* thsprepare*/ + imx327_2l_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx327_2l_write_register(ViPipe, 0x344C, 0x1F); /* tclktrail*/ + imx327_2l_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + //imx327_2l_write_register(ViPipe, 0x344E, 0x1F); /* thstrail*/ + imx327_2l_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx327_2l_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx327_2l_write_register(ViPipe, 0x3450, 0x77); /* tclkzero*/ + imx327_2l_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx327_2l_write_register(ViPipe, 0x3452, 0x1F); /* tclkprepare*/ + imx327_2l_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx327_2l_write_register(ViPipe, 0x3454, 0x17); /* tlpx*/ + imx327_2l_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx327_2l_write_register(ViPipe, 0x3472, 0x9C); /* x_out_size*/ + imx327_2l_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx327_2l_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx327_2l_default_reg_init(ViPipe); + + imx327_2l_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_2l_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_2l_write_register(ViPipe, 0x304b, 0x0a); + + printf("ViPipe:%d,===IMX327 1080P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void imx327_2l_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + imx327_2l_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_2l_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_2l_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx327_2l_write_register(ViPipe, 0x3005, 0x01); /* ADBIT*/ + imx327_2l_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx327_2l_write_register(ViPipe, 0x3009, 0x01); /**/ + imx327_2l_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx327_2l_write_register(ViPipe, 0x300C, 0x11); /* WDMODE [0] 0:Normal, 1:DOL, WDSEL [5:4] 1:DOL 2 frames*/ + imx327_2l_write_register(ViPipe, 0x3011, 0x02); + imx327_2l_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx327_2l_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx327_2l_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx327_2l_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx327_2l_write_register(ViPipe, 0x301C, 0x98); /* HMAX[7:0], TBD*/ + imx327_2l_write_register(ViPipe, 0x301D, 0x08); /* HMAX[15:8]*/ + imx327_2l_write_register(ViPipe, 0x3020, 0x02); /* SHS[7:0], TBD*/ + imx327_2l_write_register(ViPipe, 0x3021, 0x00); /* SHS[15:8]*/ + imx327_2l_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx327_2l_write_register(ViPipe, 0x3024, 0xC9); /* SHS2[7:0], TBD*/ + imx327_2l_write_register(ViPipe, 0x3025, 0x07); /* SHS2[15:8]*/ + imx327_2l_write_register(ViPipe, 0x3026, 0x00); /* SHS2[19:16]*/ + imx327_2l_write_register(ViPipe, 0x3030, 0x0B); /* RHS1[7:0], TBD*/ + imx327_2l_write_register(ViPipe, 0x3031, 0x00); /* RHS1[15:8]*/ + imx327_2l_write_register(ViPipe, 0x3032, 0x00); /* RHS1[19:16]*/ + imx327_2l_write_register(ViPipe, 0x3045, 0x05); /* DOLSCDEN [0] 1: pattern1 0: pattern2*/ + imx327_2l_write_register(ViPipe, 0x3046, 0x01); + imx327_2l_write_register(ViPipe, 0x304B, 0x0A); + imx327_2l_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx327_2l_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx327_2l_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx327_2l_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx327_2l_write_register(ViPipe, 0x309E, 0x4A); + imx327_2l_write_register(ViPipe, 0x309F, 0x4A); + imx327_2l_write_register(ViPipe, 0x30D2, 0x19); + imx327_2l_write_register(ViPipe, 0x30D7, 0x03); + imx327_2l_write_register(ViPipe, 0x3106, 0x15); /*DOLHBFIXEN[7] 0: pattern1 1: pattern2*/ + imx327_2l_write_register(ViPipe, 0x3129, 0x00); + imx327_2l_write_register(ViPipe, 0x313B, 0x61); + imx327_2l_write_register(ViPipe, 0x315E, 0x1A); + imx327_2l_write_register(ViPipe, 0x3164, 0x1A); + imx327_2l_write_register(ViPipe, 0x317C, 0x00); + imx327_2l_write_register(ViPipe, 0x31EC, 0x0E); + imx327_2l_write_register(ViPipe, 0x3405, 0x00); /* Repetition*/ + imx327_2l_write_register(ViPipe, 0x3407, 0x01); /* physical_lane_nl*/ + imx327_2l_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx327_2l_write_register(ViPipe, 0x3415, 0x00); /* NULL0_SIZE_V, set to 00h when DOL*/ + imx327_2l_write_register(ViPipe, 0x3418, 0xB4); /* y_out_size*/ + imx327_2l_write_register(ViPipe, 0x3419, 0x08); /* y_out_size*/ + imx327_2l_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx327_2l_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx327_2l_write_register(ViPipe, 0x3443, 0x01); /* csi_lane_mode*/ + imx327_2l_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx327_2l_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx327_2l_write_register(ViPipe, 0x3446, 0x77); /* tclkpost*/ + imx327_2l_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx327_2l_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx327_2l_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx327_2l_write_register(ViPipe, 0x344A, 0x47); /* thsprepare*/ + imx327_2l_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx327_2l_write_register(ViPipe, 0x344C, 0x37); /* tclktrail*/ + imx327_2l_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx327_2l_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx327_2l_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx327_2l_write_register(ViPipe, 0x3450, 0xFF); /* tclkzero*/ + imx327_2l_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx327_2l_write_register(ViPipe, 0x3452, 0x3F); /* tclkprepare*/ + imx327_2l_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx327_2l_write_register(ViPipe, 0x3454, 0x37); /* tlpx*/ + imx327_2l_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx327_2l_write_register(ViPipe, 0x3472, 0xA0); /* x_out_size*/ + imx327_2l_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx327_2l_write_register(ViPipe, 0x347B, 0x23); /**/ + imx327_2l_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx327_2l_default_reg_init(ViPipe); + + if (g_au16Imx327_2l_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + imx327_2l_write_register(ViPipe, 0x30F0, 0xF0); + imx327_2l_write_register(ViPipe, 0x3010, 0x21); + } else { + imx327_2l_write_register(ViPipe, 0x30F0, 0x64); + imx327_2l_write_register(ViPipe, 0x3010, 0x61); + } + + imx327_2l_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_2l_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_2l_write_register(ViPipe, 0x304b, 0x0a); + + printf("===Imx327 sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_fpga/Makefile b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_fpga/Makefile new file mode 100644 index 000000000..77b5fb33b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_fpga/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx327_fpga.a +TARGET_SO = $(MW_LIB)/libsns_imx327_fpga.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_fpga/imx327_fpga_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_fpga/imx327_fpga_cmos.c new file mode 100644 index 000000000..f04db5919 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_fpga/imx327_fpga_cmos.c @@ -0,0 +1,1251 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "imx327_fpga_cmos_ex.h" +#include "imx327_fpga_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX327_FPGA_ID 327 +#define SENSOR_IMX327_FPGA_WIDTH 1920 +#define SENSOR_IMX327_FPGA_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx327_fpga[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX327_FPGA_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx327_fpga[dev]) +#define IMX327_FPGA_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx327_fpga[dev] = pstCtx) +#define IMX327_FPGA_SENSOR_RESET_CTX(dev) (g_pastImx327_fpga[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunImx327_fpga_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx327_fpga_GainMode[VI_MAX_PIPE_NUM] = {0}; + +IMX327_FPGA_STATE_S g_astImx327_fpga_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx327_fpga_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx327 Lines Range*****/ +#define IMX327_FPGA_FULL_LINES_MAX (0x3FFFF) +#define IMX327_FPGA_FULL_LINES_MAX_2TO1_WDR (0x3FFFF) // considering the YOUT_SIZE and bad frame +#define IMX327_FPGA_VMAX_1080P30_LINEAR 1125 +#define IMX327_FPGA_VMAX_720P30_LINEAR 750 + +/*****Imx327 Register Address*****/ +#define IMX327_FPGA_HOLD_ADDR 0x3001 +#define IMX327_FPGA_SHS1_ADDR 0x3020 +#define IMX327_FPGA_SHS2_ADDR 0x3024 +#define IMX327_FPGA_GAIN_ADDR 0x3014 +#define IMX327_FPGA_GAIN1_ADDR 0x30F2 +#define IMX327_FPGA_HCG_ADDR 0x3009 +#define IMX327_FPGA_VMAX_ADDR 0x3018 +#define IMX327_FPGA_YOUT_ADDR 0x3418 +#define IMX327_FPGA_RHS1_ADDR 0x3030 +#define IMX327_FPGA_TABLE_END 0xffff + +#define IMX327_FPGA_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) +#define IMX327_FPGA_RES_IS_720P(w, h) ((w) <= 1280 && (h) <= 720) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX327_FPGA_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + if (pstSnsState->u8ImgMode == IMX327_FPGA_MODE_1080P30) { + pstAeSnsDft->f32Fps = g_astImx327_fpga_mode[IMX327_FPGA_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_fpga_mode[IMX327_FPGA_MODE_1080P30].f32MinFps; + } else { + pstAeSnsDft->f32Fps = g_astImx327_fpga_mode[IMX327_FPGA_MODE_720P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_fpga_mode[IMX327_FPGA_MODE_720P30].f32MinFps; + } + + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX327_FPGA_MODE_1080P30_WDR) { + pstAeSnsDft->f32Fps = g_astImx327_fpga_mode[IMX327_FPGA_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_fpga_mode[IMX327_FPGA_MODE_1080P30_WDR].f32MinFps; + } else { + pstAeSnsDft->f32Fps = g_astImx327_fpga_mode[IMX327_FPGA_MODE_720P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_fpga_mode[IMX327_FPGA_MODE_720P30_WDR].f32MinFps; + } + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = IMX327_FPGA_VMAX_1080P30_LINEAR; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case IMX327_FPGA_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_FPGA_FULL_LINES_MAX_2TO1_WDR) ? + IMX327_FPGA_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case IMX327_FPGA_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_FPGA_FULL_LINES_MAX) ? IMX327_FPGA_FULL_LINES_MAX : u32VMAX; + break; + case IMX327_FPGA_MODE_720P30: + case IMX327_FPGA_MODE_720P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_FPGA_FULL_LINES_MAX) ? IMX327_FPGA_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } else { + pstSnsRegsInfo->astI2cData[DOL2_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx327_fpga_State[ViPipe].u32RHS1_MAX = (u32VMAX - g_astImx327_fpga_State[ViPipe].u32BRL) * 2 - 21; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHS1 = 0; + CVI_U32 u32SHS2 = 0; + CVI_U32 u32YOUTSIZE; + CVI_U32 u16BRL = 0; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u16BRL = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].u16BRL; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[1] < u32LongIntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "WDR FL %d is smaller than = %d\n", + pstSnsState->au32FL[1], u32LongIntTime - 1); + return CVI_FAILURE; + } + u32SHS2 = pstSnsState->au32FL[1] - u32LongIntTime - 1; + + u32SHS1 = (u32ShortIntTime % 2) + 2; + u32RHS1 = u32ShortIntTime + u32SHS1 + 1; + g_astImx327_fpga_State[ViPipe].u32RHS1 = u32RHS1; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - (u32SHS1 + 1); + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[1] - (u32SHS2 + 1); + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + u32YOUTSIZE = (u16BRL + (u32RHS1 - 1) / 2) * 2; + u32YOUTSIZE = (u32YOUTSIZE >= 0x1FFF) ? 0x1FFF : u32YOUTSIZE; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHS1 = %d\n", u32ShortIntTime, u32SHS1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d u32YOUTSIZE = %d\n", ViPipe, u32RHS1, u32YOUTSIZE); + + pstSnsRegsInfo->astI2cData[DOL2_SHS1_0].u32Data = (u32SHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_1].u32Data = ((u32SHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_2].u32Data = ((u32SHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHS2_0].u32Data = (u32SHS2 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_1].u32Data = ((u32SHS2 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_2].u32Data = ((u32SHS2 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_0].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_1].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_2].u32Data = ((u32RHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_0].u32Data = (u32YOUTSIZE & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_1].u32Data = ((u32YOUTSIZE & 0x1F00) >> 8); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if (pstSnsState->au32FL[0] < *u32IntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], *u32IntTime - 1); + return CVI_FAILURE; + } + u32Value = pstSnsState->au32FL[0] - *u32IntTime - 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2].u32Data = ((u32Value & 0x30000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 327567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32HCG = g_astImx327_fpga_State[ViPipe].u8Hcg; + CVI_U32 u16Mode = g_au16Imx327_fpga_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = (u32HCG & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + CVI_U8 bEnableHCG = 0; + + if (pu32Again[0] >= 20 && pu32Again[1] >= 20) { + /* hcg bit[4]*/ + u32HCG |= 0x10; + bEnableHCG = 1; + } + + u32Again = pu32Again[1] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + + u32Again = pu32Again[0] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN1].u32Data = (u32Tmp & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) + u32Tmp = 0xFF; + + if (u32HCG > 0xFF) + u32HCG = 0xFF; + + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 2 : 2; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 10; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx327_fpga_State[ViPipe].u32RHS1_MAX - 3)) ? + (g_astImx327_fpga_State[ViPipe].u32RHS1_MAX - 3) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX327_FPGA_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx327_fpga_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + // CVI_U32 u32VBP1; + // CVI_U32 u32VBP1_MAX; + /* output height = BRL + VBP1 + * VBP1 = (RHS1 - 1)/2 + * long frame start_y = op_size_v + margin_top + * short frame start_y = op_size_v + margin_top + VBP1 + */ + // u32VBP1 = (g_astImx327_fpga_State[ViPipe].u32RHS1 - 1) >> 1; + // u32VBP1_MAX = (g_astImx327_fpga_State[ViPipe].u32RHS1_MAX - 1) >> 1; + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + // pstIspCfg->img_size[1].stSnsSize.u32Height = pstMode->u16BRL + u32VBP1; + // pstIspCfg->img_size[1].stWndRect.s32Y = pstMode->u16OpbSize + pstMode->u16MarginVtop; + // pstIspCfg->img_size[1].stMaxSize.u32Height = pstMode->u16BRL + u32VBP1_MAX; + // pstIspCfg->img_size[0].stSnsSize.u32Height = pstIspCfg->img_size[1].stSnsSize.u32Height; + // pstIspCfg->img_size[0].stWndRect.s32Y = pstMode->u16OpbSize + pstMode->u16MarginVtop + u32VBP1; + // pstIspCfg->img_size[0].stMaxSize.u32Height = pstIspCfg->img_size[1].stMaxSize.u32Height; + + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX327_FPGA_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = IMX327_FPGA_MODE_1080P30; + else if (pstSnsState->u8ImgMode == IMX327_FPGA_MODE_720P30_WDR) + pstSnsState->u8ImgMode = IMX327_FPGA_MODE_720P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].u32VtsDef; + g_astImx327_fpga_State[ViPipe].u8Hcg = 0x2; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX327_FPGA_MODE_1080P30) + pstSnsState->u8ImgMode = IMX327_FPGA_MODE_1080P30_WDR; + else if (pstSnsState->u8ImgMode == IMX327_FPGA_MODE_720P30) + pstSnsState->u8ImgMode = IMX327_FPGA_MODE_720P30_WDR; + + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + g_astImx327_fpga_State[ViPipe].u8Hcg = 0x1; + if (pstSnsState->u8ImgMode == IMX327_FPGA_MODE_1080P30_WDR) { + pstSnsState->u32FLStd = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx327_fpga_State[ViPipe].u32BRL = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1080p\n"); + } else if (pstSnsState->u8ImgMode == IMX327_FPGA_MODE_720P30_WDR) { + pstSnsState->u32FLStd = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx327_fpga_State[ViPipe].u32BRL = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 720P\n"); + } + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx327_fpga_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 2; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx327_fpga_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx327_fpga_addr_byte; + pstI2c_data[i].u32DataByteNum = imx327_fpga_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_HOLD].u32RegAddr = IMX327_FPGA_HOLD_ADDR; + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_SHS1_0].u32RegAddr = IMX327_FPGA_SHS1_ADDR; + pstI2c_data[DOL2_SHS1_1].u32RegAddr = IMX327_FPGA_SHS1_ADDR + 1; + pstI2c_data[DOL2_SHS1_2].u32RegAddr = IMX327_FPGA_SHS1_ADDR + 2; + + pstI2c_data[DOL2_GAIN].u32RegAddr = IMX327_FPGA_GAIN_ADDR; + pstI2c_data[DOL2_HCG].u32RegAddr = IMX327_FPGA_HCG_ADDR; + pstI2c_data[DOL2_HCG].u8DelayFrmNum = 1; + pstI2c_data[DOL2_GAIN1].u32RegAddr = IMX327_FPGA_GAIN1_ADDR; + pstI2c_data[DOL2_RHS1_0].u32RegAddr = IMX327_FPGA_RHS1_ADDR; + pstI2c_data[DOL2_RHS1_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_1].u32RegAddr = IMX327_FPGA_RHS1_ADDR + 1; + pstI2c_data[DOL2_RHS1_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_2].u32RegAddr = IMX327_FPGA_RHS1_ADDR + 2; + pstI2c_data[DOL2_RHS1_2].u8DelayFrmNum = 1; + pstI2c_data[DOL2_SHS2_0].u32RegAddr = IMX327_FPGA_SHS2_ADDR; + pstI2c_data[DOL2_SHS2_1].u32RegAddr = IMX327_FPGA_SHS2_ADDR + 1; + pstI2c_data[DOL2_SHS2_2].u32RegAddr = IMX327_FPGA_SHS2_ADDR + 2; + pstI2c_data[DOL2_VMAX_0].u32RegAddr = IMX327_FPGA_VMAX_ADDR; + pstI2c_data[DOL2_VMAX_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_1].u32RegAddr = IMX327_FPGA_VMAX_ADDR + 1; + pstI2c_data[DOL2_VMAX_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_2].u32RegAddr = IMX327_FPGA_VMAX_ADDR + 2; + pstI2c_data[DOL2_VMAX_2].u8DelayFrmNum = 1; + + pstI2c_data[DOL2_YOUT_SIZE_0].u32RegAddr = IMX327_FPGA_YOUT_ADDR; + pstI2c_data[DOL2_YOUT_SIZE_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u32RegAddr = IMX327_FPGA_YOUT_ADDR + 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_REL].u32RegAddr = IMX327_FPGA_HOLD_ADDR; + pstI2c_data[DOL2_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 1; + break; + default: + pstI2c_data[LINEAR_HOLD].u32RegAddr = IMX327_FPGA_HOLD_ADDR; + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_SHS1_0].u32RegAddr = IMX327_FPGA_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1].u32RegAddr = IMX327_FPGA_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2].u32RegAddr = IMX327_FPGA_SHS1_ADDR + 2; + pstI2c_data[LINEAR_GAIN].u32RegAddr = IMX327_FPGA_GAIN_ADDR; + pstI2c_data[LINEAR_HCG].u32RegAddr = IMX327_FPGA_HCG_ADDR; + pstI2c_data[LINEAR_HCG].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VMAX_0].u32RegAddr = IMX327_FPGA_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1].u32RegAddr = IMX327_FPGA_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_2].u32RegAddr = IMX327_FPGA_VMAX_ADDR + 2; + pstI2c_data[LINEAR_REL].u32RegAddr = IMX327_FPGA_HOLD_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[DOL2_REL].u32Data = 0; + pstI2c_data[DOL2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX327_FPGA_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_FPGA_MODE_720P30; + } else if (IMX327_FPGA_RES_IS_1080P(pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_FPGA_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX327_FPGA_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_FPGA_MODE_720P30_WDR; + CVI_TRACE_SNS(CVI_DBG_ERR, "enter IMX327_FPGA_MODE_720P30_WDR mode\n"); + } else if (IMX327_FPGA_RES_IS_1080P(pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_FPGA_MODE_1080P30_WDR; + g_astImx327_fpga_State[ViPipe].u32BRL = 1109; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) + return CVI_FAILURE; + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx327_fpga_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx327_fpga_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx327_fpga_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u8ImgMode = IMX327_FPGA_MODE_720P30_WDR; + // pstSnsState->u8ImgMode = IMX327_FPGA_MODE_1080P30; + pstSnsState->u32FLStd = IMX327_FPGA_VMAX_720P30_LINEAR; + pstSnsState->au32FL[0] = IMX327_FPGA_VMAX_720P30_LINEAR; + pstSnsState->au32FL[1] = IMX327_FPGA_VMAX_720P30_LINEAR; + // pstSnsState->u32FLStd = IMX327_FPGA_VMAX_1080P30_LINEAR; + // pstSnsState->au32FL[0] = IMX327_FPGA_VMAX_1080P30_LINEAR; + // pstSnsState->au32FL[1] = IMX327_FPGA_VMAX_1080P30_LINEAR; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx327_fpga_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx327_fpga_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + CVI_TRACE_SNS(CVI_DBG_INFO, "sensor_rx_attr/enWDRMode=%d\n", pstSnsState->enWDRMode); + pstRxAttr->wdr_manu.manual_en = 1; + pstRxAttr->wdr_manu.l2s_distance = 0; + pstRxAttr->wdr_manu.lsef_length = 0x1FFF; + pstRxAttr->wdr_manu.discard_padding_lines = 1; + pstRxAttr->wdr_manu.update = 1; + } else { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx327_fpga_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx327_fpga_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx327_fpga_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx327_fpga_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx327_fpga_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX327_FPGA_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_FPGA_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX327_FPGA_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX327_FPGA_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX327_FPGA_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX327_FPGA_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX327_FPGA_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx327_fpga_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsImx327_fpga_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx327_fpga_standby, + .pfnRestart = imx327_fpga_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx327_fpga_write_register, + .pfnReadReg = imx327_fpga_read_register, + .pfnSetBusInfo = imx327_fpga_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = CVI_NULL, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_fpga/imx327_fpga_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_fpga/imx327_fpga_cmos_ex.h new file mode 100644 index 000000000..83bcf6cfe --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_fpga/imx327_fpga_cmos_ex.h @@ -0,0 +1,116 @@ +#ifndef __IMX327_FPGA_CMOS_EX_H_ +#define __IMX327_FPGA_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +enum imx327_fpga_linear_regs_e { + LINEAR_HOLD = 0, + LINEAR_SHS1_0, + LINEAR_SHS1_1, + LINEAR_SHS1_2, + LINEAR_GAIN, + LINEAR_HCG, + LINEAR_VMAX_0, + LINEAR_VMAX_1, + LINEAR_VMAX_2, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum imx327_fpga_dol2_regs_e { + DOL2_HOLD = 0, + DOL2_SHS1_0, + DOL2_SHS1_1, + DOL2_SHS1_2, + DOL2_GAIN, + DOL2_HCG, + DOL2_GAIN1, + DOL2_RHS1_0, + DOL2_RHS1_1, + DOL2_RHS1_2, + DOL2_SHS2_0, + DOL2_SHS2_1, + DOL2_SHS2_2, + DOL2_VMAX_0, + DOL2_VMAX_1, + DOL2_VMAX_2, + DOL2_YOUT_SIZE_0, + DOL2_YOUT_SIZE_1, + DOL2_REL, + DOL2_REGS_NUM +}; + +typedef enum _IMX327_FPGA_MODE_E { + IMX327_FPGA_MODE_720P30, + IMX327_FPGA_MODE_1080P30, + IMX327_FPGA_MODE_LINEAR_NUM, + IMX327_FPGA_MODE_720P30_WDR = IMX327_FPGA_MODE_LINEAR_NUM, + IMX327_FPGA_MODE_1080P30_WDR, + IMX327_FPGA_MODE_NUM +} IMX327_FPGA_MODE_E; + +typedef struct _IMX327_FPGA_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX327_FPGA_STATE_S; + +typedef struct _IMX327_FPGA_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX327_FPGA_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx327_fpga[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx327_fpga_BusInfo[]; +extern CVI_U16 g_au16Imx327_fpga_GainMode[]; +extern const CVI_U8 imx327_fpga_i2c_addr; +extern const CVI_U32 imx327_fpga_addr_byte; +extern const CVI_U32 imx327_fpga_data_byte; +extern void imx327_fpga_init(VI_PIPE ViPipe); +extern void imx327_fpga_exit(VI_PIPE ViPipe); +extern void imx327_fpga_standby(VI_PIPE ViPipe); +extern void imx327_fpga_restart(VI_PIPE ViPipe); +extern int imx327_fpga_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx327_fpga_read_register(VI_PIPE ViPipe, int addr); +extern void imx327_fpga_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_FPGA_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_fpga/imx327_fpga_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_fpga/imx327_fpga_cmos_param.h new file mode 100644 index 000000000..251b36507 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_fpga/imx327_fpga_cmos_param.h @@ -0,0 +1,544 @@ +#ifndef __IMX327_FPGA_CMOS_PARAM_FPGA_H_ +#define __IMX327_FPGA_CMOS_PARAM_FPGA_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_fpga_cmos_ex.h" + +static const IMX327_FPGA_MODE_S g_astImx327_fpga_mode[IMX327_FPGA_MODE_NUM] = { + [IMX327_FPGA_MODE_720P30] = { + .name = "720p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1308, + .u32Height = 729, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1308, + .u32Height = 729, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.09, /* 750 *30 / 0x3FFFF */ + .u32HtsDef = 0x19C8, + .u32VtsDef = 750, + .stExp[0] = { + .u16Min = 1, + .u16Max = 750, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 9, + .u16BRL = 735, + .u16OpbSize = 4, + .u16MarginVtop = 4, + .u16MarginVbot = 5, + }, + [IMX327_FPGA_MODE_720P30_WDR] = { + .name = "720p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1308, + .u32Height = 729, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1308, + .u32Height = 729, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 1308, + .u32Height = 729, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1308, + .u32Height = 729, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.09, /* 750 *30 / 0x3FFFF */ + .u32HtsDef = 0x19C8, + .u32VtsDef = 750, + .stExp[0] = { + .u16Min = 1, + .u16Max = 750, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 750, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 9, + .u16BRL = 735, + .u16OpbSize = 4, + .u16MarginVtop = 4, + .u16MarginVbot = 5, + }, + [IMX327_FPGA_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x1130, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX327_FPGA_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 1952, + .u32Height = 1114, + }, + .stWndRect = { + .s32X = 16, + .s32Y = 20, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1952, + .u32Height = 1114, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 1952, + .u32Height = 1114, + }, + .stWndRect = { + .s32X = 16, + .s32Y = 15, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1952, + .u32Height = 1114, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 8, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 2236, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 7, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, +}; + +// F1.8 Lens +#ifdef F18 +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = { + /*************Calibration LUT Table*************/ + .CalibrationCoef = { + { //iso 100 + {0.03243722766637802, 3.855583906173706}, //B: slope, intercept + {0.024103811010718346, 3.9538209438323975}, //Gb: slope, intercept + {0.022307759150862694, 4.970882892608643}, //Gr: slope, intercept + {0.02794046327471733, 3.1342978477478027}, //R: slope, intercept + }, + { //iso 200 + {0.03799639642238617, 5.526010990142822}, //B: slope, intercept + {0.02662081830203533, 7.61380672454834}, //Gb: slope, intercept + {0.025447502732276917, 8.231551170349121}, //Gr: slope, intercept + {0.032776281237602234, 5.149646282196045}, //R: slope, intercept + }, + { //iso 400 + {0.050715841352939606, 7.763713836669922}, //B: slope, intercept + {0.032093651592731476, 12.182195663452148}, //Gb: slope, intercept + {0.030688125640153885, 12.43420696258545}, //Gr: slope, intercept + {0.040235333144664764, 8.544824600219727}, //R: slope, intercept + }, + { //iso 800 + {0.06888508796691895, 10.970534324645996}, //B: slope, intercept + {0.03813415393233299, 19.28471565246582}, //Gb: slope, intercept + {0.03805641457438469, 19.625152587890625}, //Gr: slope, intercept + {0.04966627061367035, 12.69924545288086}, //R: slope, intercept + }, + { //iso 1600 + {0.08884920179843903, 15.890214920043945}, //B: slope, intercept + {0.046779610216617584, 30.772066116333008}, //Gb: slope, intercept + {0.045214589685201645, 31.489530563354492}, //Gr: slope, intercept + {0.06512749195098877, 20.34792137145996}, //R: slope, intercept + }, + { //iso 3200 + {0.1241341084241867, 20.70075225830078}, //B: slope, intercept + {0.05977431312203407, 45.98811721801758}, //Gb: slope, intercept + {0.05858884006738663, 47.11114501953125}, //Gr: slope, intercept + {0.08636551350355148, 30.561227798461914}, //R: slope, intercept + }, + { //iso 6400 + {0.1791478991508484, 30.803356170654297}, //B: slope, intercept + {0.09205856174230576, 65.60118103027344}, //Gb: slope, intercept + {0.08692053705453873, 69.85540771484375}, //Gr: slope, intercept + {0.12406758964061737, 45.617835998535156}, //R: slope, intercept + }, + { //iso 12800 + {0.2464703917503357, 44.136966705322266}, //B: slope, intercept + {0.11594483256340027, 97.8382797241211}, //Gb: slope, intercept + {0.11075824499130249, 101.47943115234375}, //Gr: slope, intercept + {0.17024046182632446, 66.47021484375}, //R: slope, intercept + }, + { //iso 25600 + {0.3376912772655487, 68.80254364013672}, //B: slope, intercept + {0.15025299787521362, 145.10032653808594}, //Gb: slope, intercept + {0.14386454224586487, 148.1698455810547}, //Gr: slope, intercept + {0.23965470492839813, 96.42337036132812}, //R: slope, intercept + }, + { //iso 51200 + {0.4279725253582001, 117.4070816040039}, //B: slope, intercept + {0.17134547233581543, 243.6494598388672}, //Gb: slope, intercept + {0.16668814420700073, 241.21603393554688}, //Gr: slope, intercept + {0.29862311482429504, 156.05364990234375}, //R: slope, intercept + }, + { //iso 102400 + {0.534967303276062, 181.45118713378906}, //B: slope, intercept + {0.2024478018283844, 365.00177001953125}, //Gb: slope, intercept + {0.20520392060279846, 362.1013488769531}, //Gr: slope, intercept + {0.40533769130706787, 241.33485412597656}, //R: slope, intercept + }, + { //iso 204800 + {0.6578512191772461, 286.16363525390625}, //B: slope, intercept + {0.223756805062294, 551.998779296875}, //Gb: slope, intercept + {0.22110669314861298, 562.9724731445312}, //Gr: slope, intercept + {0.4937806725502014, 371.5768737792969}, //R: slope, intercept + }, + { //iso 409600 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + //------------------------------------------------------------- + { //iso 819200 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + { //iso 1638400 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + { //iso 3276800 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + } + /*********************************************/ +}; +#endif + +// F1.0 Lens +#ifdef F10 +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.038478557020425796517, 2.14561891555786132813}, //B: slope, intercept + {0.03633839637041091919, 0.17788629233837127686}, //Gb: slope, intercept + {0.03592018783092498779, 0.21645727753639221191}, //Gr: slope, intercept + {0.03592239692807197571, 1.48806631565093994141}, //R: slope, intercept + }, + { //iso 200 + {0.04168356582522392273, 4.38879251480102539063}, //B: slope, intercept + {0.03754633292555809021, 3.21502065658569335938}, //Gb: slope, intercept + {0.03759334236383438110, 3.48370814323425292969}, //Gr: slope, intercept + {0.03719408065080642700, 4.63629007339477539063}, //R: slope, intercept + }, + { //iso 400 + {0.05050259083509445190, 6.85188436508178710938}, //B: slope, intercept + {0.04007886722683906555, 8.49916744232177734375}, //Gb: slope, intercept + {0.03934165090322494507, 8.68585968017578125000}, //Gr: slope, intercept + {0.04134147986769676208, 8.89877605438232421875}, //R: slope, intercept + }, + { //iso 800 + {0.04306267201900482178, 15.41853904724121093750}, //B: slope, intercept + {0.03570587188005447388, 18.56583213806152343750}, //Gb: slope, intercept + {0.03533876314759254456, 19.57685661315917968750}, //Gr: slope, intercept + {0.03832129389047622681, 17.90320968627929687500}, //R: slope, intercept + }, + { //iso 1600 + {0.06225715205073356628, 21.87150573730468750000}, //B: slope, intercept + {0.04437549784779548645, 30.87298965454101562500}, //Gb: slope, intercept + {0.04517432302236557007, 29.32084465026855468750}, //Gr: slope, intercept + {0.05255207046866416931, 26.26001358032226562500}, //R: slope, intercept + }, + { //iso 3200 + {0.07859147340059280396, 32.48978424072265625000}, //B: slope, intercept + {0.05918205901980400085, 45.08999633789062500000}, //Gb: slope, intercept + {0.05711782723665237427, 48.86173248291015625000}, //Gr: slope, intercept + {0.07310666143894195557, 36.88227081298828125000}, //R: slope, intercept + }, + { //iso 6400 + {0.11759266257286071777, 45.81345367431640625000}, //B: slope, intercept + {0.07679814100265502930, 69.04325866699218750000}, //Gb: slope, intercept + {0.07774948328733444214, 66.52905273437500000000}, //Gr: slope, intercept + {0.10286796092987060547, 51.73817443847656250000}, //R: slope, intercept + }, + { //iso 12800 + {0.15860086679458618164, 64.15329742431640625000}, //B: slope, intercept + {0.10511043667793273926, 91.36695098876953125000}, //Gb: slope, intercept + {0.10040879994630813599, 92.05632781982421875000}, //Gr: slope, intercept + {0.13499946892261505127, 73.36162567138671875000}, //R: slope, intercept + }, + { //iso 25600 + {0.22810073196887969971, 100.01741027832031250000}, //B: slope, intercept + {0.14736327528953552246, 146.62678527832031250000}, //Gb: slope, intercept + {0.15503610670566558838, 136.06079101562500000000}, //Gr: slope, intercept + {0.20250190794467926025, 112.74269104003906250000}, //R: slope, intercept + }, + { //iso 51200 + {0.29010805487632751465, 155.05882263183593750000}, //B: slope, intercept + {0.20221179723739624023, 210.97210693359375000000}, //Gb: slope, intercept + {0.21603405475616455078, 201.40393066406250000000}, //Gr: slope, intercept + {0.27819159626960754395, 165.48959350585937500000}, //R: slope, intercept + }, + { //iso 102400 + {0.40437409281730651855, 245.11883544921875000000}, //B: slope, intercept + {0.26703724265098571777, 345.62698364257812500000}, //Gb: slope, intercept + {0.27536261081695556641, 318.75701904296875000000}, //Gr: slope, intercept + {0.44441288709640502930, 222.47651672363281250000}, //R: slope, intercept + }, + { //iso 204800 + {0.48959052562713623047, 383.21560668945312500000}, //B: slope, intercept + {0.37694901227951049805, 442.55813598632812500000}, //Gb: slope, intercept + {0.38724529743194580078, 449.72384643554687500000}, //Gr: slope, intercept + {0.60220617055892944336, 318.92291259765625000000}, //R: slope, intercept + }, + { //iso 409600 + {0.59899300336837768555, 580.43414306640625000000}, //B: slope, intercept + {0.43681395053863525391, 700.22204589843750000000}, //Gb: slope, intercept + {0.50216537714004516602, 633.89794921875000000000}, //Gr: slope, intercept + {0.77917146682739257813, 453.13076782226562500000}, //R: slope, intercept + }, + { //iso 819200 + {0.54956322908401489258, 871.06585693359375000000}, //B: slope, intercept + {0.38088488578796386719, 1040.72192382812500000000}, //Gb: slope, intercept + {0.47245877981185913086, 937.37445068359375000000}, //Gr: slope, intercept + {0.70387065410614013672, 730.45373535156250000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.67512661218643188477, 797.11108398437500000000}, //B: slope, intercept + {0.50457936525344848633, 962.40740966796875000000}, //Gb: slope, intercept + {0.59857457876205444336, 856.90533447265625000000}, //Gr: slope, intercept + {0.74725526571273803711, 740.04290771484375000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.79927802085876464844, 687.07183837890625000000}, //B: slope, intercept + {0.81719654798507690430, 687.01580810546875000000}, //Gb: slope, intercept + {0.83395677804946899414, 658.91857910156250000000}, //Gr: slope, intercept + {0.72803622484207153320, 746.19427490234375000000}, //R: slope, intercept + }, +} }; +#endif + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {240, 240, 240, 240, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1088, 1088, 1088, 1088 +#endif + }, + .stAuto = { + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, +#endif + }, + }, +}; + + +struct combo_dev_attr_s imx327_fpga_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {0, 1, 2, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_DOL, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_FPGA_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_fpga/imx327_fpga_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_fpga/imx327_fpga_sensor_ctl.c new file mode 100644 index 000000000..bbf9887b4 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_fpga/imx327_fpga_sensor_ctl.c @@ -0,0 +1,370 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_fpga_cmos_ex.h" + +static void imx327_fpga_wdr_720p30_2to1_init(VI_PIPE ViPipe); +static void imx327_fpga_linear_720p30_init(VI_PIPE ViPipe); + +const CVI_U8 imx327_fpga_i2c_addr = 0x1A; +const CVI_U32 imx327_fpga_addr_byte = 2; +const CVI_U32 imx327_fpga_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx327_fpga_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx327_fpga_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx327_fpga_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + CVI_TRACE_SNS(CVI_DBG_INFO, "Open /dev/i2c-%u ok!\n", u8DevNum); + return CVI_SUCCESS; +} + +int imx327_fpga_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx327_fpga_read_register(VI_PIPE ViPipe, int addr) +{ + /* TODO:*/ + (void) ViPipe; + (void) addr; + + return CVI_SUCCESS; +} + + +int imx327_fpga_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx327_fpga_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx327_fpga_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx327_fpga_addr_byte + imx327_fpga_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE 0x%x 0x%x error!\n", addr, data); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx327_fpga_standby(VI_PIPE ViPipe) +{ + imx327_fpga_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_fpga_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ +} + +void imx327_fpga_restart(VI_PIPE ViPipe) +{ + imx327_fpga_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_fpga_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_fpga_write_register(ViPipe, 0x304b, 0x0a); +} + +void imx327_fpga_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx327_fpga[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx327_fpga_write_register(ViPipe, + g_pastImx327_fpga[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx327_fpga[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void imx327_fpga_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = imx327_fpga_read_register(ViPipe, 0x3007) & ~0x3; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + imx327_fpga_write_register(ViPipe, 0x3007, val); +} + +void imx327_fpga_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + + enWDRMode = g_pastImx327_fpga[ViPipe]->enWDRMode; + + imx327_fpga_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) + imx327_fpga_wdr_720p30_2to1_init(ViPipe); + else + imx327_fpga_linear_720p30_init(ViPipe); + + g_pastImx327_fpga[ViPipe]->bInit = CVI_TRUE; +} + +void imx327_fpga_exit(VI_PIPE ViPipe) +{ + imx327_fpga_i2c_exit(ViPipe); +} + +static void imx327_fpga_linear_720p30_init(VI_PIPE ViPipe) +{ + imx327_fpga_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_fpga_write_register(ViPipe, 0x3000, 0x01); // STANDBY + imx327_fpga_write_register(ViPipe, 0x3001, 0x00); // HOLD + imx327_fpga_write_register(ViPipe, 0x3002, 0x00); // XMSTA + imx327_fpga_write_register(ViPipe, 0x3005, 0x00); // ADBIT 10bit +// imx327_fpga_write_register(ViPipe, 0x3007, 0x10); // VREVERS, ... + imx327_fpga_write_register(ViPipe, 0x3007, 0x11); // V VREVERS, ... + imx327_fpga_write_register(ViPipe, 0x3009, 0x02); // + imx327_fpga_write_register(ViPipe, 0x300A, 0x3C); // BLKLEVEL + //imx327_fpga_write_register(ViPipe, 0x300C, 0x00); // WDMODE [0] 0:Normal, 1:DOL, WDSEL [5:4] 1:DOL 2 frames + imx327_fpga_write_register(ViPipe, 0x3011, 0x02); +// imx327_fpga_write_register(ViPipe, 0x3014, 0x16); // GAIN, 0x2A=>12.6dB TBD + imx327_fpga_write_register(ViPipe, 0x3014, 0x00); // GAIN, 0x0=>0 dB TBD + //imx327_fpga_write_register(ViPipe, 0x3016, 0x08); // [TODO] sony's secrect register? + imx327_fpga_write_register(ViPipe, 0x3018, 0xEE); // VMAX[7:0] TBD=750 + imx327_fpga_write_register(ViPipe, 0x3019, 0x02); // VMAX[15:8] + imx327_fpga_write_register(ViPipe, 0x301A, 0x00); // VMAX[17:16]:=:0x301A[1:0] +// imx327_fpga_write_register(ViPipe, 0x301C, 0xC8); // HMAX[7:0], TBD=6600 +// imx327_fpga_write_register(ViPipe, 0x301D, 0x19); // HMAX[15:8] + imx327_fpga_write_register(ViPipe, 0x301C, 0x58); // HMAX[7:0], TBD=19800 + imx327_fpga_write_register(ViPipe, 0x301D, 0x4D); // HMAX[15:8] +// imx327_fpga_write_register(ViPipe, 0x3020, 0x8C); // SHS[7:0], TBD +// imx327_fpga_write_register(ViPipe, 0x3021, 0x01); // SHS[15:8] +// imx327_fpga_write_register(ViPipe, 0x3022, 0x00); // SHS[19:16] + imx327_fpga_write_register(ViPipe, 0x3020, 0x00); // SHS[7:0], TBD + imx327_fpga_write_register(ViPipe, 0x3021, 0x01); // SHS[15:8] + imx327_fpga_write_register(ViPipe, 0x3022, 0x00); // SHS[19:16] + //imx327_fpga_write_register(ViPipe, 0x3024, 0x00); // SHS2[7:0], TBD + //imx327_fpga_write_register(ViPipe, 0x3025, 0x00); // SHS2[15:8] + //imx327_fpga_write_register(ViPipe, 0x3026, 0x00); // SHS2[19:16] + //imx327_fpga_write_register(ViPipe, 0x3030, 0x00); // RHS1[7:0], TBD + //imx327_fpga_write_register(ViPipe, 0x3031, 0x00); // RHS1[15:8] + //imx327_fpga_write_register(ViPipe, 0x3032, 0x00); // RHS1[19:16] + //imx327_fpga_write_register(ViPipe, 0x3045, 0x00); // DOLSCDEN [0] 1: pattern1 0: pattern2 + // DOLSYDINFOEN[1] 1: embed the id code into 4th of sync + // code. 0: disable + // HINFOEN [2] 1: insert id code after 4th sync code 0: disable + imx327_fpga_write_register(ViPipe, 0x3046, 0x00); + imx327_fpga_write_register(ViPipe, 0x304B, 0x0A); + imx327_fpga_write_register(ViPipe, 0x305C, 0x20); // INCKSEL1 + imx327_fpga_write_register(ViPipe, 0x305D, 0x00); // INCKSEL2 + imx327_fpga_write_register(ViPipe, 0x305E, 0x20); // INCKSEL3 + imx327_fpga_write_register(ViPipe, 0x305F, 0x01); // INCKSEL4 + imx327_fpga_write_register(ViPipe, 0x309E, 0x4A); + imx327_fpga_write_register(ViPipe, 0x309F, 0x4A); + imx327_fpga_write_register(ViPipe, 0x30D2, 0x19); + imx327_fpga_write_register(ViPipe, 0x30D7, 0x03); + //imx327_fpga_write_register(ViPipe, 0x3106, 0x00); //DOLHBFIXEN[7] 0: pattern1 1: pattern2 + imx327_fpga_write_register(ViPipe, 0x3129, 0x1D); + imx327_fpga_write_register(ViPipe, 0x313B, 0x61); + imx327_fpga_write_register(ViPipe, 0x315E, 0x1A); + imx327_fpga_write_register(ViPipe, 0x3164, 0x1A); + imx327_fpga_write_register(ViPipe, 0x317C, 0x12); + imx327_fpga_write_register(ViPipe, 0x31EC, 0x37); + imx327_fpga_write_register(ViPipe, 0x3405, 0x10); // Repetition + imx327_fpga_write_register(ViPipe, 0x3407, 0x01); // physical_lane_nl + imx327_fpga_write_register(ViPipe, 0x3414, 0x04); // opb_size_v + imx327_fpga_write_register(ViPipe, 0x3418, 0xD9); // y_out_size + imx327_fpga_write_register(ViPipe, 0x3419, 0x02); // y_out_size + imx327_fpga_write_register(ViPipe, 0x3441, 0x0A); // csi_dt_fmt + imx327_fpga_write_register(ViPipe, 0x3442, 0x0A); // csi_dt_fmt + imx327_fpga_write_register(ViPipe, 0x3443, 0x01); // csi_lane_mode + imx327_fpga_write_register(ViPipe, 0x3444, 0x20); // extck_freq + imx327_fpga_write_register(ViPipe, 0x3445, 0x25); // extck_freq + imx327_fpga_write_register(ViPipe, 0x3446, 0x4F); // tclkpost + imx327_fpga_write_register(ViPipe, 0x3447, 0x00); // tclkpost + imx327_fpga_write_register(ViPipe, 0x3448, 0x80); // thszero + imx327_fpga_write_register(ViPipe, 0x3449, 0x00); // thszero + imx327_fpga_write_register(ViPipe, 0x344A, 0x17); // thsprepare + imx327_fpga_write_register(ViPipe, 0x344B, 0x00); // thsprepare + imx327_fpga_write_register(ViPipe, 0x344C, 0x17); // tclktrail + imx327_fpga_write_register(ViPipe, 0x344D, 0x00); // tclktrail + imx327_fpga_write_register(ViPipe, 0x344E, 0x80); // thstrail + imx327_fpga_write_register(ViPipe, 0x344F, 0x00); // thstrail + imx327_fpga_write_register(ViPipe, 0x3450, 0x57); // tclkzero + imx327_fpga_write_register(ViPipe, 0x3451, 0x00); // tclkzero + imx327_fpga_write_register(ViPipe, 0x3452, 0x17); // tclkprepare + imx327_fpga_write_register(ViPipe, 0x3453, 0x00); // tckkprepare + imx327_fpga_write_register(ViPipe, 0x3454, 0x17); // tlpx + imx327_fpga_write_register(ViPipe, 0x3455, 0x00); // tlpx + imx327_fpga_write_register(ViPipe, 0x3472, 0x1C); // x_out_size + imx327_fpga_write_register(ViPipe, 0x3473, 0x05); // x_out_size + imx327_fpga_write_register(ViPipe, 0x3480, 0x49); // incksel7 + +// imx327_fpga_default_reg_init(ViPipe); + + imx327_fpga_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_fpga_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_fpga_write_register(ViPipe, 0x304b, 0x0a); + + printf("ViPipe:%d,===IMX327 720P 30fps 10bit LINE Init for FPGA OK!===\n", ViPipe); +} + +static void imx327_fpga_wdr_720p30_2to1_init(VI_PIPE ViPipe) +{ + imx327_fpga_write_register(ViPipe, 0x3003, 0x01); // SW Reset + delay_ms(3); + imx327_fpga_write_register(ViPipe, 0x3000, 0x01); // STANDBY + imx327_fpga_write_register(ViPipe, 0x3001, 0x00); // HOLD + imx327_fpga_write_register(ViPipe, 0x3002, 0x00); // XMSTA + imx327_fpga_write_register(ViPipe, 0x3005, 0x00); // ADBIT=10bit + imx327_fpga_write_register(ViPipe, 0x3007, 0x11); // VREVERS, ... + imx327_fpga_write_register(ViPipe, 0x3009, 0x02); // + imx327_fpga_write_register(ViPipe, 0x300A, 0x3C); // BLKLEVEL + imx327_fpga_write_register(ViPipe, 0x300C, 0x11); // WDMODE [0] 0:Normal, 1:DOL, WDSEL [5:4] 1:DOL 2 frames + imx327_fpga_write_register(ViPipe, 0x3011, 0x02); + imx327_fpga_write_register(ViPipe, 0x3014, 0x16); // GAIN, 0x2A=>12.6dB TBD + //imx327_fpga_write_register(ViPipe, 0x3016, 0x08); // [TODO] sony's secrect register? + imx327_fpga_write_register(ViPipe, 0x3018, 0xEE); // VMAX[7:0] + imx327_fpga_write_register(ViPipe, 0x3019, 0x02); // VMAX[15:8] + imx327_fpga_write_register(ViPipe, 0x301A, 0x00); // VMAX[17:16]:=:0x301A[1:0] + // imx327_fpga_write_register(ViPipe, 0x301C, 0xC8); // HMAX[7:0], TBD=6600 + // imx327_fpga_write_register(ViPipe, 0x301D, 0x19); // HMAX[15:8] + imx327_fpga_write_register(ViPipe, 0x301C, 0x58); // HMAX[7:0], TBD=19800 + imx327_fpga_write_register(ViPipe, 0x301D, 0x4D); // HMAX[15:8] + imx327_fpga_write_register(ViPipe, 0x3020, 0x02); // SHS[7:0], TBD + imx327_fpga_write_register(ViPipe, 0x3021, 0x00); // SHS[15:8] + imx327_fpga_write_register(ViPipe, 0x3022, 0x00); // SHS[19:16] + imx327_fpga_write_register(ViPipe, 0x3024, 0x1B); // SHS2[7:0], TBD + imx327_fpga_write_register(ViPipe, 0x3025, 0x05); // SHS2[15:8] + imx327_fpga_write_register(ViPipe, 0x3026, 0x00); // SHS2[19:16] + imx327_fpga_write_register(ViPipe, 0x3030, 0x09); // RHS1[7:0], TBD + imx327_fpga_write_register(ViPipe, 0x3031, 0x00); // RHS1[15:8] + imx327_fpga_write_register(ViPipe, 0x3032, 0x00); // RHS1[19:16] + imx327_fpga_write_register(ViPipe, 0x3045, 0x05); // DOLSCDEN [0] 1: pattern1 0: pattern2 + // DOLSYDINFOEN[1] 1: embed the id code into 4th of sync + // code. 0: disable + // HINFOEN [2] 1: insert id code after 4th sync code 0: disable + imx327_fpga_write_register(ViPipe, 0x3046, 0x00); + imx327_fpga_write_register(ViPipe, 0x304B, 0x0A); + imx327_fpga_write_register(ViPipe, 0x305C, 0x20); // INCKSEL1 + imx327_fpga_write_register(ViPipe, 0x305D, 0x00); // INCKSEL2 + imx327_fpga_write_register(ViPipe, 0x305E, 0x20); // INCKSEL3 + imx327_fpga_write_register(ViPipe, 0x305F, 0x01); // INCKSEL4 + imx327_fpga_write_register(ViPipe, 0x309E, 0x4A); + imx327_fpga_write_register(ViPipe, 0x309F, 0x4A); + imx327_fpga_write_register(ViPipe, 0x30D2, 0x19); + imx327_fpga_write_register(ViPipe, 0x30D7, 0x03); + imx327_fpga_write_register(ViPipe, 0x3106, 0x11); //DOLHBFIXEN[7] 0: pattern1 1: pattern2 + imx327_fpga_write_register(ViPipe, 0x3129, 0x1D); + imx327_fpga_write_register(ViPipe, 0x313B, 0x61); + imx327_fpga_write_register(ViPipe, 0x315E, 0x1A); + imx327_fpga_write_register(ViPipe, 0x3164, 0x1A); + imx327_fpga_write_register(ViPipe, 0x317C, 0x12); + imx327_fpga_write_register(ViPipe, 0x31EC, 0x37); + imx327_fpga_write_register(ViPipe, 0x3405, 0x10); // Repetition + imx327_fpga_write_register(ViPipe, 0x3407, 0x01); // physical_lane_nl + imx327_fpga_write_register(ViPipe, 0x3414, 0x04); // opb_size_v + imx327_fpga_write_register(ViPipe, 0x3415, 0x00); // NULL0_SIZE_V, set to 00h when DOL + imx327_fpga_write_register(ViPipe, 0x3418, 0xC6); // y_out_size + imx327_fpga_write_register(ViPipe, 0x3419, 0x05); // y_out_size + imx327_fpga_write_register(ViPipe, 0x3441, 0x0A); // csi_dt_fmt + imx327_fpga_write_register(ViPipe, 0x3442, 0x0A); // csi_dt_fmt + imx327_fpga_write_register(ViPipe, 0x3443, 0x01); // csi_lane_mode + imx327_fpga_write_register(ViPipe, 0x3444, 0x20); // extck_freq + imx327_fpga_write_register(ViPipe, 0x3445, 0x25); // extck_freq + imx327_fpga_write_register(ViPipe, 0x3446, 0x4F); // tclkpost + imx327_fpga_write_register(ViPipe, 0x3447, 0x00); // tclkpost + imx327_fpga_write_register(ViPipe, 0x3448, 0x80); // thszero + imx327_fpga_write_register(ViPipe, 0x3449, 0x00); // thszero + imx327_fpga_write_register(ViPipe, 0x344A, 0x17); // thsprepare + imx327_fpga_write_register(ViPipe, 0x344B, 0x00); // thsprepare + imx327_fpga_write_register(ViPipe, 0x344C, 0x17); // tclktrail + imx327_fpga_write_register(ViPipe, 0x344D, 0x00); // tclktrail + imx327_fpga_write_register(ViPipe, 0x344E, 0x80); // thstrail + imx327_fpga_write_register(ViPipe, 0x344F, 0x00); // thstrail + imx327_fpga_write_register(ViPipe, 0x3450, 0x57); // tclkzero + imx327_fpga_write_register(ViPipe, 0x3451, 0x00); // tclkzero + imx327_fpga_write_register(ViPipe, 0x3452, 0x17); // tclkprepare + imx327_fpga_write_register(ViPipe, 0x3453, 0x00); // tckkprepare + imx327_fpga_write_register(ViPipe, 0x3454, 0x17); // tlpx + imx327_fpga_write_register(ViPipe, 0x3455, 0x00); // tlpx + imx327_fpga_write_register(ViPipe, 0x3472, 0x20); // x_out_size + imx327_fpga_write_register(ViPipe, 0x3473, 0x05); // x_out_size + imx327_fpga_write_register(ViPipe, 0x347B, 0x23); // + imx327_fpga_write_register(ViPipe, 0x3480, 0x49); // incksel7 + + delay_ms(20); // delay + imx327_fpga_write_register(ViPipe, 0x3000, 0x00); // STANDBY + imx327_fpga_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_fpga_write_register(ViPipe, 0x304b, 0x0a); + + printf("===Imx327 sensor 720P15fps 10bit 2to1 WDR(30fps->15fps) init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_slave/Makefile b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_slave/Makefile new file mode 100644 index 000000000..95045e73c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_slave/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx327_slave.a +TARGET_SO = $(MW_LIB)/libsns_imx327_slave.so + +EXTRA_CFLAGS = $(INCS) $(PROJ_CFLAGS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_slave/imx327_slave_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_slave/imx327_slave_cmos.c new file mode 100644 index 000000000..46b7483c3 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_slave/imx327_slave_cmos.c @@ -0,0 +1,1198 @@ +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "imx327_slave_cmos_ex.h" +#include "imx327_slave_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX327_SLAVE_ID 327 +#define SENSOR_IMX327_SLAVE_WIDTH 1920 +#define SENSOR_IMX327_SLAVE_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx327_Slave[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX327_SLAVE_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx327_Slave[dev]) +#define IMX327_SLAVE_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx327_Slave[dev] = pstCtx) +#define IMX327_SLAVE_SENSOR_RESET_CTX(dev) (g_pastImx327_Slave[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunImx327_Slave_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx327_Slave_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Imx327_Slave_UseHwSync[VI_MAX_PIPE_NUM] = {0}; + +IMX327_SLAVE_STATE_S g_astImx327_Slave_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx327_Slave_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx327 Lines Range*****/ +#define IMX327_SLAVE_FULL_LINES_MAX (0x3FFFF) +#define IMX327_SLAVE_FULL_LINES_MAX_2TO1_WDR (0x3FFFF) // considering the YOUT_SIZE and bad frame +#define IMX327_SLAVE_VMAX_1080P30_LINEAR 1125 + +/*****Imx327 Register Address*****/ +#define IMX327_SLAVE_HOLD_ADDR 0x3001 +#define IMX327_SLAVE_SHS1_ADDR 0x3020 +#define IMX327_SLAVE_SHS2_ADDR 0x3024 +#define IMX327_SLAVE_GAIN_ADDR 0x3014 +#define IMX327_SLAVE_GAIN1_ADDR 0x30F2 +#define IMX327_SLAVE_HCG_ADDR 0x3009 +#define IMX327_SLAVE_VMAX_ADDR 0x3018 +#define IMX327_SLAVE_YOUT_ADDR 0x3418 +#define IMX327_SLAVE_RHS1_ADDR 0x3030 +#define IMX327_SLAVE_TABLE_END 0xffff + +#define IMX327_SLAVE_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX327_SLAVE_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astImx327_Slave_mode[IMX327_SLAVE_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_Slave_mode[IMX327_SLAVE_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astImx327_Slave_mode[IMX327_SLAVE_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_Slave_mode[IMX327_SLAVE_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = IMX327_SLAVE_VMAX_1080P30_LINEAR; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case IMX327_SLAVE_MODE_1080P30_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_SLAVE_FULL_LINES_MAX_2TO1_WDR) ? + IMX327_SLAVE_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + break; + + case IMX327_SLAVE_MODE_1080P30: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX327_SLAVE_FULL_LINES_MAX) ? IMX327_SLAVE_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } else { + pstSnsRegsInfo->astI2cData[DOL2_VMAX_0].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_1].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_2].u32Data = ((u32VMAX & 0xF0000) >> 16); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx327_Slave_State[ViPipe].u32RHS1_MAX = + (u32VMAX - g_astImx327_Slave_State[ViPipe].u32BRL) * 2 - 21; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHS1 = 0; + CVI_U32 u32SHS2 = 0; + CVI_U32 u32YOUTSIZE; + CVI_U32 u16BRL = 0; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u16BRL = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].u16BRL; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[0] < u32LongIntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], u32LongIntTime - 1); + return CVI_FAILURE; + } + u32SHS2 = pstSnsState->au32FL[0] - u32LongIntTime - 1; + + u32SHS1 = (u32ShortIntTime % 2) + 2; + u32RHS1 = u32ShortIntTime + u32SHS1 + 1; + g_astImx327_Slave_State[ViPipe].u32RHS1 = u32RHS1; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - (u32SHS1 + 1); + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[0] - (u32SHS2 + 1); + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + u32YOUTSIZE = (u16BRL + (u32RHS1 - 1) / 2) * 2; + u32YOUTSIZE = (u32YOUTSIZE >= 0x1FFF) ? 0x1FFF : u32YOUTSIZE; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHS1 = %d\n", u32ShortIntTime, u32SHS1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d u32YOUTSIZE = %d\n", ViPipe, u32RHS1, u32YOUTSIZE); + + pstSnsRegsInfo->astI2cData[DOL2_SHS1_0].u32Data = (u32SHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_1].u32Data = ((u32SHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_2].u32Data = ((u32SHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHS2_0].u32Data = (u32SHS2 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_1].u32Data = ((u32SHS2 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_2].u32Data = ((u32SHS2 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_0].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_1].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_2].u32Data = ((u32RHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_0].u32Data = (u32YOUTSIZE & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_1].u32Data = ((u32YOUTSIZE & 0x1F00) >> 8); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if (pstSnsState->au32FL[0] < *u32IntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], *u32IntTime - 1); + return CVI_FAILURE; + } + u32Value = pstSnsState->au32FL[0] - *u32IntTime - 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2].u32Data = ((u32Value & 0x30000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 327567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32HCG = g_astImx327_Slave_State[ViPipe].u8Hcg; + CVI_U32 u16Mode = g_au16Imx327_Slave_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = (u32HCG & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + CVI_U8 bEnableHCG = 0; + + if (pu32Again[0] >= 20 && pu32Again[1] >= 20) { + /* hcg bit[4]*/ + u32HCG |= 0x10; + bEnableHCG = 1; + } + + u32Again = pu32Again[1] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + + u32Again = pu32Again[0] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN1].u32Data = (u32Tmp & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + if (u32HCG > 0xFF) { + u32HCG = 0xFF; + } + + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? 2 : 2; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 10; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx327_Slave_State[ViPipe].u32RHS1_MAX - 3)) ? + (g_astImx327_Slave_State[ViPipe].u32RHS1_MAX - 3) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX327_SLAVE_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx327_Slave_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX327_SLAVE_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = IMX327_SLAVE_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].u32VtsDef; + g_astImx327_Slave_State[ViPipe].u8Hcg = 0x2; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX327_SLAVE_MODE_1080P30) + pstSnsState->u8ImgMode = IMX327_SLAVE_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + g_astImx327_Slave_State[ViPipe].u8Hcg = 0x1; + if (pstSnsState->u8ImgMode == IMX327_SLAVE_MODE_1080P30_WDR) { + pstSnsState->u32FLStd = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx327_Slave_State[ViPipe].u32BRL = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1080p\n"); + } + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx327_Slave_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx327_slave_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx327_slave_addr_byte; + pstI2c_data[i].u32DataByteNum = imx327_slave_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_HOLD].u32RegAddr = IMX327_SLAVE_HOLD_ADDR; + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_SHS1_0].u32RegAddr = IMX327_SLAVE_SHS1_ADDR; + pstI2c_data[DOL2_SHS1_1].u32RegAddr = IMX327_SLAVE_SHS1_ADDR + 1; + pstI2c_data[DOL2_SHS1_2].u32RegAddr = IMX327_SLAVE_SHS1_ADDR + 2; + + pstI2c_data[DOL2_GAIN].u32RegAddr = IMX327_SLAVE_GAIN_ADDR; + pstI2c_data[DOL2_HCG].u32RegAddr = IMX327_SLAVE_HCG_ADDR; + pstI2c_data[DOL2_HCG].u8DelayFrmNum = 1; + pstI2c_data[DOL2_GAIN1].u32RegAddr = IMX327_SLAVE_GAIN1_ADDR; + pstI2c_data[DOL2_RHS1_0].u32RegAddr = IMX327_SLAVE_RHS1_ADDR; + pstI2c_data[DOL2_RHS1_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_1].u32RegAddr = IMX327_SLAVE_RHS1_ADDR + 1; + pstI2c_data[DOL2_RHS1_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_2].u32RegAddr = IMX327_SLAVE_RHS1_ADDR + 2; + pstI2c_data[DOL2_RHS1_2].u8DelayFrmNum = 1; + pstI2c_data[DOL2_SHS2_0].u32RegAddr = IMX327_SLAVE_SHS2_ADDR; + pstI2c_data[DOL2_SHS2_1].u32RegAddr = IMX327_SLAVE_SHS2_ADDR + 1; + pstI2c_data[DOL2_SHS2_2].u32RegAddr = IMX327_SLAVE_SHS2_ADDR + 2; + pstI2c_data[DOL2_VMAX_0].u32RegAddr = IMX327_SLAVE_VMAX_ADDR; + pstI2c_data[DOL2_VMAX_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_1].u32RegAddr = IMX327_SLAVE_VMAX_ADDR + 1; + pstI2c_data[DOL2_VMAX_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_VMAX_2].u32RegAddr = IMX327_SLAVE_VMAX_ADDR + 2; + pstI2c_data[DOL2_VMAX_2].u8DelayFrmNum = 1; + + pstI2c_data[DOL2_YOUT_SIZE_0].u32RegAddr = IMX327_SLAVE_YOUT_ADDR; + pstI2c_data[DOL2_YOUT_SIZE_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u32RegAddr = IMX327_SLAVE_YOUT_ADDR + 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_REL].u32RegAddr = IMX327_SLAVE_HOLD_ADDR; + pstI2c_data[DOL2_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 1; + break; + default: + pstI2c_data[LINEAR_HOLD].u32RegAddr = IMX327_SLAVE_HOLD_ADDR; + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_SHS1_0].u32RegAddr = IMX327_SLAVE_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1].u32RegAddr = IMX327_SLAVE_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2].u32RegAddr = IMX327_SLAVE_SHS1_ADDR + 2; + pstI2c_data[LINEAR_GAIN].u32RegAddr = IMX327_SLAVE_GAIN_ADDR; + pstI2c_data[LINEAR_HCG].u32RegAddr = IMX327_SLAVE_HCG_ADDR; + pstI2c_data[LINEAR_HCG].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_VMAX_0].u32RegAddr = IMX327_SLAVE_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1].u32RegAddr = IMX327_SLAVE_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_2].u32RegAddr = IMX327_SLAVE_VMAX_ADDR + 2; + pstI2c_data[LINEAR_REL].u32RegAddr = IMX327_SLAVE_HOLD_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[DOL2_REL].u32Data = 0; + pstI2c_data[DOL2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX327_SLAVE_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_SLAVE_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX327_SLAVE_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_SLAVE_MODE_1080P30_WDR; + g_astImx327_Slave_State[ViPipe].u32BRL = 1109; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx327_Slave_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx327_slave_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx327_Slave_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = IMX327_SLAVE_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = IMX327_SLAVE_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[0] = IMX327_SLAVE_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[1] = IMX327_SLAVE_VMAX_1080P30_LINEAR; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx327_slave_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx327_Slave_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx327_slave_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx327_slave_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx327_slave_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx327_slave_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx327_Slave_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX327_SLAVE_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX327_SLAVE_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX327_SLAVE_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX327_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX327_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX327_SLAVE_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx327_Slave_UseHwSync[ViPipe] = pstInitAttr->u16UseHwSync; + g_au16Imx327_Slave_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return imx327_slave_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsImx327_Slave_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx327_slave_standby, + .pfnRestart = imx327_slave_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx327_slave_write_register, + .pfnReadReg = imx327_slave_read_register, + .pfnSetBusInfo = imx327_slave_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_slave/imx327_slave_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_slave/imx327_slave_cmos_ex.h new file mode 100644 index 000000000..c561542b5 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_slave/imx327_slave_cmos_ex.h @@ -0,0 +1,116 @@ +#ifndef __IMX327_SLAVE_CMOS_EX_H_ +#define __IMX327_SLAVE_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +enum imx327_slave_linear_regs_e { + LINEAR_HOLD = 0, + LINEAR_SHS1_0, + LINEAR_SHS1_1, + LINEAR_SHS1_2, + LINEAR_GAIN, + LINEAR_HCG, + LINEAR_VMAX_0, + LINEAR_VMAX_1, + LINEAR_VMAX_2, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum imx327_slave_dol2_regs_e { + DOL2_HOLD = 0, + DOL2_SHS1_0, + DOL2_SHS1_1, + DOL2_SHS1_2, + DOL2_GAIN, + DOL2_HCG, + DOL2_GAIN1, + DOL2_RHS1_0, + DOL2_RHS1_1, + DOL2_RHS1_2, + DOL2_SHS2_0, + DOL2_SHS2_1, + DOL2_SHS2_2, + DOL2_VMAX_0, + DOL2_VMAX_1, + DOL2_VMAX_2, + DOL2_YOUT_SIZE_0, + DOL2_YOUT_SIZE_1, + DOL2_REL, + DOL2_REGS_NUM +}; + +typedef enum _IMX327_SLAVE_MODE_E { + IMX327_SLAVE_MODE_1080P30 = 0, + IMX327_SLAVE_MODE_LINEAR_NUM, + IMX327_SLAVE_MODE_1080P30_WDR = IMX327_SLAVE_MODE_LINEAR_NUM, + IMX327_SLAVE_MODE_NUM +} IMX327_SLAVE_MODE_E; + +typedef struct _IMX327_SLAVE_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX327_SLAVE_STATE_S; + +typedef struct _IMX327_SLAVE_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX327_SLAVE_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx327_Slave[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx327_Slave_BusInfo[]; +extern CVI_U16 g_au16Imx327_Slave_GainMode[]; +extern CVI_U16 g_au16Imx327_Slave_UseHwSync[]; +extern const CVI_U8 imx327_slave_i2c_addr; +extern const CVI_U32 imx327_slave_addr_byte; +extern const CVI_U32 imx327_slave_data_byte; +extern void imx327_slave_init(VI_PIPE ViPipe); +extern void imx327_slave_exit(VI_PIPE ViPipe); +extern void imx327_slave_standby(VI_PIPE ViPipe); +extern void imx327_slave_restart(VI_PIPE ViPipe); +extern int imx327_slave_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx327_slave_read_register(VI_PIPE ViPipe, int addr); +extern void imx327_slave_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int imx327_slave_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_SLAVE_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_slave/imx327_slave_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_slave/imx327_slave_cmos_param.h new file mode 100644 index 000000000..5977e6755 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_slave/imx327_slave_cmos_param.h @@ -0,0 +1,417 @@ +#ifndef __IMX327_SLAVE_CMOS_PARAM_H_ +#define __IMX327_SLAVE_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_slave_cmos_ex.h" + +static const IMX327_SLAVE_MODE_S g_astImx327_Slave_mode[IMX327_SLAVE_MODE_NUM] = { + [IMX327_SLAVE_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x1130, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX327_SLAVE_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1097, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 8, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 2236, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 7, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, +}; + +// F1.8 Lens +#ifdef F18 +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = { + /*************Calibration LUT Table*************/ + .CalibrationCoef = { + { //iso 100 + {0.03243722766637802, 3.855583906173706}, //B: slope, intercept + {0.024103811010718346, 3.9538209438323975}, //Gb: slope, intercept + {0.022307759150862694, 4.970882892608643}, //Gr: slope, intercept + {0.02794046327471733, 3.1342978477478027}, //R: slope, intercept + }, + { //iso 200 + {0.03799639642238617, 5.526010990142822}, //B: slope, intercept + {0.02662081830203533, 7.61380672454834}, //Gb: slope, intercept + {0.025447502732276917, 8.231551170349121}, //Gr: slope, intercept + {0.032776281237602234, 5.149646282196045}, //R: slope, intercept + }, + { //iso 400 + {0.050715841352939606, 7.763713836669922}, //B: slope, intercept + {0.032093651592731476, 12.182195663452148}, //Gb: slope, intercept + {0.030688125640153885, 12.43420696258545}, //Gr: slope, intercept + {0.040235333144664764, 8.544824600219727}, //R: slope, intercept + }, + { //iso 800 + {0.06888508796691895, 10.970534324645996}, //B: slope, intercept + {0.03813415393233299, 19.28471565246582}, //Gb: slope, intercept + {0.03805641457438469, 19.625152587890625}, //Gr: slope, intercept + {0.04966627061367035, 12.69924545288086}, //R: slope, intercept + }, + { //iso 1600 + {0.08884920179843903, 15.890214920043945}, //B: slope, intercept + {0.046779610216617584, 30.772066116333008}, //Gb: slope, intercept + {0.045214589685201645, 31.489530563354492}, //Gr: slope, intercept + {0.06512749195098877, 20.34792137145996}, //R: slope, intercept + }, + { //iso 3200 + {0.1241341084241867, 20.70075225830078}, //B: slope, intercept + {0.05977431312203407, 45.98811721801758}, //Gb: slope, intercept + {0.05858884006738663, 47.11114501953125}, //Gr: slope, intercept + {0.08636551350355148, 30.561227798461914}, //R: slope, intercept + }, + { //iso 6400 + {0.1791478991508484, 30.803356170654297}, //B: slope, intercept + {0.09205856174230576, 65.60118103027344}, //Gb: slope, intercept + {0.08692053705453873, 69.85540771484375}, //Gr: slope, intercept + {0.12406758964061737, 45.617835998535156}, //R: slope, intercept + }, + { //iso 12800 + {0.2464703917503357, 44.136966705322266}, //B: slope, intercept + {0.11594483256340027, 97.8382797241211}, //Gb: slope, intercept + {0.11075824499130249, 101.47943115234375}, //Gr: slope, intercept + {0.17024046182632446, 66.47021484375}, //R: slope, intercept + }, + { //iso 25600 + {0.3376912772655487, 68.80254364013672}, //B: slope, intercept + {0.15025299787521362, 145.10032653808594}, //Gb: slope, intercept + {0.14386454224586487, 148.1698455810547}, //Gr: slope, intercept + {0.23965470492839813, 96.42337036132812}, //R: slope, intercept + }, + { //iso 51200 + {0.4279725253582001, 117.4070816040039}, //B: slope, intercept + {0.17134547233581543, 243.6494598388672}, //Gb: slope, intercept + {0.16668814420700073, 241.21603393554688}, //Gr: slope, intercept + {0.29862311482429504, 156.05364990234375}, //R: slope, intercept + }, + { //iso 102400 + {0.534967303276062, 181.45118713378906}, //B: slope, intercept + {0.2024478018283844, 365.00177001953125}, //Gb: slope, intercept + {0.20520392060279846, 362.1013488769531}, //Gr: slope, intercept + {0.40533769130706787, 241.33485412597656}, //R: slope, intercept + }, + { //iso 204800 + {0.6578512191772461, 286.16363525390625}, //B: slope, intercept + {0.223756805062294, 551.998779296875}, //Gb: slope, intercept + {0.22110669314861298, 562.9724731445312}, //Gr: slope, intercept + {0.4937806725502014, 371.5768737792969}, //R: slope, intercept + }, + { //iso 409600 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + //------------------------------------------------------------- + { //iso 819200 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + { //iso 1638400 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + { //iso 3276800 + {0.5731459259986877, 525.5570678710938}, //B: slope, intercept + {0.11877097189426422, 962.0527954101562}, //Gb: slope, intercept + {0.13799689710140228, 933.2637329101562}, //Gr: slope, intercept + {0.3682960867881775, 696.024658203125}, //R: slope, intercept + }, + } + /*********************************************/ +}; +#endif + +// F1.0 Lens +#ifdef F10 +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.038478557020425796517, 2.14561891555786132813}, //B: slope, intercept + {0.03633839637041091919, 0.17788629233837127686}, //Gb: slope, intercept + {0.03592018783092498779, 0.21645727753639221191}, //Gr: slope, intercept + {0.03592239692807197571, 1.48806631565093994141}, //R: slope, intercept + }, + { //iso 200 + {0.04168356582522392273, 4.38879251480102539063}, //B: slope, intercept + {0.03754633292555809021, 3.21502065658569335938}, //Gb: slope, intercept + {0.03759334236383438110, 3.48370814323425292969}, //Gr: slope, intercept + {0.03719408065080642700, 4.63629007339477539063}, //R: slope, intercept + }, + { //iso 400 + {0.05050259083509445190, 6.85188436508178710938}, //B: slope, intercept + {0.04007886722683906555, 8.49916744232177734375}, //Gb: slope, intercept + {0.03934165090322494507, 8.68585968017578125000}, //Gr: slope, intercept + {0.04134147986769676208, 8.89877605438232421875}, //R: slope, intercept + }, + { //iso 800 + {0.04306267201900482178, 15.41853904724121093750}, //B: slope, intercept + {0.03570587188005447388, 18.56583213806152343750}, //Gb: slope, intercept + {0.03533876314759254456, 19.57685661315917968750}, //Gr: slope, intercept + {0.03832129389047622681, 17.90320968627929687500}, //R: slope, intercept + }, + { //iso 1600 + {0.06225715205073356628, 21.87150573730468750000}, //B: slope, intercept + {0.04437549784779548645, 30.87298965454101562500}, //Gb: slope, intercept + {0.04517432302236557007, 29.32084465026855468750}, //Gr: slope, intercept + {0.05255207046866416931, 26.26001358032226562500}, //R: slope, intercept + }, + { //iso 3200 + {0.07859147340059280396, 32.48978424072265625000}, //B: slope, intercept + {0.05918205901980400085, 45.08999633789062500000}, //Gb: slope, intercept + {0.05711782723665237427, 48.86173248291015625000}, //Gr: slope, intercept + {0.07310666143894195557, 36.88227081298828125000}, //R: slope, intercept + }, + { //iso 6400 + {0.11759266257286071777, 45.81345367431640625000}, //B: slope, intercept + {0.07679814100265502930, 69.04325866699218750000}, //Gb: slope, intercept + {0.07774948328733444214, 66.52905273437500000000}, //Gr: slope, intercept + {0.10286796092987060547, 51.73817443847656250000}, //R: slope, intercept + }, + { //iso 12800 + {0.15860086679458618164, 64.15329742431640625000}, //B: slope, intercept + {0.10511043667793273926, 91.36695098876953125000}, //Gb: slope, intercept + {0.10040879994630813599, 92.05632781982421875000}, //Gr: slope, intercept + {0.13499946892261505127, 73.36162567138671875000}, //R: slope, intercept + }, + { //iso 25600 + {0.22810073196887969971, 100.01741027832031250000}, //B: slope, intercept + {0.14736327528953552246, 146.62678527832031250000}, //Gb: slope, intercept + {0.15503610670566558838, 136.06079101562500000000}, //Gr: slope, intercept + {0.20250190794467926025, 112.74269104003906250000}, //R: slope, intercept + }, + { //iso 51200 + {0.29010805487632751465, 155.05882263183593750000}, //B: slope, intercept + {0.20221179723739624023, 210.97210693359375000000}, //Gb: slope, intercept + {0.21603405475616455078, 201.40393066406250000000}, //Gr: slope, intercept + {0.27819159626960754395, 165.48959350585937500000}, //R: slope, intercept + }, + { //iso 102400 + {0.40437409281730651855, 245.11883544921875000000}, //B: slope, intercept + {0.26703724265098571777, 345.62698364257812500000}, //Gb: slope, intercept + {0.27536261081695556641, 318.75701904296875000000}, //Gr: slope, intercept + {0.44441288709640502930, 222.47651672363281250000}, //R: slope, intercept + }, + { //iso 204800 + {0.48959052562713623047, 383.21560668945312500000}, //B: slope, intercept + {0.37694901227951049805, 442.55813598632812500000}, //Gb: slope, intercept + {0.38724529743194580078, 449.72384643554687500000}, //Gr: slope, intercept + {0.60220617055892944336, 318.92291259765625000000}, //R: slope, intercept + }, + { //iso 409600 + {0.59899300336837768555, 580.43414306640625000000}, //B: slope, intercept + {0.43681395053863525391, 700.22204589843750000000}, //Gb: slope, intercept + {0.50216537714004516602, 633.89794921875000000000}, //Gr: slope, intercept + {0.77917146682739257813, 453.13076782226562500000}, //R: slope, intercept + }, + { //iso 819200 + {0.54956322908401489258, 871.06585693359375000000}, //B: slope, intercept + {0.38088488578796386719, 1040.72192382812500000000}, //Gb: slope, intercept + {0.47245877981185913086, 937.37445068359375000000}, //Gr: slope, intercept + {0.70387065410614013672, 730.45373535156250000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.67512661218643188477, 797.11108398437500000000}, //B: slope, intercept + {0.50457936525344848633, 962.40740966796875000000}, //Gb: slope, intercept + {0.59857457876205444336, 856.90533447265625000000}, //Gr: slope, intercept + {0.74725526571273803711, 740.04290771484375000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.79927802085876464844, 687.07183837890625000000}, //B: slope, intercept + {0.81719654798507690430, 687.01580810546875000000}, //Gb: slope, intercept + {0.83395677804946899414, 658.91857910156250000000}, //Gr: slope, intercept + {0.72803622484207153320, 746.19427490234375000000}, //R: slope, intercept + }, +} }; +#endif + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {240, 240, 240, 240, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1088, 1088, 1088, 1088 +#endif + }, + .stAuto = { + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, +#endif + }, + }, +}; + +struct combo_dev_attr_s imx327_slave_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {4, 3, 5, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_DOL, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 1, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_SLAVE_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_slave/imx327_slave_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_slave/imx327_slave_sensor_ctl.c new file mode 100644 index 000000000..54d461abf --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_slave/imx327_slave_sensor_ctl.c @@ -0,0 +1,421 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_slave_cmos_ex.h" + +static void imx327_slave_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void imx327_slave_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 imx327_slave_i2c_addr = 0x1A; +const CVI_U32 imx327_slave_addr_byte = 2; +const CVI_U32 imx327_slave_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx327_slave_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx327_Slave_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx327_slave_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int imx327_slave_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx327_slave_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (imx327_slave_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, imx327_slave_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, imx327_slave_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (imx327_slave_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int imx327_slave_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx327_slave_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx327_slave_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx327_slave_addr_byte + imx327_slave_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx327_slave_standby(VI_PIPE ViPipe) +{ + imx327_slave_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ +} + +void imx327_slave_restart(VI_PIPE ViPipe) +{ + imx327_slave_write_register(ViPipe, 0x3000, 0x00); /* standby */ +} + +void imx327_slave_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx327_Slave[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx327_slave_write_register(ViPipe, + g_pastImx327_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx327_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define IMX327_CHIP_ID_ADDR 0x31dc +#define IMX327_CHIP_ID 0x6 +#define IMX327_CHIP_ID_MASK 0x6 + +void imx327_slave_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = imx327_slave_read_register(ViPipe, 0x3007) & ~0x3; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + imx327_slave_write_register(ViPipe, 0x3007, val); +} + +int imx327_slave_probe(VI_PIPE ViPipe) +{ + int nVal; + + usleep(100); + if (imx327_slave_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = imx327_slave_read_register(ViPipe, IMX327_CHIP_ID_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((nVal & IMX327_CHIP_ID_MASK) != IMX327_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void imx327_slave_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastImx327_Slave[ViPipe]->enWDRMode; + u8ImgMode = g_pastImx327_Slave[ViPipe]->u8ImgMode; + + imx327_slave_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == IMX327_SLAVE_MODE_1080P30_WDR) { + imx327_slave_wdr_1080p30_2to1_init(ViPipe); + } + } else { + imx327_slave_linear_1080p30_init(ViPipe); + } + g_pastImx327_Slave[ViPipe]->bInit = CVI_TRUE; +} + +void imx327_slave_exit(VI_PIPE ViPipe) +{ + imx327_slave_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void imx327_slave_linear_1080p30_init(VI_PIPE ViPipe) +{ + imx327_slave_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_slave_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_slave_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx327_slave_write_register(ViPipe, 0x3005, 0x01); /* ADBIT 10bit*/ + imx327_slave_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx327_slave_write_register(ViPipe, 0x3009, 0x02); /**/ + imx327_slave_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx327_slave_write_register(ViPipe, 0x3010, 0x21); + imx327_slave_write_register(ViPipe, 0x3011, 0x02); + imx327_slave_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx327_slave_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx327_slave_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx327_slave_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx327_slave_write_register(ViPipe, 0x301C, 0x30); /* HMAX[7:0], TBD*/ + imx327_slave_write_register(ViPipe, 0x301D, 0x11); /* HMAX[15:8]*/ + imx327_slave_write_register(ViPipe, 0x3020, 0x8C); /* SHS[7:0], TBD*/ + imx327_slave_write_register(ViPipe, 0x3021, 0x01); /* SHS[15:8]*/ + imx327_slave_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx327_slave_write_register(ViPipe, 0x3046, 0x01); + imx327_slave_write_register(ViPipe, 0x304B, 0x00); + imx327_slave_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx327_slave_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx327_slave_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx327_slave_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx327_slave_write_register(ViPipe, 0x309E, 0x4A); + imx327_slave_write_register(ViPipe, 0x309F, 0x4A); + imx327_slave_write_register(ViPipe, 0x30D2, 0x19); + imx327_slave_write_register(ViPipe, 0x30D7, 0x03); + imx327_slave_write_register(ViPipe, 0x3129, 0x00); + imx327_slave_write_register(ViPipe, 0x313B, 0x61); + imx327_slave_write_register(ViPipe, 0x315E, 0x1A); + imx327_slave_write_register(ViPipe, 0x3164, 0x1A); + imx327_slave_write_register(ViPipe, 0x317C, 0x00); + imx327_slave_write_register(ViPipe, 0x31EC, 0x0E); + imx327_slave_write_register(ViPipe, 0x3405, 0x10); /* Repetition*/ + imx327_slave_write_register(ViPipe, 0x3407, 0x01); /* physical_lane_nl*/ + imx327_slave_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx327_slave_write_register(ViPipe, 0x3418, 0x49); /* y_out_size*/ + imx327_slave_write_register(ViPipe, 0x3419, 0x04); /* y_out_size*/ + imx327_slave_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx327_slave_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx327_slave_write_register(ViPipe, 0x3443, 0x01); /* csi_lane_mode*/ + imx327_slave_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx327_slave_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx327_slave_write_register(ViPipe, 0x3446, 0x57); /* tclkpost*/ + imx327_slave_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + //imx327_slave_write_register(ViPipe, 0x3448, 0x37); /* thszero*/ + imx327_slave_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx327_slave_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx327_slave_write_register(ViPipe, 0x344A, 0x1F); /* thsprepare*/ + imx327_slave_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx327_slave_write_register(ViPipe, 0x344C, 0x1F); /* tclktrail*/ + imx327_slave_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + //imx327_slave_write_register(ViPipe, 0x344E, 0x1F); /* thstrail*/ + imx327_slave_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx327_slave_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx327_slave_write_register(ViPipe, 0x3450, 0x77); /* tclkzero*/ + imx327_slave_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx327_slave_write_register(ViPipe, 0x3452, 0x1F); /* tclkprepare*/ + imx327_slave_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx327_slave_write_register(ViPipe, 0x3454, 0x17); /* tlpx*/ + imx327_slave_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx327_slave_write_register(ViPipe, 0x3472, 0x9C); /* x_out_size*/ + imx327_slave_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx327_slave_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx327_slave_default_reg_init(ViPipe); + + imx327_slave_write_register(ViPipe, 0x3000, 0x00); /* standby */ + + if (!g_au16Imx327_Slave_UseHwSync[ViPipe]) { + delay_ms(20); + imx327_slave_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_slave_write_register(ViPipe, 0x304b, 0x0a); + } + + printf("ViPipe:%d,===IMX327 1080P 30fps 12bit LINE Slave Init OK!===\n", ViPipe); +} + +static void imx327_slave_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + imx327_slave_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_slave_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_slave_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx327_slave_write_register(ViPipe, 0x3005, 0x01); /* ADBIT*/ + imx327_slave_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ...*/ + imx327_slave_write_register(ViPipe, 0x3009, 0x01); /**/ + imx327_slave_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL*/ + imx327_slave_write_register(ViPipe, 0x300C, 0x11); /* WDMODE [0] 0:Normal, 1:DOL, WDSEL [5:4] 1:DOL 2 frames*/ + imx327_slave_write_register(ViPipe, 0x3011, 0x02); + imx327_slave_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD*/ + imx327_slave_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0]*/ + imx327_slave_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8]*/ + imx327_slave_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0]*/ + imx327_slave_write_register(ViPipe, 0x301C, 0x98); /* HMAX[7:0], TBD*/ + imx327_slave_write_register(ViPipe, 0x301D, 0x08); /* HMAX[15:8]*/ + imx327_slave_write_register(ViPipe, 0x3020, 0x02); /* SHS[7:0], TBD*/ + imx327_slave_write_register(ViPipe, 0x3021, 0x00); /* SHS[15:8]*/ + imx327_slave_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16]*/ + imx327_slave_write_register(ViPipe, 0x3024, 0xC9); /* SHS2[7:0], TBD*/ + imx327_slave_write_register(ViPipe, 0x3025, 0x07); /* SHS2[15:8]*/ + imx327_slave_write_register(ViPipe, 0x3026, 0x00); /* SHS2[19:16]*/ + imx327_slave_write_register(ViPipe, 0x3030, 0x0B); /* RHS1[7:0], TBD*/ + imx327_slave_write_register(ViPipe, 0x3031, 0x00); /* RHS1[15:8]*/ + imx327_slave_write_register(ViPipe, 0x3032, 0x00); /* RHS1[19:16]*/ + imx327_slave_write_register(ViPipe, 0x3045, 0x05); /* DOLSCDEN [0] 1: pattern1 0: pattern2*/ + imx327_slave_write_register(ViPipe, 0x3046, 0x01); + imx327_slave_write_register(ViPipe, 0x304B, 0x0A); + imx327_slave_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1*/ + imx327_slave_write_register(ViPipe, 0x305D, 0x03); /* INCKSEL2*/ + imx327_slave_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3*/ + imx327_slave_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4*/ + imx327_slave_write_register(ViPipe, 0x309E, 0x4A); + imx327_slave_write_register(ViPipe, 0x309F, 0x4A); + imx327_slave_write_register(ViPipe, 0x30D2, 0x19); + imx327_slave_write_register(ViPipe, 0x30D7, 0x03); + imx327_slave_write_register(ViPipe, 0x3106, 0x11); /*DOLHBFIXEN[7] 0: pattern1 1: pattern2*/ + imx327_slave_write_register(ViPipe, 0x3129, 0x00); + imx327_slave_write_register(ViPipe, 0x313B, 0x61); + imx327_slave_write_register(ViPipe, 0x315E, 0x1A); + imx327_slave_write_register(ViPipe, 0x3164, 0x1A); + imx327_slave_write_register(ViPipe, 0x317C, 0x00); + imx327_slave_write_register(ViPipe, 0x31EC, 0x0E); + imx327_slave_write_register(ViPipe, 0x3405, 0x00); /* Repetition*/ + imx327_slave_write_register(ViPipe, 0x3407, 0x01); /* physical_lane_nl*/ + imx327_slave_write_register(ViPipe, 0x3414, 0x0A); /* opb_size_v*/ + imx327_slave_write_register(ViPipe, 0x3415, 0x00); /* NULL0_SIZE_V, set to 00h when DOL*/ + imx327_slave_write_register(ViPipe, 0x3418, 0xB4); /* y_out_size*/ + imx327_slave_write_register(ViPipe, 0x3419, 0x08); /* y_out_size*/ + imx327_slave_write_register(ViPipe, 0x3441, 0x0C); /* csi_dt_fmt*/ + imx327_slave_write_register(ViPipe, 0x3442, 0x0C); /* csi_dt_fmt*/ + imx327_slave_write_register(ViPipe, 0x3443, 0x01); /* csi_lane_mode*/ + imx327_slave_write_register(ViPipe, 0x3444, 0x20); /* extck_freq*/ + imx327_slave_write_register(ViPipe, 0x3445, 0x25); /* extck_freq*/ + imx327_slave_write_register(ViPipe, 0x3446, 0x77); /* tclkpost*/ + imx327_slave_write_register(ViPipe, 0x3447, 0x00); /* tclkpost*/ + imx327_slave_write_register(ViPipe, 0x3448, 0x80); /* thszero*/ + imx327_slave_write_register(ViPipe, 0x3449, 0x00); /* thszero*/ + imx327_slave_write_register(ViPipe, 0x344A, 0x47); /* thsprepare*/ + imx327_slave_write_register(ViPipe, 0x344B, 0x00); /* thsprepare*/ + imx327_slave_write_register(ViPipe, 0x344C, 0x37); /* tclktrail*/ + imx327_slave_write_register(ViPipe, 0x344D, 0x00); /* tclktrail*/ + imx327_slave_write_register(ViPipe, 0x344E, 0x80); /* thstrail*/ + imx327_slave_write_register(ViPipe, 0x344F, 0x00); /* thstrail*/ + imx327_slave_write_register(ViPipe, 0x3450, 0xFF); /* tclkzero*/ + imx327_slave_write_register(ViPipe, 0x3451, 0x00); /* tclkzero*/ + imx327_slave_write_register(ViPipe, 0x3452, 0x3F); /* tclkprepare*/ + imx327_slave_write_register(ViPipe, 0x3453, 0x00); /* tckkprepare*/ + imx327_slave_write_register(ViPipe, 0x3454, 0x37); /* tlpx*/ + imx327_slave_write_register(ViPipe, 0x3455, 0x00); /* tlpx*/ + imx327_slave_write_register(ViPipe, 0x3472, 0xA0); /* x_out_size*/ + imx327_slave_write_register(ViPipe, 0x3473, 0x07); /* x_out_size*/ + imx327_slave_write_register(ViPipe, 0x347B, 0x23); /**/ + imx327_slave_write_register(ViPipe, 0x3480, 0x49); /* incksel7*/ + + imx327_slave_default_reg_init(ViPipe); + + if (g_au16Imx327_Slave_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + imx327_slave_write_register(ViPipe, 0x30F0, 0xF0); + imx327_slave_write_register(ViPipe, 0x3010, 0x21); + } else { + imx327_slave_write_register(ViPipe, 0x30F0, 0x64); + imx327_slave_write_register(ViPipe, 0x3010, 0x61); + } + + imx327_slave_write_register(ViPipe, 0x3000, 0x00); /* standby */ + + if (!g_au16Imx327_Slave_UseHwSync[ViPipe]) { + delay_ms(20); + imx327_slave_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_slave_write_register(ViPipe, 0x304b, 0x0a); + } else + imx327_slave_write_register(ViPipe, 0x3106, 0x40); /* XVS/XHS sub-sampling */ + + printf("===Imx327 sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) Slave init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_sublvds/Makefile b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_sublvds/Makefile new file mode 100644 index 000000000..db74d8c90 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_sublvds/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx327_sublvds.a +TARGET_SO = $(MW_LIB)/libsns_imx327_sublvds.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_sublvds/imx327_sublvds_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_sublvds/imx327_sublvds_cmos.c new file mode 100644 index 000000000..cd32f0c61 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_sublvds/imx327_sublvds_cmos.c @@ -0,0 +1,1137 @@ +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "imx327_sublvds_cmos_ex.h" +#include "imx327_sublvds_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX327_SUBLVDS_ID 327 +#define SENSOR_IMX327_SUBLVDS_WIDTH 1920 +#define SENSOR_IMX327_SUBLVDS_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx327_sublvds[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX327_SUBLVDS_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx327_sublvds[dev]) +#define IMX327_SUBLVDS_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx327_sublvds[dev] = pstCtx) +#define IMX327_SUBLVDS_SENSOR_RESET_CTX(dev) (g_pastImx327_sublvds[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunImx327_sublvds_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx327_sublvds_GainMode[VI_MAX_PIPE_NUM] = {0}; + +IMX327_SUBLVDS_STATE_S g_astImx327_sublvds_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx327_sublvds_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx327_sublvds Lines Range*****/ +#define IMX327_SUBLVDS_FULL_LINES_MAX (0x3FFFF) +#define IMX327_SUBLVDS_FULL_LINES_MAX_2TO1_WDR (0x3FFFF) // considering the YOUT_SIZE and bad frame +#define IMX327_SUBLVDS_VMAX_1080P30_LINEAR 1125 + +/*****Imx327_sublvds Register Address*****/ +#define IMX327_SUBLVDS_HOLD_ADDR 0x3001 +#define IMX327_SUBLVDS_SHS1_ADDR 0x3020 +#define IMX327_SUBLVDS_SHS2_ADDR 0x3024 +#define IMX327_SUBLVDS_GAIN_ADDR 0x3014 +#define IMX327_SUBLVDS_GAIN1_ADDR 0x30F2 +#define IMX327_SUBLVDS_HCG_ADDR 0x3009 +#define IMX327_SUBLVDS_VMAX_ADDR 0x3018 +#define IMX327_SUBLVDS_HMAX_ADDR 0x301C +#define IMX327_SUBLVDS_YOUT_ADDR 0x3418 +#define IMX327_SUBLVDS_RHS1_ADDR 0x3030 +#define IMX327_SUBLVDS_TABLE_END 0xffff + +#define IMX327_SUBLVDS_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX327_SUBLVDS_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astImx327_sublvds_mode[IMX327_SUBLVDS_MODE_1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_sublvds_mode[IMX327_SUBLVDS_MODE_1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 1; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astImx327_sublvds_mode[IMX327_SUBLVDS_MODE_1080P30_WDR].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx327_sublvds_mode[IMX327_SUBLVDS_MODE_1080P30_WDR].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 82281; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX, u32HMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32VMAX = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].u32VtsDef; + u32HMAX = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].u32HtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].f32MinFps; + + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32HMAX = u32HMAX * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor fps: %f\n", f32Fps); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_HMAX_0].u32Data = (u32HMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HMAX_1].u32Data = ((u32HMAX & 0xFF00) >> 8); + } else { + pstSnsRegsInfo->astI2cData[DOL2_HMAX_0].u32Data = (u32HMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HMAX_1].u32Data = ((u32HMAX & 0xFF00) >> 8); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx327_sublvds_State[ViPipe].u32RHS1_MAX = + (u32VMAX - g_astImx327_sublvds_State[ViPipe].u32BRL) * 2 - 21; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHS1 = 0; + CVI_U32 u32SHS2 = 0; + CVI_U32 u32YOUTSIZE; + CVI_U32 u16BRL = 0; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u16BRL = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].u16BRL; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[1] < u32LongIntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[1], u32LongIntTime - 1); + return CVI_FAILURE; + } + u32SHS2 = pstSnsState->au32FL[1] - u32LongIntTime - 1; + + u32SHS1 = (u32ShortIntTime % 2) + 2; + u32RHS1 = u32ShortIntTime + u32SHS1 + 1; + g_astImx327_sublvds_State[ViPipe].u32RHS1 = u32RHS1; + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - (u32SHS1 + 1); + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[1] - (u32SHS2 + 1); + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + u32YOUTSIZE = (u16BRL + (u32RHS1 - 1) / 2) * 2; + u32YOUTSIZE = (u32YOUTSIZE >= 0x1FFF) ? 0x1FFF : u32YOUTSIZE; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHS1 = %d\n", u32ShortIntTime, u32SHS1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d u32YOUTSIZE = %d\n", ViPipe, u32RHS1, u32YOUTSIZE); + + pstSnsRegsInfo->astI2cData[DOL2_SHS1_0].u32Data = (u32SHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_1].u32Data = ((u32SHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS1_2].u32Data = ((u32SHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHS2_0].u32Data = (u32SHS2 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_1].u32Data = ((u32SHS2 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHS2_2].u32Data = ((u32SHS2 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_0].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_1].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_2].u32Data = ((u32RHS1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_0].u32Data = (u32YOUTSIZE & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_YOUT_SIZE_1].u32Data = ((u32YOUTSIZE & 0x1F00) >> 8); + /* update isp */ + cmos_get_wdr_size(ViPipe, &pstSnsState->astSyncInfo[0].ispCfg); + } else { + if (pstSnsState->au32FL[0] < *u32IntTime - 1) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[0], *u32IntTime - 1); + return CVI_FAILURE; + } + u32Value = pstSnsState->au32FL[0] - *u32IntTime - 1; + + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2].u32Data = ((u32Value & 0x30000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 327567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32HCG = g_astImx327_sublvds_State[ViPipe].u8Hcg; + CVI_U32 u16Mode = g_au16Imx327_sublvds_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = (u32HCG & 0xFF); + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + CVI_U8 bEnableHCG = 0; + + if (pu32Again[0] >= 20 && pu32Again[1] >= 20) { + /* hcg bit[4]*/ + u32HCG |= 0x10; + bEnableHCG = 1; + } + + u32Again = pu32Again[1] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + + u32Again = pu32Again[0] - ((bEnableHCG == 1) ? 20 : 0); + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0xFF) { + u32Tmp = 0xFF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN1].u32Data = (u32Tmp & 0xFF); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + if (u32Again >= 27) { + /* hcg bit[4]*/ + u32HCG = u32HCG | 0x10; + u32Again = u32Again - 27; + } + + u32Tmp = u32Again + u32Dgain; + pstSnsRegsInfo->astI2cData[DOL2_GAIN].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_HCG].u32Data = (u32HCG & 0xFF); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = 2; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 10; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx327_sublvds_State[ViPipe].u32RHS1_MAX - 3)) ? + (g_astImx327_sublvds_State[ViPipe].u32RHS1_MAX - 3) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX327_SUBLVDS_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx327_sublvds_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX327_SUBLVDS_MODE_1080P30_WDR) + pstSnsState->u8ImgMode = IMX327_SUBLVDS_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].u32VtsDef; + g_astImx327_sublvds_State[ViPipe].u8Hcg = 0x2; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX327_SUBLVDS_MODE_1080P30) + pstSnsState->u8ImgMode = IMX327_SUBLVDS_MODE_1080P30_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + g_astImx327_sublvds_State[ViPipe].u8Hcg = 0x1; + if (pstSnsState->u8ImgMode == IMX327_SUBLVDS_MODE_1080P30_WDR) { + pstSnsState->u32FLStd = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx327_sublvds_State[ViPipe].u32BRL = + g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].u16BRL; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1080p\n"); + } + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx327_sublvds_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 2; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx327_sublvds_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx327_sublvds_addr_byte; + pstI2c_data[i].u32DataByteNum = imx327_sublvds_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_HOLD].u32RegAddr = IMX327_SUBLVDS_HOLD_ADDR; + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_SHS1_0].u32RegAddr = IMX327_SUBLVDS_SHS1_ADDR; + pstI2c_data[DOL2_SHS1_1].u32RegAddr = IMX327_SUBLVDS_SHS1_ADDR + 1; + pstI2c_data[DOL2_SHS1_2].u32RegAddr = IMX327_SUBLVDS_SHS1_ADDR + 2; + + pstI2c_data[DOL2_GAIN].u32RegAddr = IMX327_SUBLVDS_GAIN_ADDR; + pstI2c_data[DOL2_HCG].u32RegAddr = IMX327_SUBLVDS_HCG_ADDR; + pstI2c_data[DOL2_HCG].u8DelayFrmNum = 1; + pstI2c_data[DOL2_GAIN1].u32RegAddr = IMX327_SUBLVDS_GAIN1_ADDR; + pstI2c_data[DOL2_RHS1_0].u32RegAddr = IMX327_SUBLVDS_RHS1_ADDR; + pstI2c_data[DOL2_RHS1_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_1].u32RegAddr = IMX327_SUBLVDS_RHS1_ADDR + 1; + pstI2c_data[DOL2_RHS1_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_RHS1_2].u32RegAddr = IMX327_SUBLVDS_RHS1_ADDR + 2; + pstI2c_data[DOL2_RHS1_2].u8DelayFrmNum = 1; + pstI2c_data[DOL2_SHS2_0].u32RegAddr = IMX327_SUBLVDS_SHS2_ADDR; + pstI2c_data[DOL2_SHS2_1].u32RegAddr = IMX327_SUBLVDS_SHS2_ADDR + 1; + pstI2c_data[DOL2_SHS2_2].u32RegAddr = IMX327_SUBLVDS_SHS2_ADDR + 2; + pstI2c_data[DOL2_HMAX_0].u32RegAddr = IMX327_SUBLVDS_HMAX_ADDR; + pstI2c_data[DOL2_HMAX_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_HMAX_1].u32RegAddr = IMX327_SUBLVDS_HMAX_ADDR + 1; + pstI2c_data[DOL2_HMAX_1].u8DelayFrmNum = 1; + + pstI2c_data[DOL2_YOUT_SIZE_0].u32RegAddr = IMX327_SUBLVDS_YOUT_ADDR; + pstI2c_data[DOL2_YOUT_SIZE_0].u8DelayFrmNum = 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u32RegAddr = IMX327_SUBLVDS_YOUT_ADDR + 1; + pstI2c_data[DOL2_YOUT_SIZE_1].u8DelayFrmNum = 1; + pstI2c_data[DOL2_REL].u32RegAddr = IMX327_SUBLVDS_HOLD_ADDR; + pstI2c_data[DOL2_REL].u32Data = 0; + break; + default: + pstI2c_data[LINEAR_HOLD].u32RegAddr = IMX327_SUBLVDS_HOLD_ADDR; + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_SHS1_0].u32RegAddr = IMX327_SUBLVDS_SHS1_ADDR; + pstI2c_data[LINEAR_SHS1_1].u32RegAddr = IMX327_SUBLVDS_SHS1_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2].u32RegAddr = IMX327_SUBLVDS_SHS1_ADDR + 2; + pstI2c_data[LINEAR_GAIN].u32RegAddr = IMX327_SUBLVDS_GAIN_ADDR; + pstI2c_data[LINEAR_HCG].u32RegAddr = IMX327_SUBLVDS_HCG_ADDR; + pstI2c_data[LINEAR_HCG].u8DelayFrmNum = 1; + pstI2c_data[LINEAR_HMAX_0].u32RegAddr = IMX327_SUBLVDS_HMAX_ADDR; + pstI2c_data[LINEAR_HMAX_1].u32RegAddr = IMX327_SUBLVDS_HMAX_ADDR + 1; + pstI2c_data[LINEAR_REL].u32RegAddr = IMX327_SUBLVDS_HOLD_ADDR; + pstI2c_data[LINEAR_REL].u32Data = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (pstCfg0->snsCfg.need_update == CVI_TRUE) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstI2c_data[DOL2_HOLD].u32Data = 1; + pstI2c_data[DOL2_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[DOL2_REL].u32Data = 0; + pstI2c_data[DOL2_REL].bUpdate = CVI_TRUE; + } else { + pstI2c_data[LINEAR_HOLD].u32Data = 1; + pstI2c_data[LINEAR_HOLD].bUpdate = CVI_TRUE; + pstI2c_data[LINEAR_REL].u32Data = 0; + pstI2c_data[LINEAR_REL].bUpdate = CVI_TRUE; + } + } + pstCfg0->ispCfg.need_update = CVI_FALSE; + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX327_SUBLVDS_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_SUBLVDS_MODE_1080P30; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX327_SUBLVDS_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = IMX327_SUBLVDS_MODE_1080P30_WDR; + g_astImx327_sublvds_State[ViPipe].u32BRL = 1109; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx327_sublvds_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx327_sublvds_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx327_sublvds_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = IMX327_SUBLVDS_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = IMX327_SUBLVDS_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[0] = IMX327_SUBLVDS_VMAX_1080P30_LINEAR; + pstSnsState->au32FL[1] = IMX327_SUBLVDS_VMAX_1080P30_LINEAR; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx327_sublvds_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx327_sublvds_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstRxAttr->lvds_attr.wdr_mode = CVI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx327_sublvds_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx327_sublvds_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx327_sublvds_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx327_sublvds_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx327_sublvds_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX327_SUBLVDS_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX327_SUBLVDS_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX327_SUBLVDS_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX327_SUBLVDS_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX327_SUBLVDS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX327_SUBLVDS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX327_SUBLVDS_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx327_sublvds_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return imx327_sublvds_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsImx327_Sublvds_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx327_sublvds_standby, + .pfnRestart = imx327_sublvds_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx327_sublvds_write_register, + .pfnReadReg = imx327_sublvds_read_register, + .pfnSetBusInfo = imx327_sublvds_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_sublvds/imx327_sublvds_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_sublvds/imx327_sublvds_cmos_ex.h new file mode 100644 index 000000000..493a18f00 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_sublvds/imx327_sublvds_cmos_ex.h @@ -0,0 +1,113 @@ +#ifndef __IMX327_SUBLVDS_CMOS_EX_H_ +#define __IMX327_SUBLVDS_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +enum imx327_sublvds_linear_regs_e { + LINEAR_HOLD = 0, + LINEAR_SHS1_0, + LINEAR_SHS1_1, + LINEAR_SHS1_2, + LINEAR_GAIN, + LINEAR_HCG, + LINEAR_HMAX_0, + LINEAR_HMAX_1, + LINEAR_REL, + LINEAR_REGS_NUM +}; + +enum imx327_sublvds_dol2_regs_e { + DOL2_HOLD = 0, + DOL2_SHS1_0, + DOL2_SHS1_1, + DOL2_SHS1_2, + DOL2_GAIN, + DOL2_HCG, + DOL2_GAIN1, + DOL2_RHS1_0, + DOL2_RHS1_1, + DOL2_RHS1_2, + DOL2_SHS2_0, + DOL2_SHS2_1, + DOL2_SHS2_2, + DOL2_HMAX_0, + DOL2_HMAX_1, + DOL2_YOUT_SIZE_0, + DOL2_YOUT_SIZE_1, + DOL2_REL, + DOL2_REGS_NUM +}; + +typedef enum _IMX327_SUBLVDS_MODE_E { + IMX327_SUBLVDS_MODE_1080P30 = 0, + IMX327_SUBLVDS_MODE_LINEAR_NUM, + IMX327_SUBLVDS_MODE_1080P30_WDR = IMX327_SUBLVDS_MODE_LINEAR_NUM, + IMX327_SUBLVDS_MODE_NUM +} IMX327_SUBLVDS_MODE_E; + +typedef struct _IMX327_SUBLVDS_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX327_SUBLVDS_STATE_S; + +typedef struct _IMX327_SUBLVDS_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX327_SUBLVDS_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx327_sublvds[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx327_sublvds_BusInfo[]; +extern CVI_U16 g_au16Imx327_sublvds_GainMode[]; +extern const CVI_U8 imx327_sublvds_i2c_addr; +extern const CVI_U32 imx327_sublvds_addr_byte; +extern const CVI_U32 imx327_sublvds_data_byte; +extern void imx327_sublvds_init(VI_PIPE ViPipe); +extern void imx327_sublvds_exit(VI_PIPE ViPipe); +extern void imx327_sublvds_standby(VI_PIPE ViPipe); +extern void imx327_sublvds_restart(VI_PIPE ViPipe); +extern int imx327_sublvds_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx327_sublvds_read_register(VI_PIPE ViPipe, int addr); +extern void imx327_sublvds_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int imx327_sublvds_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_SUBLVDS_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_sublvds/imx327_sublvds_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_sublvds/imx327_sublvds_cmos_param.h new file mode 100644 index 000000000..8d39343f7 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_sublvds/imx327_sublvds_cmos_param.h @@ -0,0 +1,321 @@ +#ifndef __IMX327_SUBLVDS_CMOS_PARAM_H_ +#define __IMX327_SUBLVDS_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_sublvds_cmos_ex.h" + +static const IMX327_SUBLVDS_MODE_S g_astImx327_sublvds_mode[IMX327_SUBLVDS_MODE_NUM] = { + [IMX327_SUBLVDS_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1110, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 21, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1110, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x1130, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1123, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, + [IMX327_SUBLVDS_MODE_1080P30_WDR] = { + .name = "1080p30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1110, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 21, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1110, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 1948, + .u32Height = 1110, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 21, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1948, + .u32Height = 1110, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 1125 * 30 / 0x3FFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 8, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 1, + .u16Max = 2236, + .u16Def = 828, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stAgain[1] = { + .u16Min = 1024, + .u16Max = 62416, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[1] = { + .u16Min = 1024, + .u16Max = 38485, + .u16Def = 1024, + .u16Step = 1, + }, + .u16RHS1 = 11, + .u16BRL = 1109, + .u16OpbSize = 10, + .u16MarginVtop = 8, + .u16MarginVbot = 9, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.038478557020425796517, 2.14561891555786132813}, //B: slope, intercept + {0.03633839637041091919, 0.17788629233837127686}, //Gb: slope, intercept + {0.03592018783092498779, 0.21645727753639221191}, //Gr: slope, intercept + {0.03592239692807197571, 1.48806631565093994141}, //R: slope, intercept + }, + { //iso 200 + {0.04168356582522392273, 4.38879251480102539063}, //B: slope, intercept + {0.03754633292555809021, 3.21502065658569335938}, //Gb: slope, intercept + {0.03759334236383438110, 3.48370814323425292969}, //Gr: slope, intercept + {0.03719408065080642700, 4.63629007339477539063}, //R: slope, intercept + }, + { //iso 400 + {0.05050259083509445190, 6.85188436508178710938}, //B: slope, intercept + {0.04007886722683906555, 8.49916744232177734375}, //Gb: slope, intercept + {0.03934165090322494507, 8.68585968017578125000}, //Gr: slope, intercept + {0.04134147986769676208, 8.89877605438232421875}, //R: slope, intercept + }, + { //iso 800 + {0.04306267201900482178, 15.41853904724121093750}, //B: slope, intercept + {0.03570587188005447388, 18.56583213806152343750}, //Gb: slope, intercept + {0.03533876314759254456, 19.57685661315917968750}, //Gr: slope, intercept + {0.03832129389047622681, 17.90320968627929687500}, //R: slope, intercept + }, + { //iso 1600 + {0.06225715205073356628, 21.87150573730468750000}, //B: slope, intercept + {0.04437549784779548645, 30.87298965454101562500}, //Gb: slope, intercept + {0.04517432302236557007, 29.32084465026855468750}, //Gr: slope, intercept + {0.05255207046866416931, 26.26001358032226562500}, //R: slope, intercept + }, + { //iso 3200 + {0.07859147340059280396, 32.48978424072265625000}, //B: slope, intercept + {0.05918205901980400085, 45.08999633789062500000}, //Gb: slope, intercept + {0.05711782723665237427, 48.86173248291015625000}, //Gr: slope, intercept + {0.07310666143894195557, 36.88227081298828125000}, //R: slope, intercept + }, + { //iso 6400 + {0.11759266257286071777, 45.81345367431640625000}, //B: slope, intercept + {0.07679814100265502930, 69.04325866699218750000}, //Gb: slope, intercept + {0.07774948328733444214, 66.52905273437500000000}, //Gr: slope, intercept + {0.10286796092987060547, 51.73817443847656250000}, //R: slope, intercept + }, + { //iso 12800 + {0.15860086679458618164, 64.15329742431640625000}, //B: slope, intercept + {0.10511043667793273926, 91.36695098876953125000}, //Gb: slope, intercept + {0.10040879994630813599, 92.05632781982421875000}, //Gr: slope, intercept + {0.13499946892261505127, 73.36162567138671875000}, //R: slope, intercept + }, + { //iso 25600 + {0.22810073196887969971, 100.01741027832031250000}, //B: slope, intercept + {0.14736327528953552246, 146.62678527832031250000}, //Gb: slope, intercept + {0.15503610670566558838, 136.06079101562500000000}, //Gr: slope, intercept + {0.20250190794467926025, 112.74269104003906250000}, //R: slope, intercept + }, + { //iso 51200 + {0.29010805487632751465, 155.05882263183593750000}, //B: slope, intercept + {0.20221179723739624023, 210.97210693359375000000}, //Gb: slope, intercept + {0.21603405475616455078, 201.40393066406250000000}, //Gr: slope, intercept + {0.27819159626960754395, 165.48959350585937500000}, //R: slope, intercept + }, + { //iso 102400 + {0.40437409281730651855, 245.11883544921875000000}, //B: slope, intercept + {0.26703724265098571777, 345.62698364257812500000}, //Gb: slope, intercept + {0.27536261081695556641, 318.75701904296875000000}, //Gr: slope, intercept + {0.44441288709640502930, 222.47651672363281250000}, //R: slope, intercept + }, + { //iso 204800 + {0.48959052562713623047, 383.21560668945312500000}, //B: slope, intercept + {0.37694901227951049805, 442.55813598632812500000}, //Gb: slope, intercept + {0.38724529743194580078, 449.72384643554687500000}, //Gr: slope, intercept + {0.60220617055892944336, 318.92291259765625000000}, //R: slope, intercept + }, + { //iso 409600 + {0.59899300336837768555, 580.43414306640625000000}, //B: slope, intercept + {0.43681395053863525391, 700.22204589843750000000}, //Gb: slope, intercept + {0.50216537714004516602, 633.89794921875000000000}, //Gr: slope, intercept + {0.77917146682739257813, 453.13076782226562500000}, //R: slope, intercept + }, + { //iso 819200 + {0.54956322908401489258, 871.06585693359375000000}, //B: slope, intercept + {0.38088488578796386719, 1040.72192382812500000000}, //Gb: slope, intercept + {0.47245877981185913086, 937.37445068359375000000}, //Gr: slope, intercept + {0.70387065410614013672, 730.45373535156250000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.67512661218643188477, 797.11108398437500000000}, //B: slope, intercept + {0.50457936525344848633, 962.40740966796875000000}, //Gb: slope, intercept + {0.59857457876205444336, 856.90533447265625000000}, //Gr: slope, intercept + {0.74725526571273803711, 740.04290771484375000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.79927802085876464844, 687.07183837890625000000}, //B: slope, intercept + {0.81719654798507690430, 687.01580810546875000000}, //Gb: slope, intercept + {0.83395677804946899414, 658.91857910156250000000}, //Gr: slope, intercept + {0.72803622484207153320, 746.19427490234375000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {240, 240, 240, 240, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1088, 1088, 1088, 1088 +#endif + }, + .stAuto = { + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {241, 241, 241, 241, 239, 239, 239, 238, /*8*/229, 225, 273, 355, 611, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, + {1089, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + /*8*/1085, 1084, 1098, 1122, 1204, 1365, 1365, 1365}, +#endif + }, + }, +}; + +struct combo_dev_attr_s imx327_sublvds_rx_attr = { + .input_mode = INPUT_MODE_SUBLVDS, + .mac_clk = RX_MAC_CLK_200M, + .lvds_attr = { + .wdr_mode = CVI_WDR_MODE_DOL_2F, + .sync_mode = LVDS_SYNC_MODE_SAV, + .raw_data_type = RAW_DATA_12BIT, + .data_endian = LVDS_ENDIAN_BIG, + .sync_code_endian = LVDS_ENDIAN_BIG, + .lane_id = {2, 3, 1, 4, 0}, + .pn_swap = {1, 1, 1, 1, 1}, + .sync_code = { + { + {0x801, 0x9D1, 0xC01, 0xDD1}, + {0x802, 0x9D2, 0xC02, 0xDD2}, + {0x803, 0x9D3, 0xC03, 0xDD3}, + }, + }, + .vsync_type = { + .sync_type = LVDS_VSYNC_NORMAL, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __IMX327_SUBLVDS_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx327_sublvds/imx327_sublvds_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_sublvds/imx327_sublvds_sensor_ctl.c new file mode 100644 index 000000000..48704c34b --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx327_sublvds/imx327_sublvds_sensor_ctl.c @@ -0,0 +1,358 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx327_sublvds_cmos_ex.h" + +static void imx327_sublvds_wdr_1080p30_2to1_init(VI_PIPE ViPipe); +static void imx327_sublvds_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 imx327_sublvds_i2c_addr = 0x1A; +const CVI_U32 imx327_sublvds_addr_byte = 2; +const CVI_U32 imx327_sublvds_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx327_sublvds_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx327_sublvds_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx327_sublvds_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int imx327_sublvds_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx327_sublvds_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (imx327_sublvds_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, imx327_sublvds_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, imx327_sublvds_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (imx327_sublvds_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int imx327_sublvds_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx327_sublvds_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx327_sublvds_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx327_sublvds_addr_byte + imx327_sublvds_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx327_sublvds_standby(VI_PIPE ViPipe) +{ + imx327_sublvds_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_sublvds_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ +} + +void imx327_sublvds_restart(VI_PIPE ViPipe) +{ + imx327_sublvds_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_sublvds_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_sublvds_write_register(ViPipe, 0x304b, 0x0a); +} + +void imx327_sublvds_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx327_sublvds[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx327_sublvds_write_register(ViPipe, + g_pastImx327_sublvds[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx327_sublvds[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define IMX327_CHIP_ID_ADDR 0x31dc +#define IMX327_CHIP_ID 0x6 +#define IMX327_CHIP_ID_MASK 0x6 + +void imx327_sublvds_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 val = imx327_sublvds_read_register(ViPipe, 0x3007) & ~0x3; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + val |= 0x2; + break; + case ISP_SNS_FLIP: + val |= 0x1; + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x3; + break; + default: + return; + } + + imx327_sublvds_write_register(ViPipe, 0x3007, val); +} + +int imx327_sublvds_probe(VI_PIPE ViPipe) +{ + int nVal; + + usleep(100); + if (imx327_sublvds_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = imx327_sublvds_read_register(ViPipe, IMX327_CHIP_ID_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((nVal & IMX327_CHIP_ID_MASK) != IMX327_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void imx327_sublvds_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastImx327_sublvds[ViPipe]->enWDRMode; + u8ImgMode = g_pastImx327_sublvds[ViPipe]->u8ImgMode; + + imx327_sublvds_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == IMX327_SUBLVDS_MODE_1080P30_WDR) { + imx327_sublvds_wdr_1080p30_2to1_init(ViPipe); + } + } else { + imx327_sublvds_linear_1080p30_init(ViPipe); + } + g_pastImx327_sublvds[ViPipe]->bInit = CVI_TRUE; +} + +void imx327_sublvds_exit(VI_PIPE ViPipe) +{ + imx327_sublvds_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void imx327_sublvds_linear_1080p30_init(VI_PIPE ViPipe) +{ + imx327_sublvds_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_sublvds_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_sublvds_write_register(ViPipe, 0x3002, 0x00); /* XMSTA */ + imx327_sublvds_write_register(ViPipe, 0x3005, 0x01); /* ADBIT 10bit */ + imx327_sublvds_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ... */ + imx327_sublvds_write_register(ViPipe, 0x3009, 0x02); + imx327_sublvds_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL */ + imx327_sublvds_write_register(ViPipe, 0x3011, 0x02); + imx327_sublvds_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD */ + imx327_sublvds_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0] */ + imx327_sublvds_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8] */ + imx327_sublvds_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0] */ + imx327_sublvds_write_register(ViPipe, 0x301C, 0x30); /* HMAX[7:0], TBD */ + imx327_sublvds_write_register(ViPipe, 0x301D, 0x11); /* HMAX[15:8] */ + imx327_sublvds_write_register(ViPipe, 0x3020, 0x8C); /* SHS[7:0], TBD */ + imx327_sublvds_write_register(ViPipe, 0x3021, 0x01); /* SHS[15:8] */ + imx327_sublvds_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16] */ + imx327_sublvds_write_register(ViPipe, 0x3046, 0xE1); + imx327_sublvds_write_register(ViPipe, 0x304B, 0x0A); + imx327_sublvds_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1 */ + imx327_sublvds_write_register(ViPipe, 0x305D, 0x00); /* INCKSEL2 */ + imx327_sublvds_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3 */ + imx327_sublvds_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4 */ + imx327_sublvds_write_register(ViPipe, 0x309E, 0x4A); + imx327_sublvds_write_register(ViPipe, 0x309F, 0x4A); + imx327_sublvds_write_register(ViPipe, 0x30D2, 0x19); + imx327_sublvds_write_register(ViPipe, 0x30D7, 0x03); + imx327_sublvds_write_register(ViPipe, 0x3129, 0x00); + imx327_sublvds_write_register(ViPipe, 0x313B, 0x61); + imx327_sublvds_write_register(ViPipe, 0x315E, 0x1A); + imx327_sublvds_write_register(ViPipe, 0x3164, 0x1A); + imx327_sublvds_write_register(ViPipe, 0x317C, 0x00); + imx327_sublvds_write_register(ViPipe, 0x31EC, 0x0E); + imx327_sublvds_write_register(ViPipe, 0x3480, 0x49); /* incksel7 */ + + imx327_sublvds_default_reg_init(ViPipe); + + imx327_sublvds_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_sublvds_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_sublvds_write_register(ViPipe, 0x304b, 0x0a); + + printf("ViPipe:%d,===IMX327 1080P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void imx327_sublvds_wdr_1080p30_2to1_init(VI_PIPE ViPipe) +{ + imx327_sublvds_write_register(ViPipe, 0x3003, 0x01); /* SW RESET */ + delay_ms(4); + imx327_sublvds_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx327_sublvds_write_register(ViPipe, 0x3002, 0x00); /* XMSTA */ + imx327_sublvds_write_register(ViPipe, 0x3005, 0x01); /* ADBIT */ + imx327_sublvds_write_register(ViPipe, 0x3007, 0x00); /* VREVERS, ... */ + imx327_sublvds_write_register(ViPipe, 0x3009, 0x01); + imx327_sublvds_write_register(ViPipe, 0x300A, 0xF0); /* BLKLEVEL */ + imx327_sublvds_write_register(ViPipe, 0x300C, 0x11); /* WDMODE */ + imx327_sublvds_write_register(ViPipe, 0x3011, 0x02); + imx327_sublvds_write_register(ViPipe, 0x3014, 0x16); /* GAIN, 0x2A=>12.6dB TBD */ + imx327_sublvds_write_register(ViPipe, 0x3018, 0x65); /* VMAX[7:0] */ + imx327_sublvds_write_register(ViPipe, 0x3019, 0x04); /* VMAX[15:8] */ + imx327_sublvds_write_register(ViPipe, 0x301A, 0x00); /* VMAX[17:16]:=:0x301A[1:0] */ + imx327_sublvds_write_register(ViPipe, 0x301C, 0x98); /* HMAX[7:0], TBD */ + imx327_sublvds_write_register(ViPipe, 0x301D, 0x08); /* HMAX[15:8] */ + imx327_sublvds_write_register(ViPipe, 0x3020, 0x02); /* SHS[7:0], TBD */ + imx327_sublvds_write_register(ViPipe, 0x3021, 0x00); /* SHS[15:8] */ + imx327_sublvds_write_register(ViPipe, 0x3022, 0x00); /* SHS[19:16] */ + imx327_sublvds_write_register(ViPipe, 0x3024, 0xC9); /* SHS2[7:0], TBD */ + imx327_sublvds_write_register(ViPipe, 0x3025, 0x07); /* SHS2[15:8] */ + imx327_sublvds_write_register(ViPipe, 0x3026, 0x00); /* SHS2[19:16] */ + imx327_sublvds_write_register(ViPipe, 0x3030, 0x0B); /* RHS1[7:0], TBD */ + imx327_sublvds_write_register(ViPipe, 0x3031, 0x00); /* RHS1[15:8] */ + imx327_sublvds_write_register(ViPipe, 0x3032, 0x00); /* RHS1[19:16] */ + imx327_sublvds_write_register(ViPipe, 0x3045, 0x03); /* DOLSCDEN [0] 1: pattern1 0: pattern2 */ + imx327_sublvds_write_register(ViPipe, 0x3046, 0xE1); + imx327_sublvds_write_register(ViPipe, 0x304B, 0x0A); + imx327_sublvds_write_register(ViPipe, 0x305C, 0x18); /* INCKSEL1 */ + imx327_sublvds_write_register(ViPipe, 0x305D, 0x00); /* INCKSEL2 */ + imx327_sublvds_write_register(ViPipe, 0x305E, 0x20); /* INCKSEL3 */ + imx327_sublvds_write_register(ViPipe, 0x305F, 0x01); /* INCKSEL4 */ + imx327_sublvds_write_register(ViPipe, 0x309E, 0x4A); + imx327_sublvds_write_register(ViPipe, 0x309F, 0x4A); + imx327_sublvds_write_register(ViPipe, 0x30D2, 0x19); + imx327_sublvds_write_register(ViPipe, 0x30D7, 0x03); + imx327_sublvds_write_register(ViPipe, 0x3106, 0x11); /*DOLHBFIXEN[7] 0: pattern1 1: pattern2 */ + imx327_sublvds_write_register(ViPipe, 0x3129, 0x00); + imx327_sublvds_write_register(ViPipe, 0x313B, 0x61); + imx327_sublvds_write_register(ViPipe, 0x315E, 0x1A); + imx327_sublvds_write_register(ViPipe, 0x3164, 0x1A); + imx327_sublvds_write_register(ViPipe, 0x317C, 0x00); + imx327_sublvds_write_register(ViPipe, 0x31EC, 0x0E); + imx327_sublvds_write_register(ViPipe, 0x3415, 0x00); /* NULL0_SIZE_V, set to 00h when DOL */ + imx327_sublvds_write_register(ViPipe, 0x3480, 0x49); + + imx327_sublvds_default_reg_init(ViPipe); + + if (g_au16Imx327_sublvds_GainMode[ViPipe] == SNS_GAIN_MODE_SHARE) { + imx327_sublvds_write_register(ViPipe, 0x30F0, 0xF0); + imx327_sublvds_write_register(ViPipe, 0x3010, 0x21); + } else { + imx327_sublvds_write_register(ViPipe, 0x30F0, 0x64); + imx327_sublvds_write_register(ViPipe, 0x3010, 0x61); + } + + imx327_sublvds_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx327_sublvds_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + imx327_sublvds_write_register(ViPipe, 0x304b, 0x0a); + + printf("===Imx327_sublvds sensor 1080P30fps 12bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx335/Makefile b/middleware/v2/component/isp/sensor/cv181x/sony_imx335/Makefile new file mode 100644 index 000000000..f2aa51872 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx335/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_imx335.a +TARGET_SO = $(MW_LIB)/libsns_imx335.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $@) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $@) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx335/imx335_cmos.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx335/imx335_cmos.c new file mode 100644 index 000000000..a1f50c2b7 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx335/imx335_cmos.c @@ -0,0 +1,1255 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "imx335_cmos_ex.h" +#include "imx335_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define IMX335_ID 335 + +#define SENSOR_IMX335_4M_WIDTH 2560 +#define SENSOR_IMX335_4M_HEIGHT 1440 + +#define SENSOR_IMX335_4M_1600P_WIDTH 2560 +#define SENSOR_IMX335_4M_1600P_HEIGHT 1600 + +#define SENSOR_IMX335_5M_WIDTH 2592 +#define SENSOR_IMX335_5M_HEIGHT 1944 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastImx335[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define IMX335_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx335[dev]) +#define IMX335_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx335[dev] = pstCtx) +#define IMX335_SENSOR_RESET_CTX(dev) (g_pastImx335[dev] = CVI_NULL) + +#define IMX335_SNNSOR_IS_2L() (imx335_rx_attr.mipi_attr.lane_id[3] == -1 && imx335_rx_attr.mipi_attr.lane_id[4] == -1) +#define IMX335_SNNSOR_IS_4L() (imx335_rx_attr.mipi_attr.lane_id[3] != -1 && imx335_rx_attr.mipi_attr.lane_id[4] != -1) + +ISP_SNS_COMMBUS_U g_aunImx335_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Imx335_GainMode[VI_MAX_PIPE_NUM] = {0}; + +IMX335_STATE_S g_astImx335_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeImx335_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = { + [0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE +}; + +static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Imx335 Lines Range*****/ +#define IMX335_FULL_LINES_MAX (0xFFFFF) +#define IMX335_VMAX_5M30_LINEAR 0x1194 + +/*****Imx335 Register Address*****/ +#define IMX335_HOLD_ADDR 0x3001 + +#define IMX335_SHR0_L_ADDR 0x3058 //shutter time +#define IMX335_SHR0_M_ADDR 0x3059 +#define IMX335_SHR0_H_ADDR 0x305A //bit[19:16] +#define IMX335_SHR1_L_ADDR 0x305C +#define IMX335_SHR1_M_ADDR 0x305D +#define IMX335_SHR1_H_ADDR 0x305E + +#define IMX335_GAIN_L_ADDR 0x30E8 //gain +#define IMX335_GAIN_H_ADDR 0x30E9 //bit[10:8] +#define IMX335_GAIN_SHORT_L 0x30EA +#define IMX335_GAIN_SHORT_H 0x30EB + +#define IMX335_VMAX_L_ADDR 0x3030 //vmax +#define IMX335_VMAX_M_ADDR 0x3031 +#define IMX335_VMAX_H_ADDR 0x3032 //bit[19:16] + +#define IMX335_YOUT_L_ADDR 0x3056 //window, the number of effective pixel lines +#define IMX335_YOUT_H_ADDR 0x3057 //bit[12:8] + +#define IMX335_RHS1_L_ADDR 0x3068 +#define IMX335_RHS1_M_ADDR 0x3069 +#define IMX335_RHS1_H_ADDR 0x306A +#define IMX335_TABLE_END 0xffff + +#define IMX335_RES_IS_5M(w, h) ((w) == SENSOR_IMX335_5M_WIDTH && (h) == SENSOR_IMX335_5M_HEIGHT) +#define IMX335_RES_IS_4M(w, h) ((w) == SENSOR_IMX335_4M_WIDTH && (h) == SENSOR_IMX335_4M_HEIGHT) +#define IMX335_RES_IS_4M_1600P(w, h) ((w) == SENSOR_IMX335_4M_1600P_WIDTH && (h) == SENSOR_IMX335_4M_1600P_HEIGHT) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;//???print + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = IMX335_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + pstAeSnsDft->u32SnsStableFrame = 8; +#if 0 + pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0; + pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0; + + pstAeSnsDft->bAERouteExValid = CVI_FALSE; + pstAeSnsDft->stAERouteAttr.u32TotalNum = 0; + pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0; +#endif + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_astImx335_mode[pstSnsState->u8ImgMode].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx335_mode[pstSnsState->u8ImgMode].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 32381; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151; + + //shutter time [9 to (number of lines perframe -1)] + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 1; + pstAeSnsDft->u32MinIntTime = 9; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + + case WDR_MODE_2To1_LINE: + pstAeSnsDft->f32Fps = g_astImx335_mode[pstSnsState->u8ImgMode].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astImx335_mode[pstSnsState->u8ImgMode].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xC; + pstAeSnsDft->au8HistThresh[1] = 0x18; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstAeSnsDft->u32MinIntTime = 2; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 32381; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 128914; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + pstAeSnsDft->u32MaxISPDgainTarget = 16 << pstAeSnsDft->u32ISPDgainShift; + + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 52000; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + pstAeSnsDft->u8AeCompensation = 64; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + } else { + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR; + /* [TODO] */ +#if 0 + pstAeSnsDft->u16ManRatioEnable = CVI_TRUE; + pstAeSnsDft->au32Ratio[0] = 0x400; + pstAeSnsDft->au32Ratio[1] = 0x40; + pstAeSnsDft->au32Ratio[2] = 0x40; +#endif + } + break; + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX = IMX335_VMAX_5M30_LINEAR; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0, u32Tmp = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astImx335_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astImx335_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astImx335_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case IMX335_MODE_5M30_WDR: + case IMX335_MODE_4M30_WDR: + case IMX335_MODE_4M30_1600P_WDR: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + /* FSC shall be multiple of 8 */ + if (u32VMAX % 4) { + u32VMAX = u32VMAX - (u32VMAX % 4) + 4; + } + u32VMAX = (u32VMAX > IMX335_FULL_LINES_MAX) ? IMX335_FULL_LINES_MAX : u32VMAX; + break; + + case IMX335_MODE_5M30: + case IMX335_MODE_4M30: + case IMX335_MODE_4M30_2L: + case IMX335_MODE_4M30_1600P: + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + u32VMAX = (u32VMAX > IMX335_FULL_LINES_MAX) ? IMX335_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_M].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_H].u32Data = ((u32VMAX & 0xF0000) >> 16); + } else { + pstSnsRegsInfo->astI2cData[DOL2_VMAX_L].u32Data = (u32VMAX & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_M].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_VMAX_H].u32Data = ((u32VMAX & 0xF0000) >> 16); + } + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + /* In within FSC mode, RHS1 < 2 * (VMAX - BRL - 1), RHS1 = 8*n+2. */ + pstSnsState->u32FLStd = u32VMAX * 2; + g_astImx335_State[ViPipe].u32RHS1_MAX = 2 * (u32VMAX - g_astImx335_State[ViPipe].u32BRL - 1) - 1; + u32Tmp = ((g_astImx335_State[ViPipe].u32RHS1_MAX >> 3) << 3) + 2; + g_astImx335_State[ViPipe].u32RHS1_MAX = (u32Tmp > g_astImx335_State[ViPipe].u32RHS1_MAX) ? + (u32Tmp - 8) : u32Tmp; + } else { + pstSnsState->u32FLStd = u32VMAX; + } + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* + * DOL mode + * SHR1 : 18 <= SHR1 <= (RHS1 - 4), 4n + 2 + * RHS1 : (SHR1 + 4) <= RHS1 <= (SHR0 - 18), 8n + 2, within FSC mode, RHS1 < 2 * (VMAX - BRL - 1) + * SHR0 : (RHS1 + 18 ) <= SHR0 <= (FSC - 4), 4n + * Max Sexp = RHS1 - SHR1 = RHS1 - 18 + * Max Lexp = FSC - SHR0 = FSC - RHS1 - 18 + * Max Sexp + Lexp = FSC - 36 + * Sexp = (FSC - 36) / (1 + Ratio) + * Depending on the Sexp, we use 22 as the minimum SHR1 rather than 18. + * Thus: + * Sexp = (FSC - 40) / (1 + Ratio). + * Update: The adjustment of SHR0(and RHS1) which reflects at N+2 frame could be less than the minimum + * SHR0 at N+1. This causes the N+1 SEF abnormal. Reserve more blank lines between the end of SEF + * and the beginning of the LEF exposure. + * Thus: + * Sexp = (FSC - 280) / (1 + Ratio). + */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Value = 0; + CVI_U32 u32RHS1 = 0; + CVI_U32 u32SHR1 = 0; + CVI_U32 u32SHR0 = 0; + CVI_U32 module8 = 0, module4 = 0; + + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + CVI_U32 u32ShortIntTime = u32IntTime[0]; + CVI_U32 u32LongIntTime = u32IntTime[1]; + + if (pstSnsState->au32FL[1] < u32LongIntTime + 4) { + CVI_TRACE_SNS(CVI_DBG_ERR, "FL %d is smaller than = %d\n", + pstSnsState->au32FL[1], u32LongIntTime + 4); + return CVI_FAILURE; + } + u32SHR0 = pstSnsState->au32FL[1] - u32LongIntTime + (u32LongIntTime % 4); + + module8 = u32ShortIntTime % 8; + module4 = u32ShortIntTime % 4; + + /* SHS1 is 18 or 22. + * when tSef is multiple of 8, SHS1 = 18, RHS1 = 18 + tSEF = 8*n+2. + * otherwise, when mod(tSef, 8) = 5~7, SHS1 = 22, RHS1 = 22 + tSEF - mod(tSef, 4) = 8*n+2. + * when mod(tSef,8) = 0~3, SHS1 = 18, RHS1 = 18 + tSEF - mod(tSef, 4) = 8*n+2 + */ + if (!module8) { + u32SHR1 = 18; + u32RHS1 = u32ShortIntTime + u32SHR1; + } else { + if (module8 == module4) { + u32SHR1 = 18; + u32RHS1 = u32ShortIntTime + u32SHR1 - module4; + } else { + u32SHR1 = 22; + u32RHS1 = u32ShortIntTime + u32SHR1 - module4; + } + } + g_astImx335_State[ViPipe].u32RHS1 = u32RHS1; + g_astImx335_State[ViPipe].u32SHR1 = u32SHR1; + if (u32SHR0 < (u32RHS1 + u32SHR1)) { + u32SHR0 = u32RHS1 + u32SHR1; + } + + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32RHS1 - u32SHR1; + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = pstSnsState->au32FL[1] - u32SHR0; + /* Return the actual exposure lines*/ + u32IntTime[0] = pstSnsState->au32WDRIntTime[0]; + u32IntTime[1] = pstSnsState->au32WDRIntTime[1]; + + syslog(LOG_DEBUG, "u32ShortIntTime = %d u32SHR1 = %d\n", u32ShortIntTime, u32SHR1); + syslog(LOG_DEBUG, "ViPipe = %d RHS1 = %d\n", ViPipe, u32RHS1); + + + pstSnsRegsInfo->astI2cData[DOL2_SHR0_L].u32Data = (u32SHR0 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHR0_M].u32Data = ((u32SHR0 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHR0_H].u32Data = ((u32SHR0 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_SHR1_L].u32Data = (u32SHR1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_SHR1_M].u32Data = ((u32SHR1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_SHR1_H].u32Data = ((u32SHR1 & 0xF0000) >> 16); + + pstSnsRegsInfo->astI2cData[DOL2_RHS1_L].u32Data = (u32RHS1 & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_M].u32Data = ((u32RHS1 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[DOL2_RHS1_H].u32Data = ((u32RHS1 & 0xF0000) >> 16); + } else { + u32Value = pstSnsState->au32FL[0] - *u32IntTime; + u32Value = (u32Value > (pstSnsState->au32FL[0] - 1)) ? (pstSnsState->au32FL[0] - 1) : + ((u32Value < 9) ? 9 : u32Value); + pstSnsRegsInfo->astI2cData[LINEAR_SHR_L].u32Data = (u32Value & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_SHR_M].u32Data = ((u32Value & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHR_H].u32Data = ((u32Value & 0xF0000) >> 16); + } + + return CVI_SUCCESS; + +} + +static CVI_U32 gain_table[231] = { + 1024, 1059, 1097, 1135, 1175, 1217, 1259, 1304, 1349, 1397, 1446, 1497, 1549, 1604, 1660, 1719, 1779, 1842, + 1906, 1973, 2043, 2114, 2189, 2266, 2345, 2428, 2513, 2602, 2693, 2788, 2886, 2987, 3092, 3201, 3313, 3430, + 3550, 3675, 3804, 3938, 4076, 4219, 4368, 4521, 4680, 4845, 5015, 5191, 5374, 5562, 5758, 5960, 6170, 6387, + 6611, 6843, 7084, 7333, 7591, 7857, 8134, 8419, 8715, 9022, 9339, 9667, 10007, 10358, 10722, 11099, 11489, + 11893, 12311, 12743, 13191, 13655, 14135, 14631, 15146, 15678, 16229, 16799, 17390, 18001, 18633, 19288, + 19966, 20668, 21394, 22146, 22924, 23730, 24564, 25427, 26320, 27245, 28203, 29194, 30220, 31282, 32381, + 33519, 34697, 35917, 37179, 38485, 39838, 41238, 42687, 44187, 45740, 47347, 49011, 50734, 52517, 54362, 56272, + 58250, 60297, 62416, 64610, 66880, 69231, 71663, 74182, 76789, 79487, 82281, 85172, 88165, 91264, 94471, 97791, + 101227, 104785, 108467, 112279, 116225, 120309, 124537, 128913, 133444, 138133, 142988, 148013, 153214, 158599, + 164172, 169941, 175913, 182095, 188495, 195119, 201976, 209073, 216421, 224026, 231899, 240049, 248485, 257217, + 266256, 275613, 285298, 295324, 305703, 320110, 335567, 339078, 350994, 363329, 376097, 389314, 402995, 417157, + 431817, 446992, 462700, 478960, 495792, 513215, 531251, 549920, 569246, 589250, 609958, 631393, 653581, 676550, + 700325, 724936, 750412, 776783, 804081, 832338, 861588, 891866, 923208, 955652, 989236, 1024000, 1059985, + 1097235, 1135795, 1175709, 1217026, 1259795, 1304067, 1349894, 1397333, 1446438, 1497269, 1549886, 1604353, + 1660733, 1719095, 1779508, 1842043, 1906777, 1913785, 2043148, 2114949, 2189273, 2266208, 2345848, 2428286, + 2513621, 2601956, 2662563, 2788046, 2886024 +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + if (*pu32AgainLin >= gain_table[230]) { + *pu32AgainLin = gain_table[230]; + *pu32AgainDb = 230; + return CVI_SUCCESS; + } + + for (i = 1; i < 231; i++) { + if (*pu32AgainLin < gain_table[i]) { + *pu32AgainLin = gain_table[i - 1]; + *pu32AgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + int i; + + (void) ViPipe; + + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + if (*pu32DgainLin >= gain_table[140]) { + *pu32DgainLin = gain_table[140]; + *pu32DgainDb = 140; + return CVI_SUCCESS; + } + + for (i = 1; i < 141; i++) { + if (*pu32DgainLin < gain_table[i]) { + *pu32DgainLin = gain_table[i - 1]; + *pu32DgainDb = i - 1; + break; + } + } + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u16Mode = g_au16Imx335_GainMode[ViPipe]; + CVI_U32 u32Tmp; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + /* linear mode */ + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_L].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_H].u32Data = ((u32Tmp & 0x700) >> 8); + + } else { + /* DOL mode */ + if (u16Mode == SNS_GAIN_MODE_WDR_2F) { + /* don't support gain conversion in this mode. */ + u32Again = pu32Again[1]; + u32Dgain = pu32Dgain[1]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0x7FF) { + u32Tmp = 0x7FF; + } + + pstSnsRegsInfo->astI2cData[DOL2_GAIN_L].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_GAIN_H].u32Data = ((u32Tmp & 0x700) >> 8); + + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0x7FF) { + u32Tmp = 0x7FF; + } + pstSnsRegsInfo->astI2cData[DOL2_GAIN_SHORT_L].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_GAIN_SHORT_L].u32Data = ((u32Tmp & 0x700) >> 8); + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + u32Again = pu32Again[0]; + u32Dgain = pu32Dgain[0]; + + u32Tmp = u32Again + u32Dgain; + if (u32Tmp > 0x7FF) { + u32Tmp = 0x7FF; + } + + pstSnsRegsInfo->astI2cData[DOL2_GAIN_L].u32Data = (u32Tmp & 0xFF); + pstSnsRegsInfo->astI2cData[DOL2_GAIN_H].u32Data = ((u32Tmp & 0x700) >> 8); + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio, + CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime) +{ + CVI_U32 u32IntTimeMaxTmp = 0, u32IntTimeMaxTmp0 = 0; + CVI_U32 u32RatioTmp = 0x40; + CVI_U32 u32ShortTimeMinLimit = 4; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + if (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) { + if (genFSWDRMode[ViPipe] == ISP_FSWDR_LONG_FRAME_MODE) { + u32IntTimeMaxTmp = pstSnsState->au32FL[0] - 280; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + return CVI_SUCCESS; + } + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 280 - pstSnsState->au32WDRIntTime[0]) * 0x40) / + DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 280) * 0x40) / DIV_0_TO_1(au32Ratio[0] + 0x40); + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > u32IntTimeMaxTmp0) ? u32IntTimeMaxTmp0 : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astImx335_State[ViPipe].u32RHS1_MAX - 22)) ? + (g_astImx335_State[ViPipe].u32RHS1_MAX - 22) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? 1 : u32IntTimeMaxTmp; + + } + + if (u32IntTimeMaxTmp >= u32ShortTimeMinLimit) { + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * au32Ratio[0] >> 6; + au32IntTimeMax[2] = au32IntTimeMax[1] * au32Ratio[1] >> 6; + au32IntTimeMax[3] = au32IntTimeMax[2] * au32Ratio[2] >> 6; + au32IntTimeMin[0] = u32ShortTimeMinLimit; + au32IntTimeMin[1] = au32IntTimeMin[0] * au32Ratio[0] >> 6; + au32IntTimeMin[2] = au32IntTimeMin[1] * au32Ratio[1] >> 6; + au32IntTimeMin[3] = au32IntTimeMin[2] * au32Ratio[2] >> 6; + } else { + } + } else { + if (u16ManRatioEnable) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Manaul ExpRatio out of range!\n"); + return CVI_FAILURE; + } + u32IntTimeMaxTmp = u32ShortTimeMinLimit; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + u32RatioTmp = 0xFFF; + au32IntTimeMax[0] = u32IntTimeMaxTmp; + au32IntTimeMax[1] = au32IntTimeMax[0] * u32RatioTmp >> 6; + } else { + } + au32IntTimeMin[0] = au32IntTimeMax[0]; + au32IntTimeMin[1] = au32IntTimeMax[1]; + au32IntTimeMin[2] = au32IntTimeMax[2]; + au32IntTimeMin[3] = au32IntTimeMax[3]; + } + + return CVI_SUCCESS; +} + +/* Only used in LINE_WDR mode */ +static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr) +{ + CMOS_CHECK_POINTER(pstAeFSWDRAttr); + + genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode; + gu32MaxTimeGetCnt[ViPipe] = 0; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + //pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstAwbSnsDft); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + (void) ViPipe; + + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + (void) ViPipe; + + CMOS_CHECK_POINTER(pstBlc); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const IMX335_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astImx335_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == IMX335_MODE_5M30_WDR) + pstSnsState->u8ImgMode = IMX335_MODE_5M30; + else if (pstSnsState->u8ImgMode == IMX335_MODE_4M30_WDR) { + if (IMX335_SNNSOR_IS_4L()) + pstSnsState->u8ImgMode = IMX335_MODE_4M30; + else if (IMX335_SNNSOR_IS_2L()) + pstSnsState->u8ImgMode = IMX335_MODE_4M30_2L; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "lane_id is invalid\n"); + return CVI_FAILURE; + } + } else if (pstSnsState->u8ImgMode == IMX335_MODE_4M30_1600P_WDR) + pstSnsState->u8ImgMode = IMX335_MODE_4M30_1600P; + else { + } + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx335_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == IMX335_MODE_5M30) + pstSnsState->u8ImgMode = IMX335_MODE_5M30_WDR; + else if (pstSnsState->u8ImgMode == IMX335_MODE_4M30) + pstSnsState->u8ImgMode = IMX335_MODE_4M30_WDR; + else if (pstSnsState->u8ImgMode == IMX335_MODE_4M30_1600P) + pstSnsState->u8ImgMode = IMX335_MODE_4M30_1600P_WDR; + else { + } + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astImx335_mode[pstSnsState->u8ImgMode].u32VtsDef * 2; + g_astImx335_State[ViPipe].u32BRL = g_astImx335_mode[pstSnsState->u8ImgMode].u16BRL; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unknown mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunImx335_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 2; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (WDR_MODE_2To1_LINE == pstSnsState->enWDRMode) ? + DOL2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = imx335_i2c_addr; + pstI2c_data[i].u32AddrByteNum = imx335_addr_byte; + pstI2c_data[i].u32DataByteNum = imx335_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[DOL2_SHR0_L].u32RegAddr = IMX335_SHR0_L_ADDR; + pstI2c_data[DOL2_SHR0_M].u32RegAddr = IMX335_SHR0_M_ADDR; + pstI2c_data[DOL2_SHR0_H].u32RegAddr = IMX335_SHR0_H_ADDR; + + pstI2c_data[DOL2_GAIN_L].u32RegAddr = IMX335_GAIN_L_ADDR; + pstI2c_data[DOL2_GAIN_L].u8DelayFrmNum = 0; + pstI2c_data[DOL2_GAIN_H].u32RegAddr = IMX335_GAIN_H_ADDR; + pstI2c_data[DOL2_GAIN_H].u8DelayFrmNum = 0; + + pstI2c_data[DOL2_GAIN_SHORT_L].u32RegAddr = IMX335_GAIN_SHORT_L; + pstI2c_data[DOL2_GAIN_SHORT_L].u8DelayFrmNum = 0; + pstI2c_data[DOL2_GAIN_SHORT_H].u32RegAddr = IMX335_GAIN_SHORT_H; + pstI2c_data[DOL2_GAIN_SHORT_H].u8DelayFrmNum = 0; + + pstI2c_data[DOL2_RHS1_L].u32RegAddr = IMX335_RHS1_L_ADDR; + pstI2c_data[DOL2_RHS1_L].u8DelayFrmNum = 0; + pstI2c_data[DOL2_RHS1_M].u32RegAddr = IMX335_RHS1_M_ADDR; + pstI2c_data[DOL2_RHS1_M].u8DelayFrmNum = 0; + pstI2c_data[DOL2_RHS1_H].u32RegAddr = IMX335_RHS1_H_ADDR; + pstI2c_data[DOL2_RHS1_H].u8DelayFrmNum = 0; + + pstI2c_data[DOL2_SHR1_L].u32RegAddr = IMX335_SHR1_L_ADDR; + pstI2c_data[DOL2_SHR1_M].u32RegAddr = IMX335_SHR1_M_ADDR; + pstI2c_data[DOL2_SHR1_H].u32RegAddr = IMX335_SHR1_H_ADDR; + + pstI2c_data[DOL2_VMAX_L].u32RegAddr = IMX335_VMAX_L_ADDR; + pstI2c_data[DOL2_VMAX_L].u8DelayFrmNum = 0; + pstI2c_data[DOL2_VMAX_M].u32RegAddr = IMX335_VMAX_M_ADDR; + pstI2c_data[DOL2_VMAX_M].u8DelayFrmNum = 0; + pstI2c_data[DOL2_VMAX_H].u32RegAddr = IMX335_VMAX_H_ADDR; + pstI2c_data[DOL2_VMAX_H].u8DelayFrmNum = 0; + + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + default: + pstI2c_data[LINEAR_SHR_L].u32RegAddr = IMX335_SHR0_L_ADDR; + pstI2c_data[LINEAR_SHR_M].u32RegAddr = IMX335_SHR0_M_ADDR; + pstI2c_data[LINEAR_SHR_H].u32RegAddr = IMX335_SHR0_H_ADDR; + + pstI2c_data[LINEAR_GAIN_L].u32RegAddr = IMX335_GAIN_L_ADDR; + pstI2c_data[LINEAR_GAIN_H].u32RegAddr = IMX335_GAIN_H_ADDR; + + pstI2c_data[LINEAR_VMAX_L].u32RegAddr = IMX335_VMAX_L_ADDR; + pstI2c_data[LINEAR_VMAX_M].u32RegAddr = IMX335_VMAX_M_ADDR; + pstI2c_data[LINEAR_VMAX_H].u32RegAddr = IMX335_VMAX_H_ADDR; + pstCfg0->ispCfg.u8DelayFrmNum = 0; + break; + } + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + /* check update isp crop or not */ + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (IMX335_RES_IS_5M(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = IMX335_MODE_5M30; + else if (IMX335_RES_IS_4M(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + if (IMX335_SNNSOR_IS_4L()) + u8SensorImageMode = IMX335_MODE_4M30; //4 lane + else if (IMX335_SNNSOR_IS_2L()) + u8SensorImageMode = IMX335_MODE_4M30_2L; //2 lane + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "lane_id is invalid\n"); + return CVI_FAILURE; + } + } else if (IMX335_RES_IS_4M_1600P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = IMX335_MODE_4M30_1600P; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (IMX335_RES_IS_5M(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = IMX335_MODE_5M30_WDR; + else if (IMX335_RES_IS_4M(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = IMX335_MODE_4M30_WDR; + else if (IMX335_RES_IS_4M_1600P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = IMX335_MODE_4M30_1600P_WDR; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeImx335_MirrorFip[ViPipe] != eSnsMirrorFlip) { + imx335_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeImx335_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = IMX335_MODE_4M30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astImx335_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astImx335_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astImx335_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + IMX335_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &imx335_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astImx335_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astImx335_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + + if (pstSnsState->u8ImgMode == IMX335_MODE_4M30_2L) + pstRxAttr->mipi_attr.raw_data_type = RAW_DATA_10BIT; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstRxAttr->mac_clk = RX_MAC_CLK_600M; + pstRxAttr->mipi_attr.raw_data_type = RAW_DATA_10BIT; + } else { + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &imx335_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= 2) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = imx335_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = imx335_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 imx335_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunImx335_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX335_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + IMX335_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + IMX335_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + IMX335_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = IMX335_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, IMX335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, IMX335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, IMX335_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Imx335_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return imx335_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsImx335_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = imx335_standby, + .pfnRestart = imx335_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = imx335_write_register, + .pfnReadReg = imx335_read_register, + .pfnSetBusInfo = imx335_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = CVI_NULL, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; + diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx335/imx335_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx335/imx335_cmos_ex.h new file mode 100644 index 000000000..d0fdd46f2 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx335/imx335_cmos_ex.h @@ -0,0 +1,115 @@ +#ifndef __IMX335_CMOS_EX_H_ +#define __IMX335_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +enum imx335_linear_regs_e { + LINEAR_SHR_L = 0, + LINEAR_SHR_M, + LINEAR_SHR_H, + LINEAR_GAIN_H, + LINEAR_GAIN_L, + LINEAR_VMAX_L, + LINEAR_VMAX_M, + LINEAR_VMAX_H, + LINEAR_REGS_NUM +}; + +enum imx335_dol2_regs_e { + DOL2_SHR0_L = 0, + DOL2_SHR0_M, + DOL2_SHR0_H, + DOL2_GAIN_L, + DOL2_GAIN_H, + DOL2_GAIN_SHORT_L, + DOL2_GAIN_SHORT_H, + DOL2_RHS1_L, + DOL2_RHS1_M, + DOL2_RHS1_H, + DOL2_SHR1_L, + DOL2_SHR1_M, + DOL2_SHR1_H, + DOL2_VMAX_L, + DOL2_VMAX_M, + DOL2_VMAX_H, + DOL2_REGS_NUM +}; + +typedef enum _IMX335_MODE_E { + IMX335_MODE_5M30 = 0, + IMX335_MODE_4M30, + IMX335_MODE_4M30_2L, + IMX335_MODE_4M30_1600P, + IMX335_MODE_LINEAR_NUM, + IMX335_MODE_5M30_WDR = IMX335_MODE_LINEAR_NUM, + IMX335_MODE_4M30_WDR, + IMX335_MODE_4M30_1600P_WDR, + IMX335_MODE_NUM +} IMX335_MODE_E; + +typedef struct _IMX335_STATE_S { + CVI_U8 u8Hcg; + CVI_U32 u32BRL; + CVI_U32 u32SHR1; + CVI_U32 u32RHS1; + CVI_U32 u32RHS1_MAX; +} IMX335_STATE_S; + +typedef struct _IMX335_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + CVI_U16 u16RHS1; + CVI_U16 u16BRL; + CVI_U16 u16OpbSize; + CVI_U16 u16MarginVtop; + CVI_U16 u16MarginVbot; + char name[64]; +} IMX335_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastImx335[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunImx335_BusInfo[]; +extern CVI_U16 g_au16Imx335_GainMode[]; +extern const CVI_U8 imx335_i2c_addr; +extern const CVI_U32 imx335_addr_byte; +extern const CVI_U32 imx335_data_byte; +extern void imx335_init(VI_PIPE ViPipe); +extern void imx335_exit(VI_PIPE ViPipe); +extern void imx335_standby(VI_PIPE ViPipe); +extern void imx335_restart(VI_PIPE ViPipe); +extern int imx335_write_register(VI_PIPE ViPipe, int addr, int data); +extern int imx335_read_register(VI_PIPE ViPipe, int addr); +extern void imx335_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int imx335_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + +#endif /* __IMX335_CMOS_EX_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx335/imx335_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/sony_imx335/imx335_cmos_param.h new file mode 100644 index 000000000..791a6698c --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx335/imx335_cmos_param.h @@ -0,0 +1,577 @@ +#ifndef __IMX335_CMOS_PARAM_H_ +#define __IMX335_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx335_cmos_ex.h" + +static const IMX335_MODE_S g_astImx335_mode[IMX335_MODE_NUM] = { + [IMX335_MODE_4M30_1600P] = { + .name = "4M30_1600P", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2592, + .u32Height = 1620, + }, + .stWndRect = { + .s32X = 16, + .s32Y = 10, + .u32Width = 2560, + .u32Height = 1600, + }, + .stMaxSize = { + .u32Width = 2592, + .u32Height = 1620, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 0x1194 * 30 / 0xFFFFF */ + .u32HtsDef = 0x226, //hmax + .u32VtsDef = 0x1194, //vmax + .stExp[0] = { + .u16Min = 9, + .u16Max = 0x1194 - 1, + .u16Def = 9, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 32381, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 128914, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [IMX335_MODE_4M30] = { + .name = "4M30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2592, + .u32Height = 1460, + }, + .stWndRect = { + .s32X = 16, + .s32Y = 10, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2592, + .u32Height = 1460, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 0x1194 * 30 / 0xFFFFF */ + .u32HtsDef = 0x226, //hmax + .u32VtsDef = 0x1194, //vmax + .stExp[0] = { + .u16Min = 9, + .u16Max = 0x1194 - 1, + .u16Def = 9, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 32381, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 128914, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [IMX335_MODE_4M30_2L] = { + .name = "4M30_2L", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2568, + .u32Height = 1444, + }, + .stWndRect = { + .s32X = 4, + .s32Y = 2, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2568, + .u32Height = 1444, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 0x1194 * 30 / 0xFFFFF */ + .u32HtsDef = 0xA08, //hmax + .u32VtsDef = 0x1194, //vmax + .stExp[0] = { + .u16Min = 9, + .u16Max = 0x1194 - 1, + .u16Def = 9, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 32381, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 128914, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [IMX335_MODE_5M30] = { + .name = "5M30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2616, + .u32Height = 1964, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 12, + .u32Width = 2592, + .u32Height = 1944, + }, + .stMaxSize = { + .u32Width = 2616, + .u32Height = 1964, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 0x1194 * 30 / 0xFFFFF */ + .u32HtsDef = 0x226, //hmax + .u32VtsDef = 0x1194, //vmax + .stExp[0] = { + .u16Min = 9, + .u16Max = 0x1194 - 1, + .u16Def = 9, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 32381, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 128914, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [IMX335_MODE_5M30_WDR] = { + .name = "5M30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 2616, + .u32Height = 1964, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 12, + .u32Width = 2592, + .u32Height = 1944, + }, + .stMaxSize = { + .u32Width = 2616, + .u32Height = 1964, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 2616, + .u32Height = 1964, + }, + .stWndRect = { + .s32X = 12, + .s32Y = 12, + .u32Width = 2592, + .u32Height = 1944, + }, + .stMaxSize = { + .u32Width = 2616, + .u32Height = 1964, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 0x1194 * 30 / 0xFFFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 0x1194, + .stExp[0] = { + .u16Min = 8, + .u16Max = 481, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 128, + .u16Max = 7696, + .u16Def = 128, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 62416, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 62416, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 38485, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 38485, + .u32Def = 1024, + .u32Step = 1, + }, + .u16BRL = 3968, + }, + [IMX335_MODE_4M30_WDR] = { + .name = "4M30wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 2616, + .u32Height = 1460, + }, + .stWndRect = { + .s32X = 28, + .s32Y = 10, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2616, + .u32Height = 1460, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 2616, + .u32Height = 1460, + }, + .stWndRect = { + .s32X = 28, + .s32Y = 10, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2616, + .u32Height = 1460, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 0x1194 * 30 / 0xFFFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 0x1194, + .stExp[0] = { + .u16Min = 8, + .u16Max = 481, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 128, + .u16Max = 7696, + .u16Def = 128, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 62416, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 62416, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 38485, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 38485, + .u32Def = 1024, + .u32Step = 1, + }, + .u16BRL = (1440 + 20) * 2, + }, + [IMX335_MODE_4M30_1600P_WDR] = { + .name = "4M30_1600P_wdr", + /* sef */ + .astImg[0] = { + .stSnsSize = { + .u32Width = 2592, + .u32Height = 1620, + }, + .stWndRect = { + .s32X = 16, + .s32Y = 10, + .u32Width = 2560, + .u32Height = 1600, + }, + .stMaxSize = { + .u32Width = 2592, + .u32Height = 1620, + }, + }, + /* lef */ + .astImg[1] = { + .stSnsSize = { + .u32Width = 2592, + .u32Height = 1620, + }, + .stWndRect = { + .s32X = 16, + .s32Y = 10, + .u32Width = 2560, + .u32Height = 1600, + }, + .stMaxSize = { + .u32Width = 2592, + .u32Height = 1620, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.13, /* 0x1194 * 30 / 0xFFFFF */ + .u32HtsDef = 0x0898, + .u32VtsDef = 0x1194, + .stExp[0] = { + .u16Min = 8, + .u16Max = 481, + .u16Def = 8, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 128, + .u16Max = 7696, + .u16Def = 128, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 62416, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 62416, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 38485, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 38485, + .u32Def = 1024, + .u32Step = 1, + }, + .u16BRL = (1440 + 20) * 2, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.02535128779709339142, 1.61768496036529541016}, //B: slope, intercept + {0.00795035623013973236, 15.21613883972167968750}, //Gb: slope, intercept + {0.01330664381384849548, 10.40423774719238281250}, //Gr: slope, intercept + {0.02679967880249023438, 1.82649695873260498047}, //R: slope, intercept + }, + { //iso 200 + {0.02753821015357971191, 6.47844934463500976563}, //B: slope, intercept + {0.00463790073990821838, 25.24199485778808593750}, //Gb: slope, intercept + {0.00451094703748822212, 25.23709869384765625000}, //Gr: slope, intercept + {0.02894908934831619263, 6.20713567733764648438}, //R: slope, intercept + }, + { //iso 400 + {0.03178063780069351196, 12.60536384582519531250}, //B: slope, intercept + {0.00517552718520164490, 35.03299713134765625000}, //Gb: slope, intercept + {0.00502182589843869209, 35.23723602294921875000}, //Gr: slope, intercept + {0.03328817337751388550, 12.19208049774169921875}, //R: slope, intercept + }, + { //iso 800 + {0.03747911751270294189, 21.80648422241210937500}, //B: slope, intercept + {0.00625439779832959175, 49.06682205200195312500}, //Gb: slope, intercept + {0.00620671268552541733, 49.14254379272460937500}, //Gr: slope, intercept + {0.03955777361989021301, 20.63272857666015625000}, //R: slope, intercept + }, + { //iso 1600 + {0.04763090237975120544, 34.16785049438476562500}, //B: slope, intercept + {0.00715198600664734840, 70.35113525390625000000}, //Gb: slope, intercept + {0.00717207882553339005, 70.42241668701171875000}, //Gr: slope, intercept + {0.05030791088938713074, 32.31000518798828125000}, //R: slope, intercept + }, + { //iso 3200 + {0.06291828304529190063, 51.79273986816406250000}, //B: slope, intercept + {0.00942948460578918457, 99.58425903320312500000}, //Gb: slope, intercept + {0.00938474666327238083, 99.87895202636718750000}, //Gr: slope, intercept + {0.06596329063177108765, 49.59438705444335937500}, //R: slope, intercept + }, + { //iso 6400 + {0.08704897761344909668, 76.54403686523437500000}, //B: slope, intercept + {0.02136226370930671692, 135.76541137695312500000}, //Gb: slope, intercept + {0.02061788551509380341, 136.24209594726562500000}, //Gr: slope, intercept + {0.09058564901351928711, 73.56949615478515625000}, //R: slope, intercept + }, + { //iso 12800 + {0.11864978075027465820, 116.15978240966796875000}, //B: slope, intercept + {0.03285352513194084167, 193.26387023925781250000}, //Gb: slope, intercept + {0.03131035342812538147, 194.77830505371093750000}, //Gr: slope, intercept + {0.12536112964153289795, 110.30144500732421875000}, //R: slope, intercept + }, + { //iso 25600 + {0.16936406493186950684, 172.24114990234375000000}, //B: slope, intercept + {0.05775514617562294006, 267.55535888671875000000}, //Gb: slope, intercept + {0.05725358799099922180, 268.19198608398437500000}, //Gr: slope, intercept + {0.17778857052326202393, 166.38156127929687500000}, //R: slope, intercept + }, + { //iso 51200 + {0.23955665528774261475, 255.52276611328125000000}, //B: slope, intercept + {0.09076436609029769897, 378.79702758789062500000}, //Gb: slope, intercept + {0.08728235960006713867, 384.05020141601562500000}, //Gr: slope, intercept + {0.25822344422340393066, 249.06506347656250000000}, //R: slope, intercept + }, + { //iso 102400 + {0.36010745167732238770, 362.82952880859375000000}, //B: slope, intercept + {0.15752448141574859619, 513.11077880859375000000}, //Gb: slope, intercept + {0.15595595538616180420, 518.77105712890625000000}, //Gr: slope, intercept + {0.38190475106239318848, 360.52606201171875000000}, //R: slope, intercept + }, + { //iso 204800 + {0.44082218408584594727, 536.35937500000000000000}, //B: slope, intercept + {0.22994761168956756592, 701.87817382812500000000}, //Gb: slope, intercept + {0.22570468485355377197, 707.03558349609375000000}, //Gr: slope, intercept + {0.46145606040954589844, 543.70227050781250000000}, //R: slope, intercept + }, + { //iso 409600 + {0.24378113448619842529, 865.24688720703125000000}, //B: slope, intercept + {0.06541594862937927246, 1050.97998046875000000000}, //Gb: slope, intercept + {0.06018084660172462463, 1068.13745117187500000000}, //Gr: slope, intercept + {0.25154441595077514648, 904.18511962890625000000}, //R: slope, intercept + }, + { //iso 819200 + {0.24305926263332366943, 867.16644287109375000000}, //B: slope, intercept + {0.06559922546148300171, 1050.18383789062500000000}, //Gb: slope, intercept + {0.06018084660172462463, 1068.13745117187500000000}, //Gr: slope, intercept + {0.25154441595077514648, 904.18511962890625000000}, //R: slope, intercept + }, + { //iso 1638400 + {0.24378113448619842529, 865.24688720703125000000}, //B: slope, intercept + {0.06582942605018615723, 1048.96228027343750000000}, //Gb: slope, intercept + {0.06089610978960990906, 1064.75537109375000000000}, //Gr: slope, intercept + {0.25244551897048950195, 901.38049316406250000000}, //R: slope, intercept + }, + { //iso 3276800 + {0.24428291618824005127, 863.30468750000000000000}, //B: slope, intercept + {0.06582942605018615723, 1048.96228027343750000000}, //Gb: slope, intercept + {0.06080029532313346863, 1065.15185546875000000000}, //Gr: slope, intercept + {0.25226309895515441895, 901.83532714843750000000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {200, 200, 200, 200, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1076, 1076, 1076, 1076 +#endif + }, + .stAuto = { + {199, 201, 201, 200, 202, 202, 203, 206, /*8*/219, 270, 409, 679, 1023, 1023, 1023, 1023}, + {200, 201, 201, 200, 201, 199, 199, 197, /*8*/201, 242, 357, 588, 974, 974, 982, 981}, + {200, 201, 201, 200, 201, 200, 200, 199, /*8*/205, 248, 370, 609, 1007, 1009, 1012, 1012}, + {199, 201, 201, 200, 202, 202, 203, 207, /*8*/219, 270, 408, 674, 1023, 1023, 1023, 1023}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1076, 1077, 1077, 1077, 1077, 1077, 1077, 1078, + /*8*/1082, 1096, 1138, 1228, 1365, 1365, 1365, 1365}, + {1077, 1077, 1077, 1077, 1077, 1076, 1076, 1076, + /*8*/1077, 1088, 1122, 1196, 1344, 1344, 1347, 1347}, + {1077, 1077, 1077, 1077, 1077, 1077, 1077, 1076, + /*8*/1078, 1090, 1126, 1203, 1358, 1359, 1360, 1360}, + {1076, 1077, 1077, 1077, 1077, 1077, 1077, 1079, + /*8*/1082, 1096, 1137, 1226, 1365, 1365, 1365, 1365}, +#endif + }, + }, +}; + +struct combo_dev_attr_s imx335_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_400M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {2, 0, 1, 3, 4}, + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_37P125M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + +#endif /* __IMX335_CMOS_PARAM_H_ */ diff --git a/middleware/v2/component/isp/sensor/cv181x/sony_imx335/imx335_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/sony_imx335/imx335_sensor_ctl.c new file mode 100644 index 000000000..4c69dd20f --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/sony_imx335/imx335_sensor_ctl.c @@ -0,0 +1,1000 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "imx335_cmos_ex.h" +static void imx335_wdr_5M30_2to1_init(VI_PIPE ViPipe); +static void imx335_wdr_4M30_2to1_init(VI_PIPE ViPipe); +static void imx335_wdr_4M30_1600p_2to1_init(VI_PIPE ViPipe); + +static void imx335_linear_5M30_init(VI_PIPE ViPipe); +static void imx335_linear_4M30_init(VI_PIPE ViPipe); +static void imx335_linear_4M30_2l_init(VI_PIPE ViPipe); +static void imx335_linear_4M30_1600p_init(VI_PIPE ViPipe); + +const CVI_U8 imx335_i2c_addr = 0x1A; + +const CVI_U32 imx335_addr_byte = 2; +const CVI_U32 imx335_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int imx335_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunImx335_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, imx335_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int imx335_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int imx335_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (imx335_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, imx335_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, imx335_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (imx335_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + + +int imx335_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (imx335_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (imx335_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, imx335_addr_byte + imx335_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void imx335_standby(VI_PIPE ViPipe) +{ + imx335_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx335_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ +} + +void imx335_restart(VI_PIPE ViPipe) +{ + imx335_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx335_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + //imx335_write_register(ViPipe, 0x304b, 0x0a); +} + +void imx335_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastImx335[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + imx335_write_register(ViPipe, + g_pastImx335[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastImx335[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void imx335_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 u8Filp = 0; + CVI_U8 u8Mirror = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + u8Mirror = 1; + break; + case ISP_SNS_FLIP: + u8Filp = 1; + break; + case ISP_SNS_MIRROR_FLIP: + u8Filp = 1; + u8Mirror = 1; + break; + default: + return; + } + + imx335_write_register(ViPipe, 0x304e, u8Mirror); + imx335_write_register(ViPipe, 0x304f, u8Filp); + if (u8Filp != 0) { + imx335_write_register(ViPipe, 0x3074, 0x10); + imx335_write_register(ViPipe, 0x3075, 0x10); + imx335_write_register(ViPipe, 0x3081, 0xfe); + imx335_write_register(ViPipe, 0x3083, 0xfe); + imx335_write_register(ViPipe, 0x30b6, 0xfa); + imx335_write_register(ViPipe, 0x30b7, 0x01); + imx335_write_register(ViPipe, 0x3116, 0x02); + imx335_write_register(ViPipe, 0x3117, 0x00); + } else { + imx335_write_register(ViPipe, 0x3074, 0xb0); + imx335_write_register(ViPipe, 0x3075, 0x00); + imx335_write_register(ViPipe, 0x3081, 0x02); + imx335_write_register(ViPipe, 0x3083, 0x02); + imx335_write_register(ViPipe, 0x30b6, 0x00); + imx335_write_register(ViPipe, 0x30b7, 0x00); + imx335_write_register(ViPipe, 0x3116, 0x08); + imx335_write_register(ViPipe, 0x3117, 0x00); + } +} + +int imx335_probe(VI_PIPE ViPipe) +{ + int nVal; + + usleep(100); + if (imx335_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = imx335_read_register(ViPipe, 0x3000); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + return CVI_SUCCESS; +} + +void imx335_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastImx335[ViPipe]->enWDRMode; + u8ImgMode = g_pastImx335[ViPipe]->u8ImgMode; + + imx335_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == IMX335_MODE_5M30_WDR) + imx335_wdr_5M30_2to1_init(ViPipe); + else if (u8ImgMode == IMX335_MODE_4M30_WDR) + imx335_wdr_4M30_2to1_init(ViPipe); + else if (u8ImgMode == IMX335_MODE_4M30_1600P_WDR) + imx335_wdr_4M30_1600p_2to1_init(ViPipe); + else{ + } + } else { + if (u8ImgMode == IMX335_MODE_5M30) + imx335_linear_5M30_init(ViPipe); + else if (u8ImgMode == IMX335_MODE_4M30) + imx335_linear_4M30_init(ViPipe); + else if (u8ImgMode == IMX335_MODE_4M30_2L) + imx335_linear_4M30_2l_init(ViPipe); + else if (u8ImgMode == IMX335_MODE_4M30_1600P) + imx335_linear_4M30_1600p_init(ViPipe); + else { + } + } + g_pastImx335[ViPipe]->bInit = CVI_TRUE; +} + +void imx335_exit(VI_PIPE ViPipe) +{ + imx335_i2c_exit(ViPipe); +} +static void imx335_linear_4M30_init(VI_PIPE ViPipe) +{ + delay_ms(4); + imx335_write_register(ViPipe, 0x3000, 0x01); // STANDBY + imx335_write_register(ViPipe, 0x3002, 0x01); // XTMSTA + + imx335_write_register(ViPipe, 0x300C, 0x5B); + imx335_write_register(ViPipe, 0x300D, 0x40); + imx335_write_register(ViPipe, 0x3018, 0x04);// WINMODE[3:0] croping mode + imx335_write_register(ViPipe, 0x302C, 0x3C); + imx335_write_register(ViPipe, 0x302E, 0x20); + imx335_write_register(ViPipe, 0x3056, 0xB4);//Y_OUT_SIZE[12:0] + imx335_write_register(ViPipe, 0x3057, 0x05); + imx335_write_register(ViPipe, 0x3074, 0xA8); + imx335_write_register(ViPipe, 0x3075, 0x02); + imx335_write_register(ViPipe, 0x3076, 0x68); + imx335_write_register(ViPipe, 0x3077, 0x0B); + imx335_write_register(ViPipe, 0x30C6, 0x12); + imx335_write_register(ViPipe, 0x30CE, 0x64); + imx335_write_register(ViPipe, 0x30D8, 0xE0); + imx335_write_register(ViPipe, 0x30D9, 0x0E); + imx335_write_register(ViPipe, 0x314C, 0xC0); + imx335_write_register(ViPipe, 0x315A, 0x06); + imx335_write_register(ViPipe, 0x316A, 0x7E); + imx335_write_register(ViPipe, 0x319E, 0x02); + imx335_write_register(ViPipe, 0x31A1, 0x00); + imx335_write_register(ViPipe, 0x3288, 0x21); + imx335_write_register(ViPipe, 0x328A, 0x02); + imx335_write_register(ViPipe, 0x3414, 0x05); + imx335_write_register(ViPipe, 0x3416, 0x18); + imx335_write_register(ViPipe, 0x3648, 0x01); + imx335_write_register(ViPipe, 0x364A, 0x04); + imx335_write_register(ViPipe, 0x364C, 0x04); + imx335_write_register(ViPipe, 0x3678, 0x01); + imx335_write_register(ViPipe, 0x367C, 0x31); + imx335_write_register(ViPipe, 0x367E, 0x31); + imx335_write_register(ViPipe, 0x3706, 0x10); + imx335_write_register(ViPipe, 0x3708, 0x03); + imx335_write_register(ViPipe, 0x3714, 0x02); + imx335_write_register(ViPipe, 0x3715, 0x02); + imx335_write_register(ViPipe, 0x3716, 0x01); + imx335_write_register(ViPipe, 0x3717, 0x03); + imx335_write_register(ViPipe, 0x371C, 0x3D); + imx335_write_register(ViPipe, 0x371D, 0x3F); + imx335_write_register(ViPipe, 0x372C, 0x00); + imx335_write_register(ViPipe, 0x372D, 0x00); + imx335_write_register(ViPipe, 0x372E, 0x46); + imx335_write_register(ViPipe, 0x372F, 0x00); + imx335_write_register(ViPipe, 0x3730, 0x89); + imx335_write_register(ViPipe, 0x3731, 0x00); + imx335_write_register(ViPipe, 0x3732, 0x08); + imx335_write_register(ViPipe, 0x3733, 0x01); + imx335_write_register(ViPipe, 0x3734, 0xFE); + imx335_write_register(ViPipe, 0x3735, 0x05); + imx335_write_register(ViPipe, 0x3740, 0x02); + imx335_write_register(ViPipe, 0x375D, 0x00); + imx335_write_register(ViPipe, 0x375E, 0x00); + imx335_write_register(ViPipe, 0x375F, 0x11); + imx335_write_register(ViPipe, 0x3760, 0x01); + imx335_write_register(ViPipe, 0x3768, 0x1B); + imx335_write_register(ViPipe, 0x3769, 0x1B); + imx335_write_register(ViPipe, 0x376A, 0x1B); + imx335_write_register(ViPipe, 0x376B, 0x1B); + imx335_write_register(ViPipe, 0x376C, 0x1A); + imx335_write_register(ViPipe, 0x376D, 0x17); + imx335_write_register(ViPipe, 0x376E, 0x0F); + imx335_write_register(ViPipe, 0x3776, 0x00); + imx335_write_register(ViPipe, 0x3777, 0x00); + imx335_write_register(ViPipe, 0x3778, 0x46); + imx335_write_register(ViPipe, 0x3779, 0x00); + imx335_write_register(ViPipe, 0x377A, 0x89); + imx335_write_register(ViPipe, 0x377B, 0x00); + imx335_write_register(ViPipe, 0x377C, 0x08); + imx335_write_register(ViPipe, 0x377D, 0x01); + imx335_write_register(ViPipe, 0x377E, 0x23); + imx335_write_register(ViPipe, 0x377F, 0x02); + imx335_write_register(ViPipe, 0x3780, 0xD9); + imx335_write_register(ViPipe, 0x3781, 0x03); + imx335_write_register(ViPipe, 0x3782, 0xF5); + imx335_write_register(ViPipe, 0x3783, 0x06); + imx335_write_register(ViPipe, 0x3784, 0xA5); + imx335_write_register(ViPipe, 0x3788, 0x0F); + imx335_write_register(ViPipe, 0x378A, 0xD9); + imx335_write_register(ViPipe, 0x378B, 0x03); + imx335_write_register(ViPipe, 0x378C, 0xEB); + imx335_write_register(ViPipe, 0x378D, 0x05); + imx335_write_register(ViPipe, 0x378E, 0x87); + imx335_write_register(ViPipe, 0x378F, 0x06); + imx335_write_register(ViPipe, 0x3790, 0xF5); + imx335_write_register(ViPipe, 0x3792, 0x43); + imx335_write_register(ViPipe, 0x3794, 0x7A); + imx335_write_register(ViPipe, 0x3796, 0xA1); + imx335_write_register(ViPipe, 0x3A18, 0x7F); + imx335_write_register(ViPipe, 0x3A1A, 0x37); + imx335_write_register(ViPipe, 0x3A1C, 0x37); + imx335_write_register(ViPipe, 0x3A1E, 0xF7); + imx335_write_register(ViPipe, 0x3A1F, 0x00); + imx335_write_register(ViPipe, 0x3A20, 0x3F); + imx335_write_register(ViPipe, 0x3A22, 0x6F); + imx335_write_register(ViPipe, 0x3A24, 0x3F); + imx335_write_register(ViPipe, 0x3A26, 0x5F); + imx335_write_register(ViPipe, 0x3A28, 0x2F); + imx335_default_reg_init(ViPipe); + + imx335_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx335_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe:%d,===IMX335 4M 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void imx335_linear_4M30_2l_init(VI_PIPE ViPipe) +{ + delay_ms(4); + imx335_write_register(ViPipe, 0x3000, 0x01); // STANDBY + imx335_write_register(ViPipe, 0x3002, 0x01); // XTMSTA + + imx335_write_register(ViPipe, 0x300C, 0x5B); // BCWAIT_TIME[7:0] + imx335_write_register(ViPipe, 0x300D, 0x40); // CPWAIT_TIME[7:0] + imx335_write_register(ViPipe, 0x3018, 0x04); // WINMODE[3:0] + imx335_write_register(ViPipe, 0x302C, 0x48); // HTRIMMING_START[11:0] + imx335_write_register(ViPipe, 0x302E, 0x08); // HNUM[11:0] + imx335_write_register(ViPipe, 0x3050, 0x00); // ADBIT[0] + imx335_write_register(ViPipe, 0x3056, 0xA4); // Y_OUT_SIZE[12:0] + imx335_write_register(ViPipe, 0x3057, 0x05); // + imx335_write_register(ViPipe, 0x3074, 0xB8); // AREA3_ST_ADR_1[12:0] + imx335_write_register(ViPipe, 0x3075, 0x02); // + imx335_write_register(ViPipe, 0x3076, 0x48); // AREA3_WIDTH_1[12:0] + imx335_write_register(ViPipe, 0x3077, 0x0B); // + imx335_write_register(ViPipe, 0x30C6, 0x12); // BLACK_OFSET_ADR[12:0] + imx335_write_register(ViPipe, 0x30CE, 0x64); // UNRD_LINE_MAX[12:0] + imx335_write_register(ViPipe, 0x30D8, 0xD0); // UNREAD_ED_ADR[12:0] + imx335_write_register(ViPipe, 0x30D9, 0x0E); // + imx335_write_register(ViPipe, 0x315A, 0x02); // INCKSEL2[1:0] + imx335_write_register(ViPipe, 0x316A, 0x7E); // INCKSEL4[1:0] + imx335_write_register(ViPipe, 0x319D, 0x00); // MDBIT + imx335_write_register(ViPipe, 0x31A1, 0x00); // XVS_DRV[1:0] + imx335_write_register(ViPipe, 0x3288, 0x21); // - + imx335_write_register(ViPipe, 0x328A, 0x02); // - + imx335_write_register(ViPipe, 0x3414, 0x05); // - + imx335_write_register(ViPipe, 0x3416, 0x18); // - + imx335_write_register(ViPipe, 0x341C, 0xFF); // ADBIT1[8:0] + imx335_write_register(ViPipe, 0x341D, 0x01); // + imx335_write_register(ViPipe, 0x3648, 0x01); // - + imx335_write_register(ViPipe, 0x364A, 0x04); // - + imx335_write_register(ViPipe, 0x364C, 0x04); // - + imx335_write_register(ViPipe, 0x3678, 0x01); // - + imx335_write_register(ViPipe, 0x367C, 0x31); // - + imx335_write_register(ViPipe, 0x367E, 0x31); // - + imx335_write_register(ViPipe, 0x3706, 0x10); // - + imx335_write_register(ViPipe, 0x3708, 0x03); // - + imx335_write_register(ViPipe, 0x3714, 0x02); // - + imx335_write_register(ViPipe, 0x3715, 0x02); // - + imx335_write_register(ViPipe, 0x3716, 0x01); // - + imx335_write_register(ViPipe, 0x3717, 0x03); // - + imx335_write_register(ViPipe, 0x371C, 0x3D); // - + imx335_write_register(ViPipe, 0x371D, 0x3F); // - + imx335_write_register(ViPipe, 0x372C, 0x00); // - + imx335_write_register(ViPipe, 0x372D, 0x00); // - + imx335_write_register(ViPipe, 0x372E, 0x46); // - + imx335_write_register(ViPipe, 0x372F, 0x00); // - + imx335_write_register(ViPipe, 0x3730, 0x89); // - + imx335_write_register(ViPipe, 0x3731, 0x00); // - + imx335_write_register(ViPipe, 0x3732, 0x08); // - + imx335_write_register(ViPipe, 0x3733, 0x01); // - + imx335_write_register(ViPipe, 0x3734, 0xFE); // - + imx335_write_register(ViPipe, 0x3735, 0x05); // - + imx335_write_register(ViPipe, 0x3740, 0x02); // - + imx335_write_register(ViPipe, 0x375D, 0x00); // - + imx335_write_register(ViPipe, 0x375E, 0x00); // - + imx335_write_register(ViPipe, 0x375F, 0x11); // - + imx335_write_register(ViPipe, 0x3760, 0x01); // - + imx335_write_register(ViPipe, 0x3768, 0x1A); // - + imx335_write_register(ViPipe, 0x3769, 0x1A); // - + imx335_write_register(ViPipe, 0x376A, 0x1A); // - + imx335_write_register(ViPipe, 0x376B, 0x1A); // - + imx335_write_register(ViPipe, 0x376C, 0x1A); // - + imx335_write_register(ViPipe, 0x376D, 0x17); // - + imx335_write_register(ViPipe, 0x376E, 0x0F); // - + imx335_write_register(ViPipe, 0x3776, 0x00); // - + imx335_write_register(ViPipe, 0x3777, 0x00); // - + imx335_write_register(ViPipe, 0x3778, 0x46); // - + imx335_write_register(ViPipe, 0x3779, 0x00); // - + imx335_write_register(ViPipe, 0x377A, 0x89); // - + imx335_write_register(ViPipe, 0x377B, 0x00); // - + imx335_write_register(ViPipe, 0x377C, 0x08); // - + imx335_write_register(ViPipe, 0x377D, 0x01); // - + imx335_write_register(ViPipe, 0x377E, 0x23); // - + imx335_write_register(ViPipe, 0x377F, 0x02); // - + imx335_write_register(ViPipe, 0x3780, 0xD9); // - + imx335_write_register(ViPipe, 0x3781, 0x03); // - + imx335_write_register(ViPipe, 0x3782, 0xF5); // - + imx335_write_register(ViPipe, 0x3783, 0x06); // - + imx335_write_register(ViPipe, 0x3784, 0xA5); // - + imx335_write_register(ViPipe, 0x3788, 0x0F); // - + imx335_write_register(ViPipe, 0x378A, 0xD9); // - + imx335_write_register(ViPipe, 0x378B, 0x03); // - + imx335_write_register(ViPipe, 0x378C, 0xEB); // - + imx335_write_register(ViPipe, 0x378D, 0x05); // - + imx335_write_register(ViPipe, 0x378E, 0x87); // - + imx335_write_register(ViPipe, 0x378F, 0x06); // - + imx335_write_register(ViPipe, 0x3790, 0xF5); // - + imx335_write_register(ViPipe, 0x3792, 0x43); // - + imx335_write_register(ViPipe, 0x3794, 0x7A); // - + imx335_write_register(ViPipe, 0x3796, 0xA1); // - + imx335_write_register(ViPipe, 0x3A01, 0x01); // LANEMODE[2:0] + imx335_default_reg_init(ViPipe); + + imx335_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx335_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe:%d,===IMX335 4M 30fps 2L 10bit LINE Init OK!===\n", ViPipe); +} + +static void imx335_linear_4M30_1600p_init(VI_PIPE ViPipe) +{ + delay_ms(4); + imx335_write_register(ViPipe, 0x3000, 0x01); // STANDBY + imx335_write_register(ViPipe, 0x3002, 0x01); // XTMSTA + + imx335_write_register(ViPipe, 0x300C, 0x5B); + imx335_write_register(ViPipe, 0x300D, 0x40); + imx335_write_register(ViPipe, 0x3018, 0x04);// WINMODE[3:0] croping mode + imx335_write_register(ViPipe, 0x302C, 0x3C); + imx335_write_register(ViPipe, 0x302E, 0x20); + imx335_write_register(ViPipe, 0x3056, 0x54);//Y_OUT_SIZE[12:0] + imx335_write_register(ViPipe, 0x3057, 0x06); + imx335_write_register(ViPipe, 0x3074, 0x08); + imx335_write_register(ViPipe, 0x3075, 0x02); + imx335_write_register(ViPipe, 0x3076, 0xA8); + imx335_write_register(ViPipe, 0x3077, 0x0C); + imx335_write_register(ViPipe, 0x30C6, 0x12); + imx335_write_register(ViPipe, 0x30CE, 0x64); + imx335_write_register(ViPipe, 0x30D8, 0x80); + imx335_write_register(ViPipe, 0x30D9, 0x0F); + imx335_write_register(ViPipe, 0x315A, 0x02); + imx335_write_register(ViPipe, 0x316A, 0x7E); + imx335_write_register(ViPipe, 0x31A1, 0x00); + imx335_write_register(ViPipe, 0x3288, 0x21); + imx335_write_register(ViPipe, 0x328A, 0x02); + imx335_write_register(ViPipe, 0x3414, 0x05); + imx335_write_register(ViPipe, 0x3416, 0x18); + imx335_write_register(ViPipe, 0x3648, 0x01); + imx335_write_register(ViPipe, 0x364A, 0x04); + imx335_write_register(ViPipe, 0x364C, 0x04); + imx335_write_register(ViPipe, 0x3678, 0x01); + imx335_write_register(ViPipe, 0x367C, 0x31); + imx335_write_register(ViPipe, 0x367E, 0x31); + imx335_write_register(ViPipe, 0x3706, 0x10); + imx335_write_register(ViPipe, 0x3708, 0x03); + imx335_write_register(ViPipe, 0x3714, 0x02); + imx335_write_register(ViPipe, 0x3715, 0x02); + imx335_write_register(ViPipe, 0x3716, 0x01); + imx335_write_register(ViPipe, 0x3717, 0x03); + imx335_write_register(ViPipe, 0x371C, 0x3D); + imx335_write_register(ViPipe, 0x371D, 0x3F); + imx335_write_register(ViPipe, 0x372C, 0x00); + imx335_write_register(ViPipe, 0x372D, 0x00); + imx335_write_register(ViPipe, 0x372E, 0x46); + imx335_write_register(ViPipe, 0x372F, 0x00); + imx335_write_register(ViPipe, 0x3730, 0x89); + imx335_write_register(ViPipe, 0x3731, 0x00); + imx335_write_register(ViPipe, 0x3732, 0x08); + imx335_write_register(ViPipe, 0x3733, 0x01); + imx335_write_register(ViPipe, 0x3734, 0xFE); + imx335_write_register(ViPipe, 0x3735, 0x05); + imx335_write_register(ViPipe, 0x3740, 0x02); + imx335_write_register(ViPipe, 0x375D, 0x00); + imx335_write_register(ViPipe, 0x375E, 0x00); + imx335_write_register(ViPipe, 0x375F, 0x11); + imx335_write_register(ViPipe, 0x3760, 0x01); + imx335_write_register(ViPipe, 0x3768, 0x1B); + imx335_write_register(ViPipe, 0x3769, 0x1B); + imx335_write_register(ViPipe, 0x376A, 0x1B); + imx335_write_register(ViPipe, 0x376B, 0x1B); + imx335_write_register(ViPipe, 0x376C, 0x1A); + imx335_write_register(ViPipe, 0x376D, 0x17); + imx335_write_register(ViPipe, 0x376E, 0x0F); + imx335_write_register(ViPipe, 0x3776, 0x00); + imx335_write_register(ViPipe, 0x3777, 0x00); + imx335_write_register(ViPipe, 0x3778, 0x46); + imx335_write_register(ViPipe, 0x3779, 0x00); + imx335_write_register(ViPipe, 0x377A, 0x89); + imx335_write_register(ViPipe, 0x377B, 0x00); + imx335_write_register(ViPipe, 0x377C, 0x08); + imx335_write_register(ViPipe, 0x377D, 0x01); + imx335_write_register(ViPipe, 0x377E, 0x23); + imx335_write_register(ViPipe, 0x377F, 0x02); + imx335_write_register(ViPipe, 0x3780, 0xD9); + imx335_write_register(ViPipe, 0x3781, 0x03); + imx335_write_register(ViPipe, 0x3782, 0xF5); + imx335_write_register(ViPipe, 0x3783, 0x06); + imx335_write_register(ViPipe, 0x3784, 0xA5); + imx335_write_register(ViPipe, 0x3788, 0x0F); + imx335_write_register(ViPipe, 0x378A, 0xD9); + imx335_write_register(ViPipe, 0x378B, 0x03); + imx335_write_register(ViPipe, 0x378C, 0xEB); + imx335_write_register(ViPipe, 0x378D, 0x05); + imx335_write_register(ViPipe, 0x378E, 0x87); + imx335_write_register(ViPipe, 0x378F, 0x06); + imx335_write_register(ViPipe, 0x3790, 0xF5); + imx335_write_register(ViPipe, 0x3792, 0x43); + imx335_write_register(ViPipe, 0x3794, 0x7A); + imx335_write_register(ViPipe, 0x3796, 0xA1); + imx335_default_reg_init(ViPipe); + + imx335_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx335_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe:%d,===IMX335 4M 1660P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void imx335_linear_5M30_init(VI_PIPE ViPipe) +{ + delay_ms(4); + imx335_write_register(ViPipe, 0x3000, 0x01); // STANDBY + imx335_write_register(ViPipe, 0x3002, 0x01); // XTMSTA + + imx335_write_register(ViPipe, 0x300C, 0x5B); + imx335_write_register(ViPipe, 0x300D, 0x40); + imx335_write_register(ViPipe, 0x315A, 0x02); + imx335_write_register(ViPipe, 0x316A, 0x7E); + imx335_write_register(ViPipe, 0x31A1, 0x00); + imx335_write_register(ViPipe, 0x3288, 0x21); + imx335_write_register(ViPipe, 0x328A, 0x02); + imx335_write_register(ViPipe, 0x3414, 0x05); + imx335_write_register(ViPipe, 0x3416, 0x18); + imx335_write_register(ViPipe, 0x3648, 0x01); + imx335_write_register(ViPipe, 0x364A, 0x04); + imx335_write_register(ViPipe, 0x364C, 0x04); + imx335_write_register(ViPipe, 0x3678, 0x01); + imx335_write_register(ViPipe, 0x367C, 0x31); + imx335_write_register(ViPipe, 0x367E, 0x31); + imx335_write_register(ViPipe, 0x3706, 0x10); + imx335_write_register(ViPipe, 0x3708, 0x03); + imx335_write_register(ViPipe, 0x3714, 0x02); + imx335_write_register(ViPipe, 0x3715, 0x02); + imx335_write_register(ViPipe, 0x3716, 0x01); + imx335_write_register(ViPipe, 0x3717, 0x03); + imx335_write_register(ViPipe, 0x371C, 0x3D); + imx335_write_register(ViPipe, 0x371D, 0x3F); + imx335_write_register(ViPipe, 0x372C, 0x00); + imx335_write_register(ViPipe, 0x372D, 0x00); + imx335_write_register(ViPipe, 0x372E, 0x46); + imx335_write_register(ViPipe, 0x372F, 0x00); + imx335_write_register(ViPipe, 0x3730, 0x89); + imx335_write_register(ViPipe, 0x3731, 0x00); + imx335_write_register(ViPipe, 0x3732, 0x08); + imx335_write_register(ViPipe, 0x3733, 0x01); + imx335_write_register(ViPipe, 0x3734, 0xFE); + imx335_write_register(ViPipe, 0x3735, 0x05); + imx335_write_register(ViPipe, 0x3740, 0x02); + imx335_write_register(ViPipe, 0x375D, 0x00); + imx335_write_register(ViPipe, 0x375E, 0x00); + imx335_write_register(ViPipe, 0x375F, 0x11); + imx335_write_register(ViPipe, 0x3760, 0x01); + imx335_write_register(ViPipe, 0x3768, 0x1B); + imx335_write_register(ViPipe, 0x3769, 0x1B); + imx335_write_register(ViPipe, 0x376A, 0x1B); + imx335_write_register(ViPipe, 0x376B, 0x1B); + imx335_write_register(ViPipe, 0x376C, 0x1A); + imx335_write_register(ViPipe, 0x376D, 0x17); + imx335_write_register(ViPipe, 0x376E, 0x0F); + imx335_write_register(ViPipe, 0x3776, 0x00); + imx335_write_register(ViPipe, 0x3777, 0x00); + imx335_write_register(ViPipe, 0x3778, 0x46); + imx335_write_register(ViPipe, 0x3779, 0x00); + imx335_write_register(ViPipe, 0x377A, 0x89); + imx335_write_register(ViPipe, 0x377B, 0x00); + imx335_write_register(ViPipe, 0x377C, 0x08); + imx335_write_register(ViPipe, 0x377D, 0x01); + imx335_write_register(ViPipe, 0x377E, 0x23); + imx335_write_register(ViPipe, 0x377F, 0x02); + imx335_write_register(ViPipe, 0x3780, 0xD9); + imx335_write_register(ViPipe, 0x3781, 0x03); + imx335_write_register(ViPipe, 0x3782, 0xF5); + imx335_write_register(ViPipe, 0x3783, 0x06); + imx335_write_register(ViPipe, 0x3784, 0xA5); + imx335_write_register(ViPipe, 0x3788, 0x0F); + imx335_write_register(ViPipe, 0x378A, 0xD9); + imx335_write_register(ViPipe, 0x378B, 0x03); + imx335_write_register(ViPipe, 0x378C, 0xEB); + imx335_write_register(ViPipe, 0x378D, 0x05); + imx335_write_register(ViPipe, 0x378E, 0x87); + imx335_write_register(ViPipe, 0x378F, 0x06); + imx335_write_register(ViPipe, 0x3790, 0xF5); + imx335_write_register(ViPipe, 0x3792, 0x43); + imx335_write_register(ViPipe, 0x3794, 0x7A); + imx335_write_register(ViPipe, 0x3796, 0xA1); + imx335_default_reg_init(ViPipe); + + imx335_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx335_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + CVI_TRACE_SNS(CVI_DBG_INFO, "ViPipe:%d,===IMX335 5M 30fps 12bit LINE Init OK!===\n", ViPipe); +} + +static void imx335_wdr_5M30_2to1_init(VI_PIPE ViPipe) +{ + delay_ms(4); + imx335_write_register(ViPipe, 0x3000, 0x01); /* STANDBY */ + imx335_write_register(ViPipe, 0x3002, 0x01); /* XTMSTA */ + imx335_write_register(ViPipe, 0x3003, 0x00); + imx335_write_register(ViPipe, 0x3004, 0x00); + imx335_write_register(ViPipe, 0x300C, 0x5B); // BCWAIT_TIME[7:0] + imx335_write_register(ViPipe, 0x300D, 0x40); // CPWAIT_TIME[7:0] + imx335_write_register(ViPipe, 0x3034, 0x13); // HMAX[15:0] + imx335_write_register(ViPipe, 0x3035, 0x01); // + imx335_write_register(ViPipe, 0x3048, 0x01); // WDMODE[0] + imx335_write_register(ViPipe, 0x3049, 0x01); // WDSEL[1:0] + imx335_write_register(ViPipe, 0x304A, 0x04); // WD_SET1[2:0] + imx335_write_register(ViPipe, 0x304B, 0x03); // WD_SET2[3:0] + imx335_write_register(ViPipe, 0x304C, 0x13); // OPB_SIZE_V[5:0] + imx335_write_register(ViPipe, 0x3050, 0x00); // ADBIT[0] + imx335_write_register(ViPipe, 0x3058, 0x68); // SHR0[19:0] + imx335_write_register(ViPipe, 0x3059, 0x01); // + imx335_write_register(ViPipe, 0x3068, 0x4A); // RHS1[19:0] + imx335_write_register(ViPipe, 0x315A, 0x02); // INCKSEL2[1:0] + imx335_write_register(ViPipe, 0x316A, 0x7E); // INCKSEL4[1:0] + imx335_write_register(ViPipe, 0x319D, 0x00); // MDBIT + imx335_write_register(ViPipe, 0x31A1, 0x00); // XVS_DRV[1:0] + imx335_write_register(ViPipe, 0x31D7, 0x01); // XVSMSKCNT_INT[1:0] + imx335_write_register(ViPipe, 0x3288, 0x21); // - + imx335_write_register(ViPipe, 0x328A, 0x02); // - + imx335_write_register(ViPipe, 0x3414, 0x05); // - + imx335_write_register(ViPipe, 0x3416, 0x18); // - + imx335_write_register(ViPipe, 0x341C, 0xFF); // ADBIT1[8:0] + imx335_write_register(ViPipe, 0x341D, 0x01); // + imx335_write_register(ViPipe, 0x3648, 0x01); // - + imx335_write_register(ViPipe, 0x364A, 0x04); // - + imx335_write_register(ViPipe, 0x364C, 0x04); // - + imx335_write_register(ViPipe, 0x3678, 0x01); // - + imx335_write_register(ViPipe, 0x367C, 0x31); // - + imx335_write_register(ViPipe, 0x367E, 0x31); // - + imx335_write_register(ViPipe, 0x3706, 0x10); // - + imx335_write_register(ViPipe, 0x3708, 0x03); // - + imx335_write_register(ViPipe, 0x3714, 0x02); // - + imx335_write_register(ViPipe, 0x3715, 0x02); // - + imx335_write_register(ViPipe, 0x3716, 0x01); // - + imx335_write_register(ViPipe, 0x3717, 0x03); // - + imx335_write_register(ViPipe, 0x371C, 0x3D); // - + imx335_write_register(ViPipe, 0x371D, 0x3F); // - + imx335_write_register(ViPipe, 0x372C, 0x00); // - + imx335_write_register(ViPipe, 0x372D, 0x00); // - + imx335_write_register(ViPipe, 0x372E, 0x46); // - + imx335_write_register(ViPipe, 0x372F, 0x00); // - + imx335_write_register(ViPipe, 0x3730, 0x89); // - + imx335_write_register(ViPipe, 0x3731, 0x00); // - + imx335_write_register(ViPipe, 0x3732, 0x08); // - + imx335_write_register(ViPipe, 0x3733, 0x01); // - + imx335_write_register(ViPipe, 0x3734, 0xFE); // - + imx335_write_register(ViPipe, 0x3735, 0x05); // - + imx335_write_register(ViPipe, 0x3740, 0x02); // - + imx335_write_register(ViPipe, 0x375D, 0x00); // - + imx335_write_register(ViPipe, 0x375E, 0x00); // - + imx335_write_register(ViPipe, 0x375F, 0x11); // - + imx335_write_register(ViPipe, 0x3760, 0x01); // - + imx335_write_register(ViPipe, 0x3768, 0x1B); // - + imx335_write_register(ViPipe, 0x3769, 0x1B); // - + imx335_write_register(ViPipe, 0x376A, 0x1B); // - + imx335_write_register(ViPipe, 0x376B, 0x1B); // - + imx335_write_register(ViPipe, 0x376C, 0x1A); // - + imx335_write_register(ViPipe, 0x376D, 0x17); // - + imx335_write_register(ViPipe, 0x376E, 0x0F); // - + imx335_write_register(ViPipe, 0x3776, 0x00); // - + imx335_write_register(ViPipe, 0x3777, 0x00); // - + imx335_write_register(ViPipe, 0x3778, 0x46); // - + imx335_write_register(ViPipe, 0x3779, 0x00); // - + imx335_write_register(ViPipe, 0x377A, 0x89); // - + imx335_write_register(ViPipe, 0x377B, 0x00); // - + imx335_write_register(ViPipe, 0x377C, 0x08); // - + imx335_write_register(ViPipe, 0x377D, 0x01); // - + imx335_write_register(ViPipe, 0x377E, 0x23); // - + imx335_write_register(ViPipe, 0x377F, 0x02); // - + imx335_write_register(ViPipe, 0x3780, 0xD9); // - + imx335_write_register(ViPipe, 0x3781, 0x03); // - + imx335_write_register(ViPipe, 0x3782, 0xF5); // - + imx335_write_register(ViPipe, 0x3783, 0x06); // - + imx335_write_register(ViPipe, 0x3784, 0xA5); // - + imx335_write_register(ViPipe, 0x3788, 0x0F); // - + imx335_write_register(ViPipe, 0x378A, 0xD9); // - + imx335_write_register(ViPipe, 0x378B, 0x03); // - + imx335_write_register(ViPipe, 0x378C, 0xEB); // - + imx335_write_register(ViPipe, 0x378D, 0x05); // - + imx335_write_register(ViPipe, 0x378E, 0x87); // - + imx335_write_register(ViPipe, 0x378F, 0x06); // - + imx335_write_register(ViPipe, 0x3790, 0xF5); // - + imx335_write_register(ViPipe, 0x3792, 0x43); // - + imx335_write_register(ViPipe, 0x3794, 0x7A); // - + imx335_write_register(ViPipe, 0x3796, 0xA1); // - + + imx335_default_reg_init(ViPipe); + + imx335_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx335_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + + CVI_TRACE_SNS(CVI_DBG_INFO, "===Imx335 sensor 5M30fps 10bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} +static void imx335_wdr_4M30_2to1_init(VI_PIPE ViPipe) +{ + delay_ms(4); + imx335_write_register(ViPipe, 0x3000, 0x01);/* STANDBY */ + imx335_write_register(ViPipe, 0x3002, 0x01);/* XTMSTA */ + + imx335_write_register(ViPipe, 0x300C, 0x5B);// BCWAIT_TIME[CWAIT_TIME[7:0] + imx335_write_register(ViPipe, 0x300D, 0x40);// CPWAIT_TIME[PWAIT_TIME[7:0] + imx335_write_register(ViPipe, 0x3018, 0x04);// WINMODE[3:0]INMODE[3:0] + imx335_write_register(ViPipe, 0x3034, 0x13);// HMAX[15:0]MAX[15:0] + imx335_write_register(ViPipe, 0x3035, 0x01);// - + imx335_write_register(ViPipe, 0x3048, 0x01);// WDMODE[0]DMODE[0] + imx335_write_register(ViPipe, 0x3049, 0x01);// WDSEL[1:0]DSEL[1:0] + imx335_write_register(ViPipe, 0x304A, 0x04);// WD_SET1[2:0]D_SET1[2:0] + imx335_write_register(ViPipe, 0x304B, 0x03);// WD_SET2[3:0]D_SET2[3:0] + imx335_write_register(ViPipe, 0x304C, 0x13);// OPB_SIZE_V[5PB_SIZE_V[5:0] + imx335_write_register(ViPipe, 0x3050, 0x00);// ADBIT[0]DBIT[0] + imx335_write_register(ViPipe, 0x3056, 0xB4);// Y_OUT_SIZE[1_OUT_SIZE[12:0] + imx335_write_register(ViPipe, 0x3057, 0x05);// - + imx335_write_register(ViPipe, 0x3058, 0x68);// SHR0[19:0]HR0[19:0] + imx335_write_register(ViPipe, 0x3059, 0x01);// - + imx335_write_register(ViPipe, 0x3068, 0x4A);// RHS1[19:0]HS1[19:0] + imx335_write_register(ViPipe, 0x3074, 0xA8);// AREA3_ST_ADRREA3_ST_ADR_1[12:0] + imx335_write_register(ViPipe, 0x3075, 0x02);// - + imx335_write_register(ViPipe, 0x3076, 0x68);// AREA3_WIDTH_REA3_WIDTH_1[12:0] + imx335_write_register(ViPipe, 0x3077, 0x0B);// - + imx335_write_register(ViPipe, 0x30C6, 0x12);// BLACK_OFSET_LACK_OFSET_ADR[12:0] + imx335_write_register(ViPipe, 0x30CE, 0x64);// UNRD_LINE_MANRD_LINE_MAX[12:0] + imx335_write_register(ViPipe, 0x30D8, 0xE0);// UNREAD_ED_ADNREAD_ED_ADR[12:0] + imx335_write_register(ViPipe, 0x30D9, 0x0E);// - + imx335_write_register(ViPipe, 0x315A, 0x02);// INCKSEL2[1:0NCKSEL2[1:0] + imx335_write_register(ViPipe, 0x316A, 0x7E);// INCKSEL4[1:0NCKSEL4[1:0] + imx335_write_register(ViPipe, 0x319D, 0x00);// MDBITDBIT + imx335_write_register(ViPipe, 0x31A1, 0x00);// XVS_DRV[1:0]CEN + imx335_write_register(ViPipe, 0x31D7, 0x01);// XVSMSKCNT_INVS_DRV[1:0] + imx335_write_register(ViPipe, 0x3288, 0x21);// -VSMSKCNT_INT[1:0] + imx335_write_register(ViPipe, 0x328A, 0x02);// - + imx335_write_register(ViPipe, 0x3414, 0x05);// - + imx335_write_register(ViPipe, 0x3416, 0x18);// - + imx335_write_register(ViPipe, 0x341C, 0xFF);// ADBIT1[8:0] + imx335_write_register(ViPipe, 0x341D, 0x01);// DBIT1[8:0] + imx335_write_register(ViPipe, 0x3648, 0x01);// - + imx335_write_register(ViPipe, 0x364A, 0x04);// - + imx335_write_register(ViPipe, 0x364C, 0x04);// - + imx335_write_register(ViPipe, 0x3678, 0x01);// - + imx335_write_register(ViPipe, 0x367C, 0x31);// - + imx335_write_register(ViPipe, 0x367E, 0x31);// - + imx335_write_register(ViPipe, 0x3706, 0x10);// - + imx335_write_register(ViPipe, 0x3708, 0x03);// - + imx335_write_register(ViPipe, 0x3714, 0x02);// - + imx335_write_register(ViPipe, 0x3715, 0x02);// - + imx335_write_register(ViPipe, 0x3716, 0x01);// - + imx335_write_register(ViPipe, 0x3717, 0x03);// - + imx335_write_register(ViPipe, 0x371C, 0x3D);// - + imx335_write_register(ViPipe, 0x371D, 0x3F);// - + imx335_write_register(ViPipe, 0x372C, 0x00);// - + imx335_write_register(ViPipe, 0x372D, 0x00);// - + imx335_write_register(ViPipe, 0x372E, 0x46);// - + imx335_write_register(ViPipe, 0x372F, 0x00);// - + imx335_write_register(ViPipe, 0x3730, 0x89);// - + imx335_write_register(ViPipe, 0x3731, 0x00);// - + imx335_write_register(ViPipe, 0x3732, 0x08);// - + imx335_write_register(ViPipe, 0x3733, 0x01);// - + imx335_write_register(ViPipe, 0x3734, 0xFE);// - + imx335_write_register(ViPipe, 0x3735, 0x05);// - + imx335_write_register(ViPipe, 0x3740, 0x02);// - + imx335_write_register(ViPipe, 0x375D, 0x00);// - + imx335_write_register(ViPipe, 0x375E, 0x00);// - + imx335_write_register(ViPipe, 0x375F, 0x11);// - + imx335_write_register(ViPipe, 0x3760, 0x01);// - + imx335_write_register(ViPipe, 0x3768, 0x1B);// - + imx335_write_register(ViPipe, 0x3769, 0x1B);// - + imx335_write_register(ViPipe, 0x376A, 0x1B);// - + imx335_write_register(ViPipe, 0x376B, 0x1B);// - + imx335_write_register(ViPipe, 0x376C, 0x1A);// - + imx335_write_register(ViPipe, 0x376D, 0x17);// - + imx335_write_register(ViPipe, 0x376E, 0x0F);// - + imx335_write_register(ViPipe, 0x3776, 0x00);// - + imx335_write_register(ViPipe, 0x3777, 0x00);// - + imx335_write_register(ViPipe, 0x3778, 0x46);// - + imx335_write_register(ViPipe, 0x3779, 0x00);// - + imx335_write_register(ViPipe, 0x377A, 0x89);// - + imx335_write_register(ViPipe, 0x377B, 0x00);// - + imx335_write_register(ViPipe, 0x377C, 0x08);// - + imx335_write_register(ViPipe, 0x377D, 0x01);// - + imx335_write_register(ViPipe, 0x377E, 0x23);// - + imx335_write_register(ViPipe, 0x377F, 0x02);// - + imx335_write_register(ViPipe, 0x3780, 0xD9);// - + imx335_write_register(ViPipe, 0x3781, 0x03);// - + imx335_write_register(ViPipe, 0x3782, 0xF5);// - + imx335_write_register(ViPipe, 0x3783, 0x06);// - + imx335_write_register(ViPipe, 0x3784, 0xA5);// - + imx335_write_register(ViPipe, 0x3788, 0x0F);// - + imx335_write_register(ViPipe, 0x378A, 0xD9);// - + imx335_write_register(ViPipe, 0x378B, 0x03);// - + imx335_write_register(ViPipe, 0x378C, 0xEB);// - + imx335_write_register(ViPipe, 0x378D, 0x05);// - + imx335_write_register(ViPipe, 0x378E, 0x87);// - + imx335_write_register(ViPipe, 0x378F, 0x06);// - + imx335_write_register(ViPipe, 0x3790, 0xF5);// - + imx335_write_register(ViPipe, 0x3792, 0x43);// - + imx335_write_register(ViPipe, 0x3794, 0x7A);// - + imx335_write_register(ViPipe, 0x3796, 0xA1);// - + + imx335_default_reg_init(ViPipe); + + imx335_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx335_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + + CVI_TRACE_SNS(CVI_DBG_INFO, "===Imx335 sensor 4M30fps 10bit 2to1 WDR(60fps->30fps) init success!=====\n"); +} +static void imx335_wdr_4M30_1600p_2to1_init(VI_PIPE ViPipe) +{ + delay_ms(4); + imx335_write_register(ViPipe, 0x3000, 0x01);/* STANDBY */ + imx335_write_register(ViPipe, 0x3002, 0x01);/* XTMSTA */ + + imx335_write_register(ViPipe, 0x300C, 0x5B);// BCWAIT_TIME[7:0] + imx335_write_register(ViPipe, 0x300D, 0x40);// CPWAIT_TIME[7:0] + imx335_write_register(ViPipe, 0x3018, 0x04);// WINMODE[3:0] + imx335_write_register(ViPipe, 0x302C, 0x3C);// HTRIMMING_START[11:0] + imx335_write_register(ViPipe, 0x302E, 0x20);// HNUM[11:0] + imx335_write_register(ViPipe, 0x3034, 0x13);// HMAX[15:0] + imx335_write_register(ViPipe, 0x3035, 0x01);// + imx335_write_register(ViPipe, 0x3048, 0x01);// WDMODE[0] + imx335_write_register(ViPipe, 0x3049, 0x01);// WDSEL[1:0] + imx335_write_register(ViPipe, 0x304A, 0x04);// WD_SET1[2:0] + imx335_write_register(ViPipe, 0x304B, 0x03);// WD_SET2[3:0] + imx335_write_register(ViPipe, 0x304C, 0x13);// OPB_SIZE_V[5:0] + imx335_write_register(ViPipe, 0x3050, 0x00);// ADBIT[0] + imx335_write_register(ViPipe, 0x3056, 0x54);// Y_OUT_SIZE[12:0] + imx335_write_register(ViPipe, 0x3057, 0x06);// + imx335_write_register(ViPipe, 0x3058, 0x68);// SHR0[19:0] + imx335_write_register(ViPipe, 0x3059, 0x01);// + imx335_write_register(ViPipe, 0x3068, 0x4A);// RHS1[19:0] + imx335_write_register(ViPipe, 0x3074, 0x08);// AREA3_ST_ADR_1[12:0] + imx335_write_register(ViPipe, 0x3075, 0x02);// + imx335_write_register(ViPipe, 0x3076, 0xA8);// AREA3_WIDTH_1[12:0] + imx335_write_register(ViPipe, 0x3077, 0x0C);// + imx335_write_register(ViPipe, 0x30C6, 0x12);// BLACK_OFSET_ADR[12:0] + imx335_write_register(ViPipe, 0x30CE, 0x64);// UNRD_LINE_MAX[12:0] + imx335_write_register(ViPipe, 0x30D8, 0x80);// UNREAD_ED_ADR[12:0] + imx335_write_register(ViPipe, 0x30D9, 0x0F);// + imx335_write_register(ViPipe, 0x315A, 0x02);// INCKSEL2[1:0] + imx335_write_register(ViPipe, 0x316A, 0x7E);// INCKSEL4[1:0] + imx335_write_register(ViPipe, 0x319D, 0x00);// MDBIT + imx335_write_register(ViPipe, 0x31A1, 0x00);// XVS_DRV[1:0] + imx335_write_register(ViPipe, 0x31D7, 0x01);// XVSMSKCNT_INT[1:0] + imx335_write_register(ViPipe, 0x3288, 0x21);// + imx335_write_register(ViPipe, 0x328A, 0x02);// + imx335_write_register(ViPipe, 0x3414, 0x05);// + imx335_write_register(ViPipe, 0x3416, 0x18);// + imx335_write_register(ViPipe, 0x341C, 0xFF);// ADBIT1[8:0] + imx335_write_register(ViPipe, 0x341D, 0x01);// + imx335_write_register(ViPipe, 0x3648, 0x01);// + imx335_write_register(ViPipe, 0x364A, 0x04);// + imx335_write_register(ViPipe, 0x364C, 0x04);// + imx335_write_register(ViPipe, 0x3678, 0x01);// + imx335_write_register(ViPipe, 0x367C, 0x31);// + imx335_write_register(ViPipe, 0x367E, 0x31);// + imx335_write_register(ViPipe, 0x3706, 0x10);// + imx335_write_register(ViPipe, 0x3708, 0x03);// + imx335_write_register(ViPipe, 0x3714, 0x02);// + imx335_write_register(ViPipe, 0x3715, 0x02);// + imx335_write_register(ViPipe, 0x3716, 0x01);// + imx335_write_register(ViPipe, 0x3717, 0x03);// + imx335_write_register(ViPipe, 0x371C, 0x3D);// + imx335_write_register(ViPipe, 0x371D, 0x3F);// + imx335_write_register(ViPipe, 0x372C, 0x00);// + imx335_write_register(ViPipe, 0x372D, 0x00);// + imx335_write_register(ViPipe, 0x372E, 0x46);// + imx335_write_register(ViPipe, 0x372F, 0x00);// + imx335_write_register(ViPipe, 0x3730, 0x89);// + imx335_write_register(ViPipe, 0x3731, 0x00);// + imx335_write_register(ViPipe, 0x3732, 0x08);// + imx335_write_register(ViPipe, 0x3733, 0x01);// + imx335_write_register(ViPipe, 0x3734, 0xFE);// + imx335_write_register(ViPipe, 0x3735, 0x05);// + imx335_write_register(ViPipe, 0x3740, 0x02);// + imx335_write_register(ViPipe, 0x375D, 0x00);// + imx335_write_register(ViPipe, 0x375E, 0x00);// + imx335_write_register(ViPipe, 0x375F, 0x11);// + imx335_write_register(ViPipe, 0x3760, 0x01);// + imx335_write_register(ViPipe, 0x3768, 0x1B);// + imx335_write_register(ViPipe, 0x3769, 0x1B);// + imx335_write_register(ViPipe, 0x376A, 0x1B);// + imx335_write_register(ViPipe, 0x376B, 0x1B);// + imx335_write_register(ViPipe, 0x376C, 0x1A);// + imx335_write_register(ViPipe, 0x376D, 0x17);// + imx335_write_register(ViPipe, 0x376E, 0x0F);// + imx335_write_register(ViPipe, 0x3776, 0x00);// + imx335_write_register(ViPipe, 0x3777, 0x00);// + imx335_write_register(ViPipe, 0x3778, 0x46);// + imx335_write_register(ViPipe, 0x3779, 0x00);// + imx335_write_register(ViPipe, 0x377A, 0x89);// + imx335_write_register(ViPipe, 0x377B, 0x00);// + imx335_write_register(ViPipe, 0x377C, 0x08);// + imx335_write_register(ViPipe, 0x377D, 0x01);// + imx335_write_register(ViPipe, 0x377E, 0x23);// + imx335_write_register(ViPipe, 0x377F, 0x02);// + imx335_write_register(ViPipe, 0x3780, 0xD9);// + imx335_write_register(ViPipe, 0x3781, 0x03);// + imx335_write_register(ViPipe, 0x3782, 0xF5);// + imx335_write_register(ViPipe, 0x3783, 0x06);// + imx335_write_register(ViPipe, 0x3784, 0xA5);// + imx335_write_register(ViPipe, 0x3788, 0x0F);// + imx335_write_register(ViPipe, 0x378A, 0xD9);// + imx335_write_register(ViPipe, 0x378B, 0x03);// + imx335_write_register(ViPipe, 0x378C, 0xEB);// + imx335_write_register(ViPipe, 0x378D, 0x05);// + imx335_write_register(ViPipe, 0x378E, 0x87);// + imx335_write_register(ViPipe, 0x378F, 0x06);// + imx335_write_register(ViPipe, 0x3790, 0xF5);// + imx335_write_register(ViPipe, 0x3792, 0x43);// + imx335_write_register(ViPipe, 0x3794, 0x7A);// + imx335_write_register(ViPipe, 0x3796, 0xA1);// + + imx335_default_reg_init(ViPipe); + + imx335_write_register(ViPipe, 0x3000, 0x00); /* standby */ + delay_ms(20); + imx335_write_register(ViPipe, 0x3002, 0x00); /* master mode start */ + + CVI_TRACE_SNS(CVI_DBG_INFO, "===Imx335 sensor 4M1600P 30fps 10bit 2to1 WDR(60fps->30fps) init success!\n"); +} diff --git a/middleware/v2/component/panel/cv180x/dsi_3aml069lp01g.h b/middleware/v2/component/panel/cv180x/dsi_3aml069lp01g.h new file mode 100644 index 000000000..a2f903d2c --- /dev/null +++ b/middleware/v2/component/panel/cv180x/dsi_3aml069lp01g.h @@ -0,0 +1,203 @@ +#ifndef _MIPI_TX_PARAM__3AML069LP01G_H_ +#define _MIPI_TX_PARAM__3AML069LP01G_H_ + +#include +#include + +#define _3AML069LP01G_RX_VACT 1024 +#define _3AML069LP01G_RX_VSA 3 +#define _3AML069LP01G_RX_VBP 5 +#define _3AML069LP01G_RX_VFP 7 + +#define _3AML069LP01G_RX_HACT 600 +#define _3AML069LP01G_RX_HSA 20 +#define _3AML069LP01G_RX_HBP 20 +#define _3AML069LP01G_RX_HFP 90 + +#define PIXEL_CLK(x) ((x##_VACT + x##_VSA + x##_VBP + x##_VFP) \ + * (x##_HACT + x##_HSA + x##_HBP + x##_HFP) * 60 / 1000) + +const struct combo_dev_cfg_s dev_cfg_3AML069LP01G_600x1024 = { + .devno = 0, +#ifdef MIPI_PANEL_2_LANES + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, -1, -1}, +#else + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, MIPI_TX_LANE_2, MIPI_TX_LANE_3}, +#endif + .lane_pn_swap = {false, false, false, false, false}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = _3AML069LP01G_RX_HSA, + .vid_hbp_pixels = _3AML069LP01G_RX_HBP, + .vid_hfp_pixels = _3AML069LP01G_RX_HFP, + .vid_hline_pixels = _3AML069LP01G_RX_HACT, + .vid_vsa_lines = _3AML069LP01G_RX_VSA, + .vid_vbp_lines = _3AML069LP01G_RX_VBP, + .vid_vfp_lines = _3AML069LP01G_RX_VFP, + .vid_active_lines = _3AML069LP01G_RX_VACT, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = PIXEL_CLK(_3AML069LP01G_RX), +}; + +const struct hs_settle_s hs_timing_cfg_3AML069LP01G_600x1024 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_3aml069lp01g_0[] = { 0xee, 0x50 }; +static CVI_U8 data_3aml069lp01g_1[] = { 0xea, 0x85, 0x55 }; +static CVI_U8 data_3aml069lp01g_2[] = { 0x24, 0x20 }; +static CVI_U8 data_3aml069lp01g_3[] = { 0x30, 0x00 }; +static CVI_U8 data_3aml069lp01g_4[] = { 0x39, 0x02, 0x07, 0x10 }; +static CVI_U8 data_3aml069lp01g_5[] = { 0x79, 0x00 }; +static CVI_U8 data_3aml069lp01g_6[] = { 0x7b, 0x00 }; +static CVI_U8 data_3aml069lp01g_7[] = { 0x7a, 0x00 }; +static CVI_U8 data_3aml069lp01g_8[] = { 0x90, 0x50, 0xc0 }; +static CVI_U8 data_3aml069lp01g_9[] = { 0x93, 0x80 }; +static CVI_U8 data_3aml069lp01g_10[] = { 0x95, 0x74 }; +static CVI_U8 data_3aml069lp01g_11[] = { 0x97, 0x37 }; +static CVI_U8 data_3aml069lp01g_12[] = { 0x99, 0x00 }; +static CVI_U8 data_3aml069lp01g_13[] = { 0x56, 0x83 }; +static CVI_U8 data_3aml069lp01g_14[] = { 0x33, 0x83 }; +static CVI_U8 data_3aml069lp01g_15[] = { 0x34, 0x3f }; +static CVI_U8 data_3aml069lp01g_16[] = { 0xee, 0x60 }; +static CVI_U8 data_3aml069lp01g_17[] = { 0x30, 0x03 }; +static CVI_U8 data_3aml069lp01g_18[] = { 0x32, 0xd9 }; +static CVI_U8 data_3aml069lp01g_19[] = { 0x3b, 0x00 }; +static CVI_U8 data_3aml069lp01g_20[] = { 0x3c, 0x07 }; +static CVI_U8 data_3aml069lp01g_21[] = { 0x3d, 0x11 }; +static CVI_U8 data_3aml069lp01g_22[] = { 0x3e, 0x94 }; +static CVI_U8 data_3aml069lp01g_23[] = { 0x42, 0x55 }; +static CVI_U8 data_3aml069lp01g_24[] = { 0x43, 0x55 }; +static CVI_U8 data_3aml069lp01g_25[] = { 0x86, 0x20 }; +static CVI_U8 data_3aml069lp01g_26[] = { 0x8b, 0x90 }; +static CVI_U8 data_3aml069lp01g_27[] = { 0x8d, 0x40 }; +static CVI_U8 data_3aml069lp01g_28[] = { 0x91, 0x11 }; +static CVI_U8 data_3aml069lp01g_29[] = { 0x92, 0x11 }; +static CVI_U8 data_3aml069lp01g_30[] = { 0x93, 0x9f }; +static CVI_U8 data_3aml069lp01g_31[] = { 0x9a, 0x07 }; +static CVI_U8 data_3aml069lp01g_32[] = { 0x9b, 0x02, 0x00 }; +static CVI_U8 data_3aml069lp01g_33[] = { 0x47, 0x05, 0x1e, 0x2f, 0x39, 0x40 }; +static CVI_U8 data_3aml069lp01g_34[] = { 0x5a, 0x05, 0x1e, 0x2f, 0x39, 0x40 }; +static CVI_U8 data_3aml069lp01g_35[] = { 0x4c, 0x53, 0x4a, 0x5d, 0x40, 0x40 }; +static CVI_U8 data_3aml069lp01g_36[] = { 0x5f, 0x53, 0x4a, 0x5d, 0x40, 0x40 }; +static CVI_U8 data_3aml069lp01g_37[] = { 0x51, 0x42, 0x29, 0x3e, 0x3d, 0x48 }; +static CVI_U8 data_3aml069lp01g_38[] = { 0x64, 0x42, 0x29, 0x3e, 0x3d, 0x48 }; +static CVI_U8 data_3aml069lp01g_39[] = { 0x56, 0x4c, 0x57, 0x66, 0x7f }; +static CVI_U8 data_3aml069lp01g_40[] = { 0x56, 0x4c, 0x57, 0x66, 0x7f }; +static CVI_U8 data_3aml069lp01g_41[] = { 0xee, 0x70 }; +static CVI_U8 data_3aml069lp01g_42[] = { 0x00, 0x01, 0x04, 0x00, 0x01 }; +static CVI_U8 data_3aml069lp01g_43[] = { 0x04, 0x06, 0x09, 0x44, 0x01 }; +static CVI_U8 data_3aml069lp01g_44[] = { 0x0c, 0x05, 0x2d }; +static CVI_U8 data_3aml069lp01g_45[] = { 0x10, 0x05, 0x09, 0x00, 0x00, 0x00 }; +static CVI_U8 data_3aml069lp01g_46[] = { 0x15, 0x00, 0x19, 0x0c, 0x08, 0x00 }; +static CVI_U8 data_3aml069lp01g_47[] = { 0x20, 0x01, 0x05, 0x00, 0x00, 0x00 }; +static CVI_U8 data_3aml069lp01g_48[] = { 0x25, 0x00, 0x15, 0x0c, 0x07, 0x00 }; +static CVI_U8 data_3aml069lp01g_49[] = { 0x29, 0x05, 0x2d }; +static CVI_U8 data_3aml069lp01g_50[] = { 0x45, 0x01 }; +static CVI_U8 data_3aml069lp01g_51[] = { 0x46, 0xff, 0x00, 0x00, 0x00, 0x50 }; +static CVI_U8 data_3aml069lp01g_52[] = { 0x4b, 0x88 }; +static CVI_U8 data_3aml069lp01g_53[] = { 0x60, 0x3c, 0x05, 0x07, 0x19, 0x1d }; +static CVI_U8 data_3aml069lp01g_54[] = { 0x65, 0x1b, 0x1f, 0x11, 0x11, 0x3c }; +static CVI_U8 data_3aml069lp01g_55[] = { 0x6a, 0x3c, 0x3c, 0x3c, 0x15, 0x15 }; +static CVI_U8 data_3aml069lp01g_56[] = { 0x6f, 0x13, 0x13, 0x17, 0x17, 0x01 }; +static CVI_U8 data_3aml069lp01g_57[] = { 0x74, 0x03, 0x3c }; +static CVI_U8 data_3aml069lp01g_58[] = { 0x80, 0x3c, 0x04, 0x06, 0x18, 0x1c }; +static CVI_U8 data_3aml069lp01g_59[] = { 0x85, 0x1a, 0x1e, 0x10, 0x10, 0x3c }; +static CVI_U8 data_3aml069lp01g_60[] = { 0x8a, 0x3c, 0x3c, 0x3c, 0x14, 0x14 }; +static CVI_U8 data_3aml069lp01g_61[] = { 0x8f, 0x12, 0x12, 0x16, 0x16, 0x00 }; +static CVI_U8 data_3aml069lp01g_62[] = { 0x94, 0x02, 0x3c }; +static CVI_U8 data_3aml069lp01g_63[] = { 0xea, 0x00, 0x00 }; +static CVI_U8 data_3aml069lp01g_64[] = { 0xee, 0x00 }; +static CVI_U8 data_3aml069lp01g_65[] = { 0x11 }; +static CVI_U8 data_3aml069lp01g_66[] = { 0x29 }; +#ifdef _MIPI_TX_BIST_MODE +static CVI_U8 data_3aml069lp01g_67[] = { 0xee, 0x60 }; +static CVI_U8 data_3aml069lp01g_68[] = { 0xea, 0x7a, 0xaa }; + +static CVI_U8 data_3aml069lp01g_69[] = { 0x21, 0x10 }; +static CVI_U8 data_3aml069lp01g_70[] = { 0x11 }; +static CVI_U8 data_3aml069lp01g_71[] = { 0x29 }; +#endif +const struct dsc_instr dsi_init_cmds_3AML069LP01G_600x1024[] = { + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_0 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_1 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_2 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_3 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_3aml069lp01g_4 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_5 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_6 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_7 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_8 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_11 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_16 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_17 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_18 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_19 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_20 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_21 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_22 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_23 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_24 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_25 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_26 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_27 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_28 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_29 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_30 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_31 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_32 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_33 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_34 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_35 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_36 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_37 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_38 }, + {.delay = 0, .data_type = 0x29, .size = 5, .data = data_3aml069lp01g_39 }, + {.delay = 0, .data_type = 0x29, .size = 5, .data = data_3aml069lp01g_40 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_41 }, + {.delay = 0, .data_type = 0x29, .size = 5, .data = data_3aml069lp01g_42 }, + {.delay = 0, .data_type = 0x29, .size = 5, .data = data_3aml069lp01g_43 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_44 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_45 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_46 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_47 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_48 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_49 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_50 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_51 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_52 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_53 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_54 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_55 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_56 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_57 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_58 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_59 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_60 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_61 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_62 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_63 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_64 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_3aml069lp01g_65 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_3aml069lp01g_66 } +#ifdef _MIPI_TX_BIST_MODE + { .delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_67 }, + { .delay = 200, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_68 }, + + { .delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_69 }, + { .delay = 40, .data_type = 0x05, .size = 1, .data = data_3aml069lp01g_70 }, + { .delay = 1, .data_type = 0x05, .size = 1, .data = data_3aml069lp01g_71 }, +#endif +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM__3AML069LP01G_H_ diff --git a/middleware/v2/component/panel/cv180x/dsi_gm8775c.h b/middleware/v2/component/panel/cv180x/dsi_gm8775c.h new file mode 100644 index 000000000..0344a4bf0 --- /dev/null +++ b/middleware/v2/component/panel/cv180x/dsi_gm8775c.h @@ -0,0 +1,160 @@ +#ifndef _MIPI_TX_PARAM_GM8775C_1080P_H_ +#define _MIPI_TX_PARAM_GM8775C_1080P_H_ + +#include +#include "linux/cvi_comm_mipi_tx.h" + +#define _BIST_COLOR 0 + +#define _HX8775C_RX_HACT 1920 +#define _HX8775C_RX_HFP 88 +#define _HX8775C_RX_HSA 44 +#define _HX8775C_RX_HBP 148 + +#define _HX8775C_RX_VACT 1080 +#define _HX8775C_RX_VFP 4 +#define _HX8775C_RX_VSA 5 +#define _HX8775C_RX_VBP 36 + +#define PIXEL_CLK(x) ((x##_VACT + x##_VSA + x##_VBP + x##_VFP) \ + * (x##_HACT + x##_HSA + x##_HBP + x##_HFP) * 60 / 1000) + +struct combo_dev_cfg_s dev_cfg_gm8775c = { + .devno = 0, +#ifdef MIPI_PANEL_2_LANES + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, -1, -1}, +#else + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, MIPI_TX_LANE_2, MIPI_TX_LANE_3}, +#endif + .lane_pn_swap = {true, true, true, true, true}, + + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = _HX8775C_RX_HSA, + .vid_hbp_pixels = _HX8775C_RX_HBP, + .vid_hfp_pixels = _HX8775C_RX_HFP, + .vid_hline_pixels = _HX8775C_RX_HACT, + .vid_vsa_lines = _HX8775C_RX_VSA, + .vid_vbp_lines = _HX8775C_RX_VBP, + .vid_vfp_lines = _HX8775C_RX_VFP, + .vid_active_lines = _HX8775C_RX_VACT, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = PIXEL_CLK(_HX8775C_RX), +}; + +const struct hs_settle_s hs_timing_cfg_gm8775c = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_gm8775c_0[] = { 0x27, 0xAA }; +static CVI_U8 data_gm8775c_1[] = { 0x48, 0x02 }; +static CVI_U8 data_gm8775c_2[] = { 0xB6, 0x20 }; +static CVI_U8 data_gm8775c_3[] = { 0x01, 0x80 }; +static CVI_U8 data_gm8775c_4[] = { 0x02, 0x38 }; +static CVI_U8 data_gm8775c_5[] = { 0x03, 0x47 }; +static CVI_U8 data_gm8775c_6[] = { 0x04, 0x58 }; +static CVI_U8 data_gm8775c_7[] = { 0x05, 0x2c }; +static CVI_U8 data_gm8775c_8[] = { 0x06, 0x94 }; +static CVI_U8 data_gm8775c_9[] = { 0x07, 0x00 }; +static CVI_U8 data_gm8775c_10[] = { 0x08, 0x04 }; +static CVI_U8 data_gm8775c_11[] = { 0x09, 0x05 }; +static CVI_U8 data_gm8775c_12[] = { 0x0A, 0x24 }; + +//use mipi clk +static CVI_U8 data_gm8775c_13[] = { 0x0B, 0x82 }; +static CVI_U8 data_gm8775c_14[] = { 0x0C, 0x14 }; + +static CVI_U8 data_gm8775c_15[] = { 0x0D, 0x01 }; +static CVI_U8 data_gm8775c_16[] = { 0x0E, 0x80 }; +static CVI_U8 data_gm8775c_17[] = { 0x0F, 0x20 }; +static CVI_U8 data_gm8775c_18[] = { 0x10, 0x20 }; +static CVI_U8 data_gm8775c_19[] = { 0x11, 0x03 }; +static CVI_U8 data_gm8775c_20[] = { 0x12, 0x1B }; +static CVI_U8 data_gm8775c_21[] = { 0x13, 0x53 }; +static CVI_U8 data_gm8775c_22[] = { 0x14, 0x01 }; +static CVI_U8 data_gm8775c_23[] = { 0x15, 0x23 }; +static CVI_U8 data_gm8775c_24[] = { 0x16, 0x40 }; +static CVI_U8 data_gm8775c_25[] = { 0x17, 0x00 }; +static CVI_U8 data_gm8775c_26[] = { 0x18, 0x01 }; +static CVI_U8 data_gm8775c_27[] = { 0x19, 0x23 }; +static CVI_U8 data_gm8775c_28[] = { 0x1A, 0x40 }; +static CVI_U8 data_gm8775c_29[] = { 0x1B, 0x00 }; +static CVI_U8 data_gm8775c_30[] = { 0x1E, 0x46 }; +static CVI_U8 data_gm8775c_31[] = { 0x51, 0x30 }; +static CVI_U8 data_gm8775c_32[] = { 0x1F, 0x10 }; +//debug +// static CVI_U8 data_gm8775c_35[] = { 0x7B, 0x4E }; +// static CVI_U8 data_gm8775c_36[] = { 0x7C, 0x4F }; +// static CVI_U8 data_gm8775c_37[] = { 0x7D, 0x4D }; + +#if _BIST_COLOR +static CVI_U8 data_gm8775c_33[] = { 0x2A, 0x4D }; +#else +static CVI_U8 data_gm8775c_34[] = { 0x2A, 0x01 }; + +// static CVI_U8 data_gm8775c_35[] = { 0x6A, 0x08 }; +// static CVI_U8 data_gm8775c_36[] = { 0x6C, 0x9E }; +// static CVI_U8 data_gm8775c_37[] = { 0x6D, 0x07 }; +// static CVI_U8 data_gm8775c_38[] = { 0x6E, 0x00 }; +// static CVI_U8 data_gm8775c_39[] = { 0x6F, 0x8A }; +// static CVI_U8 data_gm8775c_40[] = { 0x70, 0x19 }; +// static CVI_U8 data_gm8775c_41[] = { 0x71, 0x00 }; +#endif + +const struct dsc_instr dsi_init_cmds_gm8775c[] = { + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_0 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_1 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_2 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_3 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_4 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_5 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_6 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_7 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_8 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_9 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_10 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_11 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_12 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_13 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_14 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_15 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_16 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_17 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_18 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_19 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_20 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_21 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_22 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_23 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_24 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_25 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_26 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_27 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_28 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_29 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_30 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_31 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_32 }, + //debug + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_35 }, + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_36 }, + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_37 }, +#if _BIST_COLOR + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_33 }, +#else + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_34 } + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_35 }, + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_36 }, + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_37 }, + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_38 }, + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_39 }, + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_40 }, + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_41 } +#endif +}; +#endif +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_GM8775C_1080P_H_ diff --git a/middleware/v2/component/panel/cv180x/dsi_hx8394_evb.h b/middleware/v2/component/panel/cv180x/dsi_hx8394_evb.h new file mode 100644 index 000000000..48f4ba9fa --- /dev/null +++ b/middleware/v2/component/panel/cv180x/dsi_hx8394_evb.h @@ -0,0 +1,125 @@ +#ifndef _MIPI_TX_PARAM_HX8394_H_ +#define _MIPI_TX_PARAM_HX8394_H_ + +#include +#include + +const struct combo_dev_cfg_s dev_cfg_hx8394_720x1280 = { + .devno = 0, +#ifdef MIPI_PANEL_2_LANES + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, -1, -1}, +#else + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, MIPI_TX_LANE_2, MIPI_TX_LANE_3}, +#endif + .lane_pn_swap = {true, true, true, true, true}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = 64, + .vid_hbp_pixels = 36, + .vid_hfp_pixels = 128, + .vid_hline_pixels = 720, + .vid_vsa_lines = 16, + .vid_vbp_lines = 4, + .vid_vfp_lines = 6, + .vid_active_lines = 1280, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 74250, +}; + +const struct hs_settle_s hs_timing_cfg_hx8394_720x1280 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_hx8394_0[] = { 0xb9, 0xff, 0x83, 0x94 }; +static CVI_U8 data_hx8394_1[] = { + 0xb1, 0x50, 0x15, 0x75, 0x09, 0x32, 0x44, 0x71, 0x31, 0x4d, + 0x2f, 0x56, 0x73, 0x02, 0x02 +}; +static CVI_U8 data_hx8394_2[] = { +#ifdef MIPI_PANEL_2_LANES + 0xba, 0x61, 0x03, 0x68, 0x6b, 0xb2, 0xc0 +#else + 0xba, 0x63, 0x03, 0x68, 0x6b, 0xb2, 0xc0 +#endif +}; +static CVI_U8 data_hx8394_3[] = { 0xd2, 0x88 }; +static CVI_U8 data_hx8394_4[] = { 0xb2, 0x00, 0x80, 0x64, 0x10, 0x07 }; +static CVI_U8 data_hx8394_5[] = { + 0xb4, 0x01, 0x75, 0x01, 0x75, 0x01, 0x75, 0x01, 0x0c, 0x86, + 0x75, 0x00, 0x3f, 0x01, 0x75, 0x01, 0x75, 0x01, 0x75, 0x01, + 0x0c, 0x86 +}; +static CVI_U8 data_hx8394_6[] = { + 0xd3, 0x00, 0x00, 0x06, 0x06, 0x40, 0x1a, 0x08, 0x00, 0x32, + 0x10, 0x08, 0x00, 0x08, 0x54, 0x15, 0x10, 0x05, 0x04, 0x02, + 0x12, 0x10, 0x05, 0x07, 0x23, 0x23, 0x0c, 0x0c, 0x27, 0x10, + 0x07, 0x07, 0x10, 0x40 +}; +static CVI_U8 data_hx8394_7[] = { + 0xd5, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x20, + 0x21, 0x22, 0x23, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x19, 0x19, 0x18, 0x18, 0x18, 0x18, 0x1b, 0x1b, 0x1a, + 0x1a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18 +}; +static CVI_U8 data_hx8394_8[] = { + 0xd6, 0x03, 0x02, 0x01, 0x00, 0x07, 0x06, 0x05, 0x04, 0x23, + 0x22, 0x21, 0x20, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x58, + 0x58, 0x18, 0x18, 0x19, 0x19, 0x18, 0x18, 0x1b, 0x1b, 0x1a, + 0x1a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18 +}; +static CVI_U8 data_hx8394_9[] = { + 0xe0, 0x00, 0x1a, 0x24, 0x2c, 0x2e, 0x32, 0x34, 0x32, 0x66, + 0x73, 0x82, 0x7f, 0x85, 0x95, 0x97, 0x99, 0xa4, 0xa5, 0xa0, + 0xab, 0xba, 0x5a, 0x59, 0x5d, 0x61, 0x63, 0x6c, 0x72, 0x7f, + 0x00, 0x19, 0x24, 0x2c, 0x2e, 0x32, 0x34, 0x32, 0x66, 0x73, + 0x82, 0x7f, 0x85, 0x95, 0x97, 0x99, 0xa4, 0xa5, 0xa0, 0xab, + 0xba, 0x5a, 0x59, 0x5d, 0x61, 0x63, 0x6c, 0x72, 0x7f +}; +static CVI_U8 data_hx8394_10[] = { 0xcc, 0x03 }; +static CVI_U8 data_hx8394_11[] = { 0xc0, 0x1f, 0x73 }; +static CVI_U8 data_hx8394_12[] = { 0xb6, 0x42, 0x42 }; +static CVI_U8 data_hx8394_13[] = { 0xd4, 0x02 }; +static CVI_U8 data_hx8394_14[] = { 0xbd, 0x01 }; +static CVI_U8 data_hx8394_15[] = { 0xb1, 0x00 }; +static CVI_U8 data_hx8394_16[] = { 0xbd, 0x00 }; +static CVI_U8 data_hx8394_17[] = { + 0xbf, 0x40, 0x81, 0x50, 0x00, 0x1a, 0xfc, 0x01 +}; +static CVI_U8 data_hx8394_18[] = { 0xc6, 0xef }; +static CVI_U8 data_hx8394_19[] = { 0x36, 0x02 };// h-flip +static CVI_U8 data_hx8394_20[] = { 0x11 }; +static CVI_U8 data_hx8394_21[] = { 0x29 }; + +const struct dsc_instr dsi_init_cmds_hx8394_720x1280[] = { + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_hx8394_0 }, + {.delay = 0, .data_type = 0x29, .size = 15, .data = data_hx8394_1 }, + {.delay = 0, .data_type = 0x29, .size = 7, .data = data_hx8394_2 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8394_3 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_hx8394_4 }, + {.delay = 0, .data_type = 0x29, .size = 22, .data = data_hx8394_5 }, + {.delay = 0, .data_type = 0x29, .size = 34, .data = data_hx8394_6 }, + {.delay = 0, .data_type = 0x29, .size = 45, .data = data_hx8394_7 }, + {.delay = 0, .data_type = 0x29, .size = 45, .data = data_hx8394_8 }, + {.delay = 0, .data_type = 0x29, .size = 59, .data = data_hx8394_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8394_10 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_hx8394_11 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_hx8394_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8394_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8394_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8394_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8394_16 }, + {.delay = 0, .data_type = 0x29, .size = 8, .data = data_hx8394_17 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8394_18 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8394_19 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_hx8394_20 }, + {.delay = 20, .data_type = 0x05, .size = 1, .data = data_hx8394_21 } + +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_HX8394_H_ diff --git a/middleware/v2/component/panel/cv180x/dsi_hx8399_1080p.h b/middleware/v2/component/panel/cv180x/dsi_hx8399_1080p.h new file mode 100644 index 000000000..57b27c22a --- /dev/null +++ b/middleware/v2/component/panel/cv180x/dsi_hx8399_1080p.h @@ -0,0 +1,194 @@ +#ifndef _MIPI_TX_PARAM_HX8399_1080P_H_ +#define _MIPI_TX_PARAM_HX8399_1080P_H_ + +#include +#include + +#define HX8399_HACT 1080 +#define HX8399_HSA 5 +#define HX8399_HBP 148 +#define HX8399_HFP 5 + +#define HX8399_VACT 1920 +#define HX8399_VSA 6 +#define HX8399_VBP 2 +#define HX8399_VFP 2 + +#define PIXEL_CLK(x) ((x##_VACT + x##_VSA + x##_VBP + x##_VFP) \ + * (x##_HACT + x##_HSA + x##_HBP + x##_HFP) * 60 / 1000) + +const struct combo_dev_cfg_s dev_cfg_hx8399_1080x1920 = { + .devno = 0, +#ifdef MIPI_PANEL_2_LANES + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, -1, -1}, +#else + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, MIPI_TX_LANE_2, MIPI_TX_LANE_3}, +#endif + .lane_pn_swap = {true, true, true, true, true}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = HX8399_HSA, + .vid_hbp_pixels = HX8399_HBP, + .vid_hfp_pixels = HX8399_HFP, + .vid_hline_pixels = HX8399_HACT, + .vid_vsa_lines = HX8399_VSA, + .vid_vbp_lines = HX8399_VBP, + .vid_vfp_lines = HX8399_VFP, + .vid_active_lines = HX8399_VACT, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = PIXEL_CLK(HX8399), +}; + +const struct hs_settle_s hs_timing_cfg_hx8399_1080x1920 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_hx8399_0[] = { + 0xB9, 0xFF, 0x83, 0x99, +}; +static CVI_U8 data_hx8399_1[] = { + 0xD2, 0x77, +}; +static CVI_U8 data_hx8399_2[] = { + 0xB1, 0x02, 0x04, 0x74, + 0x94, 0x01, 0x32, 0x33, + 0x11, 0x11, 0xAB, 0x4D, + 0x56, 0x73, 0x02, 0x02, +}; +static CVI_U8 data_hx8399_3[] = { + 0xB2, 0x00, 0x80, 0x80, + 0xAE, 0x05, 0x07, 0x5A, + 0x11, 0x00, 0x00, 0x10, + 0x1E, 0x70, 0x03, 0xD4, +}; +static CVI_U8 data_hx8399_4[] = { + 0xB4, 0x00, 0xFF, 0x02, + 0xC0, 0x02, 0xC0, 0x00, + 0x00, 0x08, 0x00, 0x04, + 0x06, 0x00, 0x32, 0x04, + 0x0A, 0x08, 0x21, 0x03, + 0x01, 0x00, 0x0F, 0xB8, + 0x8B, 0x02, 0xC0, 0x02, + 0xC0, 0x00, 0x00, 0x08, + 0x00, 0x04, 0x06, 0x00, + 0x32, 0x04, 0x0A, 0x08, + 0x01, 0x00, 0x0F, 0xB8, + 0x01, +}; +static CVI_U8 data_hx8399_5[] = { + 0xD3, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x10, 0x04, + 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x05, 0x05, + 0x07, 0x00, 0x00, 0x00, + 0x05, 0x40, +}; +static CVI_U8 data_hx8399_6[] = { + 0xD5, 0x18, 0x18, 0x19, + 0x19, 0x18, 0x18, 0x21, + 0x20, 0x01, 0x00, 0x07, + 0x06, 0x05, 0x04, 0x03, + 0x02, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x2F, + 0x2F, 0x30, 0x30, 0x31, + 0x31, 0x18, 0x18, 0x18, + 0x18, +}; +static CVI_U8 data_hx8399_7[] = { + 0xD6, 0x18, 0x18, 0x19, + 0x19, 0x40, 0x40, 0x20, + 0x21, 0x06, 0x07, 0x00, + 0x01, 0x02, 0x03, 0x04, + 0x05, 0x40, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x2F, + 0x2F, 0x30, 0x30, 0x31, + 0x31, 0x40, 0x40, 0x40, + 0x40, +}; +static CVI_U8 data_hx8399_8[] = { + 0xD8, 0xA2, 0xAA, 0x02, + 0xA0, 0xA2, 0xA8, 0x02, + 0xA0, 0xB0, 0x00, 0x00, + 0x00, 0xB0, 0x00, 0x00, + 0x00, +}; +static CVI_U8 data_hx8399_9[] = { + 0xBD, 0x01, +}; +static CVI_U8 data_hx8399_10[] = { + 0xD8, 0xB0, 0x00, 0x00, + 0x00, 0xB0, 0x00, 0x00, + 0x00, 0xE2, 0xAA, 0x03, + 0xF0, 0xE2, 0xAA, 0x03, + 0xF0, +}; +static CVI_U8 data_hx8399_11[] = { + 0xBD, 0x02, +}; +static CVI_U8 data_hx8399_12[] = { + 0xD8, 0xE2, 0xAA, 0x03, + 0xF0, 0xE2, 0xAA, 0x03, + 0xF0, +}; +static CVI_U8 data_hx8399_13[] = { + 0xBD, 0x00, +}; +static CVI_U8 data_hx8399_14[] = { + 0xB6, 0x8D, 0x8D +}; +static CVI_U8 data_hx8399_15[] = { + 0xE0, 0x00, 0x0E, 0x19, + 0x13, 0x2E, 0x39, 0x48, + 0x44, 0x4D, 0x57, 0x5F, + 0x66, 0x6C, 0x76, 0x7F, + 0x85, 0x8A, 0x95, 0x9A, + 0xA4, 0x9B, 0xAB, 0xB0, + 0x5C, 0x58, 0x64, 0x77, + 0x00, 0x0E, 0x19, 0x13, + 0x2E, 0x39, 0x48, 0x44, + 0x4D, 0x57, 0x5F, 0x66, + 0x6C, 0x76, 0x7F, 0x85, + 0x8A, 0x95, 0x9A, 0xA4, + 0x9B, 0xAB, 0xB0, 0x5C, + 0x58, 0x64, 0x77, +}; +static CVI_U8 data_hx8399_16[] = { + 0xcc, 0x08, +}; +static CVI_U8 data_hx8399_17[] = { + 0x11, 0x00 +}; +static CVI_U8 data_hx8399_18[] = { + 0x29, 0x00 +}; + +const struct dsc_instr dsi_init_cmds_hx8399_1080x1920[] = { + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_hx8399_0 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8399_1 }, + {.delay = 0, .data_type = 0x29, .size = 16, .data = data_hx8399_2 }, + {.delay = 0, .data_type = 0x29, .size = 16, .data = data_hx8399_3 }, + {.delay = 0, .data_type = 0x29, .size = 45, .data = data_hx8399_4 }, + {.delay = 10, .data_type = 0x29, .size = 34, .data = data_hx8399_5 }, + {.delay = 10, .data_type = 0x29, .size = 33, .data = data_hx8399_6 }, + {.delay = 10, .data_type = 0x29, .size = 33, .data = data_hx8399_7 }, + {.delay = 0, .data_type = 0x29, .size = 17, .data = data_hx8399_8 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8399_9 }, + {.delay = 0, .data_type = 0x29, .size = 17, .data = data_hx8399_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8399_11 }, + {.delay = 0, .data_type = 0x29, .size = 9, .data = data_hx8399_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8399_13 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_hx8399_14 }, + {.delay = 10, .data_type = 0x29, .size = 55, .data = data_hx8399_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8399_16 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_hx8399_17 }, + {.delay = 20, .data_type = 0x05, .size = 1, .data = data_hx8399_18 }, +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_HX8399_1080P_H_ diff --git a/middleware/v2/component/panel/cv180x/dsi_icn9707.h b/middleware/v2/component/panel/cv180x/dsi_icn9707.h new file mode 100644 index 000000000..5a0e42f4c --- /dev/null +++ b/middleware/v2/component/panel/cv180x/dsi_icn9707.h @@ -0,0 +1,130 @@ +#ifndef _MIPI_TX_PARAM_ICN9707_H_ +#define _MIPI_TX_PARAM_ICN9707_H_ + +#include +#include + +const struct combo_dev_cfg_s dev_cfg_icn9707_480x1920 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_3, MIPI_TX_LANE_2, MIPI_TX_LANE_CLK, MIPI_TX_LANE_1, MIPI_TX_LANE_0}, + .lane_pn_swap = {true, true, true, true, true}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = 4, + .vid_hbp_pixels = 53, + .vid_hfp_pixels = 53, + .vid_hline_pixels = 480, + .vid_vsa_lines = 4, + .vid_vbp_lines = 12, + .vid_vfp_lines = 32, + .vid_active_lines = 1920, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 69660, +}; + +const struct hs_settle_s hs_timing_cfg_icn9707_480x1920 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_icn9707_0[] = { 0xf0, 0x5a, 0x59 }; +static CVI_U8 data_icn9707_1[] = { 0xf1, 0xa5, 0xa6 }; +static CVI_U8 data_icn9707_2[] = { + 0xb4, 0x1d, 0x1c, 0x0b, 0x10, 0x11, 0x12, 0x13, 0x0c, 0x0d, + 0x0e, 0x0f, 0x00, 0x1e, 0x1f, 0x04, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03 +}; +static CVI_U8 data_icn9707_3[] = { + 0xb0, 0x60, 0x00, 0x00, 0x08, 0x66, 0x66, 0x33, 0x33, 0x66, + 0x00, 0x00, 0xaf, 0x00, 0x00, 0x0f +}; +static CVI_U8 data_icn9707_4[] = { + 0xb1, 0x53, 0xa0, 0x00, 0x85, 0x0e, 0x00, 0x00, 0x62, 0x00, + 0x00 +}; +static CVI_U8 data_icn9707_5[] = { + 0xb2, 0x37, 0x09, 0x08, 0x8b, 0x08, 0x00, 0x22, 0x00, 0x44, + 0xd9 +}; +static CVI_U8 data_icn9707_6[] = { 0xb6, 0x49, 0x49 }; +static CVI_U8 data_icn9707_7[] = { + 0xb7, 0x01, 0x01, 0x09, 0x0d, 0x11, 0x19, 0x1d, 0x15, 0x00, + 0x25, 0x21, 0x00, 0x00, 0x00, 0x00, 0x02, 0xf7, 0x38 +}; +static CVI_U8 data_icn9707_8[] = { 0xb8, 0x34, 0x53, 0x02, 0xcc }; +static CVI_U8 data_icn9707_9[] = { 0xba, 0x27, 0x33 }; +static CVI_U8 data_icn9707_10[] = { + 0xbd, 0x43, 0x0e, 0x0e, 0x4b, 0x4b, 0x14, 0x14 +}; +static CVI_U8 data_icn9707_11[] = { + 0xc1, 0x00, 0x0c, 0x20, 0x04, 0x00, 0x32, 0x32, 0x04 +}; +static CVI_U8 data_icn9707_12[] = { 0xc2, 0x31, 0xc0 }; +static CVI_U8 data_icn9707_13[] = { 0xc3, 0x22, 0x31 }; +static CVI_U8 data_icn9707_14[] = { + 0xc6, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00 +}; +static CVI_U8 data_icn9707_15[] = { + 0xc8, 0x7c, 0x66, 0x56, 0x49, 0x46, 0x37, 0x3a, 0x23, 0x3b, + 0x38, 0x38, 0x55, 0x43, 0x4c, 0x40, 0x3c, 0x2f, 0x1c, 0x06, + 0x7c, 0x65, 0x56, 0x4a, 0x46, 0x37, 0x3a, 0x23, 0x3a, 0x38, + 0x38, 0x55, 0x43, 0x4c, 0x40, 0x3c, 0x2f, 0x1c, 0x06 +}; +static CVI_U8 data_icn9707_16[] = { 0xd0, 0x07, 0xff, 0xff }; +static CVI_U8 data_icn9707_17[] = { 0xd2, 0x63, 0x0b, 0x08, 0x88 }; +static CVI_U8 data_icn9707_18[] = { + 0xd4, 0x00, 0x00, 0x00, 0x32, 0x04, 0x54 +}; +static CVI_U8 data_icn9707_19[] = { 0xf1, 0x5a, 0x59 }; +static CVI_U8 data_icn9707_20[] = { 0xf0, 0xa5, 0xa6 }; +static CVI_U8 data_icn9707_21[] = { 0x11 }; +static CVI_U8 data_icn9707_22[] = { 0x29 }; + +#ifdef _MIPI_TX_BIST_MODE +static CVI_U8 data_icn9707_23[] = { 0x01 }; +static CVI_U8 data_icn9707_24[] = { 0xF0, 0x5A, 0x59 }; +static CVI_U8 data_icn9707_25[] = { 0xF1, 0xA5, 0xA6 }; +static CVI_U8 data_icn9707_26[] = { 0xC0, 0x11 }; +static CVI_U8 data_icn9707_27[] = { 0x11 }; +static CVI_U8 data_icn9707_28[] = { 0x29 }; +#endif + +const struct dsc_instr dsi_init_cmds_icn9707_480x1920[] = { +#ifdef _MIPI_TX_BIST_MODE + { .delay = 120, .data_type = 0x05, .size = 1, .data = data_icn9707_23 }, + { .delay = 0, .data_type = 0x29, .size = 3, .data = data_icn9707_24 }, + { .delay = 0, .data_type = 0x29, .size = 1, .data = data_icn9707_25 }, + { .delay = 0, .data_type = 0x15, .size = 2, .data = data_icn9707_26 }, + { .delay = 200, .data_type = 0x05, .size = 1, .data = data_icn9707_27 }, + { .delay = 50, .data_type = 0x05, .size = 1, .data = data_icn9707_28 } +#else + {.delay = 1, .data_type = 0x29, .size = 3, .data = data_icn9707_0 }, + {.delay = 1, .data_type = 0x29, .size = 3, .data = data_icn9707_1 }, + {.delay = 1, .data_type = 0x29, .size = 23, .data = data_icn9707_2 }, + {.delay = 1, .data_type = 0x29, .size = 16, .data = data_icn9707_3 }, + {.delay = 1, .data_type = 0x29, .size = 11, .data = data_icn9707_4 }, + {.delay = 1, .data_type = 0x29, .size = 11, .data = data_icn9707_5 }, + {.delay = 1, .data_type = 0x29, .size = 3, .data = data_icn9707_6 }, + {.delay = 1, .data_type = 0x29, .size = 19, .data = data_icn9707_7 }, + {.delay = 1, .data_type = 0x29, .size = 5, .data = data_icn9707_8 }, + {.delay = 1, .data_type = 0x29, .size = 3, .data = data_icn9707_9 }, + {.delay = 1, .data_type = 0x29, .size = 8, .data = data_icn9707_10 }, + {.delay = 1, .data_type = 0x29, .size = 9, .data = data_icn9707_11 }, + {.delay = 1, .data_type = 0x29, .size = 3, .data = data_icn9707_12 }, + {.delay = 1, .data_type = 0x29, .size = 3, .data = data_icn9707_13 }, + {.delay = 1, .data_type = 0x29, .size = 9, .data = data_icn9707_14 }, + {.delay = 1, .data_type = 0x29, .size = 39, .data = data_icn9707_15 }, + {.delay = 1, .data_type = 0x29, .size = 4, .data = data_icn9707_16 }, + {.delay = 1, .data_type = 0x29, .size = 5, .data = data_icn9707_17 }, + {.delay = 1, .data_type = 0x29, .size = 7, .data = data_icn9707_18 }, + {.delay = 1, .data_type = 0x29, .size = 3, .data = data_icn9707_19 }, + {.delay = 1, .data_type = 0x29, .size = 3, .data = data_icn9707_20 }, + {.delay = 200, .data_type = 0x05, .size = 1, .data = data_icn9707_21 }, + {.delay = 50, .data_type = 0x05, .size = 1, .data = data_icn9707_22 } +#endif +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_ICN9707_H_ diff --git a/middleware/v2/component/panel/cv180x/dsi_ili9881c.h b/middleware/v2/component/panel/cv180x/dsi_ili9881c.h new file mode 100644 index 000000000..8ff5e47cc --- /dev/null +++ b/middleware/v2/component/panel/cv180x/dsi_ili9881c.h @@ -0,0 +1,429 @@ +#ifndef _MIPI_TX_PARAM_ILI9881C_H_ +#define _MIPI_TX_PARAM_ILI9881C_H_ + +#include +#include + +const struct combo_dev_cfg_s dev_cfg_ili9881c_720x1280 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, MIPI_TX_LANE_2, MIPI_TX_LANE_3}, + .lane_pn_swap = {false, false, false, false, false}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = 64, + .vid_hbp_pixels = 36, + .vid_hfp_pixels = 128, + .vid_hline_pixels = 720, + .vid_vsa_lines = 16, + .vid_vbp_lines = 4, + .vid_vfp_lines = 6, + .vid_active_lines = 1280, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 74250, +}; + +const struct hs_settle_s hs_timing_cfg_ili9881c_720x1280 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_ili9881c_0[] = { 0xff, 0x98, 0x81, 0x03 }; +static CVI_U8 data_ili9881c_1[] = { 0x01, 0x00 }; +static CVI_U8 data_ili9881c_2[] = { 0x02, 0x00 }; +static CVI_U8 data_ili9881c_3[] = { 0x03, 0x73 }; +static CVI_U8 data_ili9881c_4[] = { 0x04, 0x00 }; +static CVI_U8 data_ili9881c_5[] = { 0x05, 0x00 }; +static CVI_U8 data_ili9881c_6[] = { 0x06, 0x0a }; +static CVI_U8 data_ili9881c_7[] = { 0x07, 0x00 }; +static CVI_U8 data_ili9881c_8[] = { 0x08, 0x00 }; +static CVI_U8 data_ili9881c_9[] = { 0x09, 0x01 }; +static CVI_U8 data_ili9881c_10[] = { 0x0a, 0x00 }; +static CVI_U8 data_ili9881c_11[] = { 0x0b, 0x00 }; +static CVI_U8 data_ili9881c_12[] = { 0x0c, 0x01 }; +static CVI_U8 data_ili9881c_13[] = { 0x0d, 0x00 }; +static CVI_U8 data_ili9881c_14[] = { 0x0e, 0x00 }; +static CVI_U8 data_ili9881c_15[] = { 0x0f, 0x1d }; +static CVI_U8 data_ili9881c_16[] = { 0x10, 0x1d }; +static CVI_U8 data_ili9881c_17[] = { 0x11, 0x00 }; +static CVI_U8 data_ili9881c_18[] = { 0x12, 0x00 }; +static CVI_U8 data_ili9881c_19[] = { 0x13, 0x00 }; +static CVI_U8 data_ili9881c_20[] = { 0x14, 0x00 }; +static CVI_U8 data_ili9881c_21[] = { 0x15, 0x00 }; +static CVI_U8 data_ili9881c_22[] = { 0x16, 0x00 }; +static CVI_U8 data_ili9881c_23[] = { 0x17, 0x00 }; +static CVI_U8 data_ili9881c_24[] = { 0x18, 0x00 }; +static CVI_U8 data_ili9881c_25[] = { 0x19, 0x00 }; +static CVI_U8 data_ili9881c_26[] = { 0x1a, 0x00 }; +static CVI_U8 data_ili9881c_27[] = { 0x1b, 0x00 }; +static CVI_U8 data_ili9881c_28[] = { 0x1c, 0x00 }; +static CVI_U8 data_ili9881c_29[] = { 0x1d, 0x00 }; +static CVI_U8 data_ili9881c_30[] = { 0x1e, 0x40 }; +static CVI_U8 data_ili9881c_31[] = { 0x1f, 0x80 }; +static CVI_U8 data_ili9881c_32[] = { 0x20, 0x06 }; +static CVI_U8 data_ili9881c_33[] = { 0x21, 0x02 }; +static CVI_U8 data_ili9881c_34[] = { 0x22, 0x00 }; +static CVI_U8 data_ili9881c_35[] = { 0x23, 0x00 }; +static CVI_U8 data_ili9881c_36[] = { 0x24, 0x00 }; +static CVI_U8 data_ili9881c_37[] = { 0x25, 0x00 }; +static CVI_U8 data_ili9881c_38[] = { 0x26, 0x00 }; +static CVI_U8 data_ili9881c_39[] = { 0x27, 0x00 }; +static CVI_U8 data_ili9881c_40[] = { 0x28, 0x33 }; +static CVI_U8 data_ili9881c_41[] = { 0x29, 0x03 }; +static CVI_U8 data_ili9881c_42[] = { 0x2a, 0x00 }; +static CVI_U8 data_ili9881c_43[] = { 0x2b, 0x00 }; +static CVI_U8 data_ili9881c_44[] = { 0x2c, 0x00 }; +static CVI_U8 data_ili9881c_45[] = { 0x2d, 0x00 }; +static CVI_U8 data_ili9881c_46[] = { 0x2e, 0x00 }; +static CVI_U8 data_ili9881c_47[] = { 0x2f, 0x00 }; +static CVI_U8 data_ili9881c_48[] = { 0x30, 0x00 }; +static CVI_U8 data_ili9881c_49[] = { 0x31, 0x00 }; +static CVI_U8 data_ili9881c_50[] = { 0x32, 0x00 }; +static CVI_U8 data_ili9881c_51[] = { 0x33, 0x00 }; +static CVI_U8 data_ili9881c_52[] = { 0x34, 0x04 }; +static CVI_U8 data_ili9881c_53[] = { 0x35, 0x00 }; +static CVI_U8 data_ili9881c_54[] = { 0x36, 0x00 }; +static CVI_U8 data_ili9881c_55[] = { 0x37, 0x00 }; +static CVI_U8 data_ili9881c_56[] = { 0x38, 0x3c }; +static CVI_U8 data_ili9881c_57[] = { 0x39, 0x00 }; +static CVI_U8 data_ili9881c_58[] = { 0x3a, 0x40 }; +static CVI_U8 data_ili9881c_59[] = { 0x3b, 0x40 }; +static CVI_U8 data_ili9881c_60[] = { 0x3c, 0x00 }; +static CVI_U8 data_ili9881c_61[] = { 0x3d, 0x00 }; +static CVI_U8 data_ili9881c_62[] = { 0x3e, 0x00 }; +static CVI_U8 data_ili9881c_63[] = { 0x3f, 0x00 }; +static CVI_U8 data_ili9881c_64[] = { 0x40, 0x00 }; +static CVI_U8 data_ili9881c_65[] = { 0x41, 0x00 }; +static CVI_U8 data_ili9881c_66[] = { 0x42, 0x00 }; +static CVI_U8 data_ili9881c_67[] = { 0x43, 0x00 }; +static CVI_U8 data_ili9881c_68[] = { 0x44, 0x00 }; +static CVI_U8 data_ili9881c_69[] = { 0x50, 0x01 }; +static CVI_U8 data_ili9881c_70[] = { 0x51, 0x23 }; +static CVI_U8 data_ili9881c_71[] = { 0x52, 0x45 }; +static CVI_U8 data_ili9881c_72[] = { 0x53, 0x67 }; +static CVI_U8 data_ili9881c_73[] = { 0x54, 0x89 }; +static CVI_U8 data_ili9881c_74[] = { 0x55, 0xab }; +static CVI_U8 data_ili9881c_75[] = { 0x56, 0x01 }; +static CVI_U8 data_ili9881c_76[] = { 0x57, 0x23 }; +static CVI_U8 data_ili9881c_77[] = { 0x58, 0x45 }; +static CVI_U8 data_ili9881c_78[] = { 0x59, 0x67 }; +static CVI_U8 data_ili9881c_79[] = { 0x5a, 0x89 }; +static CVI_U8 data_ili9881c_80[] = { 0x5b, 0xab }; +static CVI_U8 data_ili9881c_81[] = { 0x5c, 0xcd }; +static CVI_U8 data_ili9881c_82[] = { 0x5d, 0xef }; +static CVI_U8 data_ili9881c_83[] = { 0x5e, 0x11 }; +static CVI_U8 data_ili9881c_84[] = { 0x5f, 0x01 }; +static CVI_U8 data_ili9881c_85[] = { 0x60, 0x00 }; +static CVI_U8 data_ili9881c_86[] = { 0x61, 0x15 }; +static CVI_U8 data_ili9881c_87[] = { 0x62, 0x14 }; +static CVI_U8 data_ili9881c_88[] = { 0x63, 0x0e }; +static CVI_U8 data_ili9881c_89[] = { 0x64, 0x0f }; +static CVI_U8 data_ili9881c_90[] = { 0x65, 0x0c }; +static CVI_U8 data_ili9881c_91[] = { 0x66, 0x0d }; +static CVI_U8 data_ili9881c_92[] = { 0x67, 0x06 }; +static CVI_U8 data_ili9881c_93[] = { 0x68, 0x02 }; +static CVI_U8 data_ili9881c_94[] = { 0x69, 0x07 }; +static CVI_U8 data_ili9881c_95[] = { 0x6a, 0x02 }; +static CVI_U8 data_ili9881c_96[] = { 0x6b, 0x02 }; +static CVI_U8 data_ili9881c_97[] = { 0x6c, 0x02 }; +static CVI_U8 data_ili9881c_98[] = { 0x6d, 0x02 }; +static CVI_U8 data_ili9881c_99[] = { 0x6e, 0x02 }; +static CVI_U8 data_ili9881c_100[] = { 0x6f, 0x02 }; +static CVI_U8 data_ili9881c_101[] = { 0x70, 0x02 }; +static CVI_U8 data_ili9881c_102[] = { 0x71, 0x02 }; +static CVI_U8 data_ili9881c_103[] = { 0x72, 0x02 }; +static CVI_U8 data_ili9881c_104[] = { 0x73, 0x02 }; +static CVI_U8 data_ili9881c_105[] = { 0x74, 0x02 }; +static CVI_U8 data_ili9881c_106[] = { 0x75, 0x01 }; +static CVI_U8 data_ili9881c_107[] = { 0x76, 0x00 }; +static CVI_U8 data_ili9881c_108[] = { 0x77, 0x14 }; +static CVI_U8 data_ili9881c_109[] = { 0x78, 0x15 }; +static CVI_U8 data_ili9881c_110[] = { 0x79, 0x0e }; +static CVI_U8 data_ili9881c_111[] = { 0x7a, 0x0f }; +static CVI_U8 data_ili9881c_112[] = { 0x7b, 0x0c }; +static CVI_U8 data_ili9881c_113[] = { 0x7c, 0x0d }; +static CVI_U8 data_ili9881c_114[] = { 0x7d, 0x06 }; +static CVI_U8 data_ili9881c_115[] = { 0x7e, 0x02 }; +static CVI_U8 data_ili9881c_116[] = { 0x7f, 0x07 }; +static CVI_U8 data_ili9881c_117[] = { 0x80, 0x02 }; +static CVI_U8 data_ili9881c_118[] = { 0x81, 0x02 }; +static CVI_U8 data_ili9881c_119[] = { 0x82, 0x02 }; +static CVI_U8 data_ili9881c_120[] = { 0x83, 0x02 }; +static CVI_U8 data_ili9881c_121[] = { 0x84, 0x02 }; +static CVI_U8 data_ili9881c_122[] = { 0x85, 0x02 }; +static CVI_U8 data_ili9881c_123[] = { 0x86, 0x02 }; +static CVI_U8 data_ili9881c_124[] = { 0x87, 0x02 }; +static CVI_U8 data_ili9881c_125[] = { 0x88, 0x02 }; +static CVI_U8 data_ili9881c_126[] = { 0x89, 0x02 }; +static CVI_U8 data_ili9881c_127[] = { 0x8a, 0x02 }; +static CVI_U8 data_ili9881c_128[] = { 0xff, 0x98, 0x81, 0x04 }; +static CVI_U8 data_ili9881c_129[] = { 0x6c, 0x15 }; +static CVI_U8 data_ili9881c_130[] = { 0x6e, 0x2b }; +static CVI_U8 data_ili9881c_131[] = { 0x6f, 0x33 }; +static CVI_U8 data_ili9881c_132[] = { 0x8d, 0x18 }; +static CVI_U8 data_ili9881c_133[] = { 0x87, 0xba }; +static CVI_U8 data_ili9881c_134[] = { 0x26, 0x76 }; +static CVI_U8 data_ili9881c_135[] = { 0xb2, 0xd1 }; +static CVI_U8 data_ili9881c_136[] = { 0xb5, 0x06 }; +static CVI_U8 data_ili9881c_137[] = { 0x3a, 0x24 }; +static CVI_U8 data_ili9881c_138[] = { 0x35, 0x1f }; +static CVI_U8 data_ili9881c_139[] = { 0xff, 0x98, 0x81, 0x01 }; +static CVI_U8 data_ili9881c_140[] = { 0x22, 0x09 }; +static CVI_U8 data_ili9881c_141[] = { 0x31, 0x00 }; +static CVI_U8 data_ili9881c_142[] = { 0x40, 0x33 }; +static CVI_U8 data_ili9881c_143[] = { 0x53, 0xa2 }; +static CVI_U8 data_ili9881c_144[] = { 0x55, 0x92 }; +static CVI_U8 data_ili9881c_145[] = { 0x50, 0x96 }; +static CVI_U8 data_ili9881c_146[] = { 0x51, 0x96 }; +static CVI_U8 data_ili9881c_147[] = { 0x60, 0x22 }; +static CVI_U8 data_ili9881c_148[] = { 0x61, 0x00 }; +static CVI_U8 data_ili9881c_149[] = { 0x62, 0x19 }; +static CVI_U8 data_ili9881c_150[] = { 0x63, 0x00 }; +static CVI_U8 data_ili9881c_151[] = { 0xa0, 0x08 }; +static CVI_U8 data_ili9881c_152[] = { 0xa1, 0x11 }; +static CVI_U8 data_ili9881c_153[] = { 0xa2, 0x19 }; +static CVI_U8 data_ili9881c_154[] = { 0xa3, 0x0d }; +static CVI_U8 data_ili9881c_155[] = { 0xa4, 0x0d }; +static CVI_U8 data_ili9881c_156[] = { 0xa5, 0x1e }; +static CVI_U8 data_ili9881c_157[] = { 0xa6, 0x14 }; +static CVI_U8 data_ili9881c_158[] = { 0xa7, 0x17 }; +static CVI_U8 data_ili9881c_159[] = { 0xa8, 0x4f }; +static CVI_U8 data_ili9881c_160[] = { 0xa9, 0x1a }; +static CVI_U8 data_ili9881c_161[] = { 0xaa, 0x27 }; +static CVI_U8 data_ili9881c_162[] = { 0xab, 0x49 }; +static CVI_U8 data_ili9881c_163[] = { 0xac, 0x1a }; +static CVI_U8 data_ili9881c_164[] = { 0xad, 0x18 }; +static CVI_U8 data_ili9881c_165[] = { 0xae, 0x4c }; +static CVI_U8 data_ili9881c_166[] = { 0xaf, 0x22 }; +static CVI_U8 data_ili9881c_167[] = { 0xb0, 0x27 }; +static CVI_U8 data_ili9881c_168[] = { 0xb1, 0x4b }; +static CVI_U8 data_ili9881c_169[] = { 0xb2, 0x60 }; +static CVI_U8 data_ili9881c_170[] = { 0xb3, 0x39 }; +static CVI_U8 data_ili9881c_171[] = { 0xc0, 0x08 }; +static CVI_U8 data_ili9881c_172[] = { 0xc1, 0x11 }; +static CVI_U8 data_ili9881c_173[] = { 0xc2, 0x19 }; +static CVI_U8 data_ili9881c_174[] = { 0xc3, 0x0d }; +static CVI_U8 data_ili9881c_175[] = { 0xc4, 0x0d }; +static CVI_U8 data_ili9881c_176[] = { 0xc5, 0x1e }; +static CVI_U8 data_ili9881c_177[] = { 0xc6, 0x14 }; +static CVI_U8 data_ili9881c_178[] = { 0xc7, 0x17 }; +static CVI_U8 data_ili9881c_179[] = { 0xc8, 0x4f }; +static CVI_U8 data_ili9881c_180[] = { 0xc9, 0x1a }; +static CVI_U8 data_ili9881c_181[] = { 0xca, 0x27 }; +static CVI_U8 data_ili9881c_182[] = { 0xcb, 0x49 }; +static CVI_U8 data_ili9881c_183[] = { 0xcc, 0x1a }; +static CVI_U8 data_ili9881c_184[] = { 0xcd, 0x18 }; +static CVI_U8 data_ili9881c_185[] = { 0xce, 0x4c }; +static CVI_U8 data_ili9881c_186[] = { 0xcf, 0x33 }; +static CVI_U8 data_ili9881c_187[] = { 0xd0, 0x27 }; +static CVI_U8 data_ili9881c_188[] = { 0xd1, 0x4b }; +static CVI_U8 data_ili9881c_189[] = { 0xd2, 0x60 }; +static CVI_U8 data_ili9881c_190[] = { 0xd3, 0x39 }; +static CVI_U8 data_ili9881c_191[] = { 0xff, 0x98, 0x81, 0x00 }; +static CVI_U8 data_ili9881c_192[] = { 0x36 }; +static CVI_U8 data_ili9881c_193[] = { 0x35 }; +static CVI_U8 data_ili9881c_194[] = { 0x11 }; +static CVI_U8 data_ili9881c_195[] = { 0x29 }; + +const struct dsc_instr dsi_init_cmds_ili9881c_720x1280[] = { + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881c_0 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_1 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_2 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_3 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_4 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_5 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_6 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_7 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_8 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_11 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_16 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_17 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_18 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_19 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_20 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_21 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_22 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_23 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_24 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_25 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_26 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_27 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_28 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_29 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_30 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_31 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_32 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_33 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_34 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_35 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_36 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_37 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_38 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_39 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_40 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_41 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_42 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_43 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_44 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_45 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_46 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_47 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_48 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_49 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_50 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_51 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_52 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_53 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_54 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_55 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_56 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_57 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_58 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_59 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_60 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_61 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_62 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_63 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_64 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_65 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_66 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_67 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_68 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_69 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_70 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_71 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_72 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_73 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_74 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_75 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_76 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_77 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_78 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_79 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_80 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_81 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_82 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_83 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_84 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_85 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_86 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_87 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_88 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_89 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_90 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_91 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_92 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_93 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_94 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_95 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_96 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_97 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_98 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_99 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_100 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_101 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_102 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_103 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_104 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_105 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_106 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_107 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_108 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_109 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_110 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_111 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_112 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_113 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_114 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_115 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_116 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_117 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_118 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_119 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_120 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_121 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_122 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_123 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_124 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_125 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_126 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_127 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881c_128 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_129 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_130 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_131 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_132 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_133 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_134 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_135 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_136 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_137 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_138 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881c_139 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_140 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_141 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_142 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_143 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_144 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_145 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_146 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_147 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_148 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_149 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_150 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_151 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_152 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_153 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_154 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_155 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_156 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_157 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_158 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_159 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_160 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_161 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_162 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_163 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_164 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_165 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_166 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_167 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_168 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_169 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_170 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_171 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_172 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_173 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_174 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_175 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_176 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_177 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_178 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_179 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_180 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_181 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_182 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_183 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_184 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_185 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_186 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_187 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_188 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_189 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_190 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881c_191 }, + {.delay = 0, .data_type = 0x05, .size = 1, .data = data_ili9881c_192 }, + {.delay = 0, .data_type = 0x05, .size = 1, .data = data_ili9881c_193 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_ili9881c_194 }, + {.delay = 20, .data_type = 0x05, .size = 1, .data = data_ili9881c_195 } +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_ILI9881C_H_ diff --git a/middleware/v2/component/panel/cv180x/dsi_ili9881d.h b/middleware/v2/component/panel/cv180x/dsi_ili9881d.h new file mode 100644 index 000000000..1b0b68a37 --- /dev/null +++ b/middleware/v2/component/panel/cv180x/dsi_ili9881d.h @@ -0,0 +1,418 @@ +#ifndef _MIPI_TX_PARAM_ILI9881D_H_ +#define _MIPI_TX_PARAM_ILI9881D_H_ + +#include +#include + +const struct combo_dev_cfg_s dev_cfg_ili9881d_720x1280 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_2, MIPI_TX_LANE_CLK, MIPI_TX_LANE_3}, + .lane_pn_swap = {false, false, false, false, false}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = 60, + .vid_hbp_pixels = 60, + .vid_hfp_pixels = 140, + .vid_hline_pixels = 720, + .vid_vsa_lines = 16, + .vid_vbp_lines = 24, + .vid_vfp_lines = 8, + .vid_active_lines = 1280, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 70118, +}; + +const struct hs_settle_s hs_timing_cfg_ili9881d_720x1280 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_ili9881d_0[] = { 0xff, 0x98, 0x81, 0x01 }; +static CVI_U8 data_ili9881d_1[] = { 0x91, 0x00 }; +static CVI_U8 data_ili9881d_2[] = { 0x92, 0x00 }; +static CVI_U8 data_ili9881d_3[] = { 0x93, 0x72 }; +static CVI_U8 data_ili9881d_4[] = { 0x94, 0x00 }; +static CVI_U8 data_ili9881d_5[] = { 0x95, 0x00 }; +static CVI_U8 data_ili9881d_6[] = { 0x96, 0x09 }; +static CVI_U8 data_ili9881d_7[] = { 0x97, 0x00 }; +static CVI_U8 data_ili9881d_8[] = { 0x98, 0x00 }; +static CVI_U8 data_ili9881d_9[] = { 0x09, 0x01 }; +static CVI_U8 data_ili9881d_10[] = { 0x0a, 0x00 }; +static CVI_U8 data_ili9881d_11[] = { 0x0b, 0x00 }; +static CVI_U8 data_ili9881d_12[] = { 0x0c, 0x01 }; +static CVI_U8 data_ili9881d_13[] = { 0x0d, 0x00 }; +static CVI_U8 data_ili9881d_14[] = { 0x0e, 0x00 }; +static CVI_U8 data_ili9881d_15[] = { 0x0f, 0x00 }; +static CVI_U8 data_ili9881d_16[] = { 0x10, 0x00 }; +static CVI_U8 data_ili9881d_17[] = { 0x11, 0x00 }; +static CVI_U8 data_ili9881d_18[] = { 0x12, 0x00 }; +static CVI_U8 data_ili9881d_19[] = { 0x13, 0x00 }; +static CVI_U8 data_ili9881d_20[] = { 0x14, 0x00 }; +static CVI_U8 data_ili9881d_21[] = { 0x15, 0x00 }; +static CVI_U8 data_ili9881d_22[] = { 0x16, 0x00 }; +static CVI_U8 data_ili9881d_23[] = { 0x17, 0x00 }; +static CVI_U8 data_ili9881d_24[] = { 0x18, 0x00 }; +static CVI_U8 data_ili9881d_25[] = { 0x19, 0x00 }; +static CVI_U8 data_ili9881d_26[] = { 0x1a, 0x00 }; +static CVI_U8 data_ili9881d_27[] = { 0x1b, 0x00 }; +static CVI_U8 data_ili9881d_28[] = { 0x1c, 0x00 }; +static CVI_U8 data_ili9881d_29[] = { 0x1d, 0x00 }; +static CVI_U8 data_ili9881d_30[] = { 0x1e, 0xc0 }; +static CVI_U8 data_ili9881d_31[] = { 0x1f, 0x40 }; +static CVI_U8 data_ili9881d_32[] = { 0x20, 0x05 }; +static CVI_U8 data_ili9881d_33[] = { 0x21, 0x02 }; +static CVI_U8 data_ili9881d_34[] = { 0x22, 0x00 }; +static CVI_U8 data_ili9881d_35[] = { 0x23, 0x00 }; +static CVI_U8 data_ili9881d_36[] = { 0x24, 0x00 }; +static CVI_U8 data_ili9881d_37[] = { 0x25, 0x00 }; +static CVI_U8 data_ili9881d_38[] = { 0x26, 0x00 }; +static CVI_U8 data_ili9881d_39[] = { 0x27, 0x00 }; +static CVI_U8 data_ili9881d_40[] = { 0x28, 0x33 }; +static CVI_U8 data_ili9881d_41[] = { 0x29, 0x02 }; +static CVI_U8 data_ili9881d_42[] = { 0x2a, 0x00 }; +static CVI_U8 data_ili9881d_43[] = { 0x2b, 0x00 }; +static CVI_U8 data_ili9881d_44[] = { 0x2c, 0x00 }; +static CVI_U8 data_ili9881d_45[] = { 0x2d, 0x00 }; +static CVI_U8 data_ili9881d_46[] = { 0x2e, 0x00 }; +static CVI_U8 data_ili9881d_47[] = { 0x2f, 0x00 }; +static CVI_U8 data_ili9881d_48[] = { 0x30, 0x00 }; +static CVI_U8 data_ili9881d_49[] = { 0x31, 0x00 }; +static CVI_U8 data_ili9881d_50[] = { 0x32, 0x00 }; +static CVI_U8 data_ili9881d_51[] = { 0x33, 0x00 }; +static CVI_U8 data_ili9881d_52[] = { 0x34, 0x04 }; +static CVI_U8 data_ili9881d_53[] = { 0x35, 0x00 }; +static CVI_U8 data_ili9881d_54[] = { 0x36, 0x00 }; +static CVI_U8 data_ili9881d_55[] = { 0x37, 0x00 }; +static CVI_U8 data_ili9881d_56[] = { 0x38, 0x3c }; +static CVI_U8 data_ili9881d_57[] = { 0x39, 0x07 }; +static CVI_U8 data_ili9881d_58[] = { 0x3a, 0x00 }; +static CVI_U8 data_ili9881d_59[] = { 0x3b, 0x00 }; +static CVI_U8 data_ili9881d_60[] = { 0x3c, 0x00 }; +static CVI_U8 data_ili9881d_61[] = { 0x40, 0x03 }; +static CVI_U8 data_ili9881d_62[] = { 0x41, 0x20 }; +static CVI_U8 data_ili9881d_63[] = { 0x42, 0x00 }; +static CVI_U8 data_ili9881d_64[] = { 0x43, 0x40 }; +static CVI_U8 data_ili9881d_65[] = { 0x44, 0x03 }; +static CVI_U8 data_ili9881d_66[] = { 0x45, 0x00 }; +static CVI_U8 data_ili9881d_67[] = { 0x46, 0x01 }; +static CVI_U8 data_ili9881d_68[] = { 0x47, 0x08 }; +static CVI_U8 data_ili9881d_69[] = { 0x48, 0x00 }; +static CVI_U8 data_ili9881d_70[] = { 0x49, 0x00 }; +static CVI_U8 data_ili9881d_71[] = { 0x4a, 0x00 }; +static CVI_U8 data_ili9881d_72[] = { 0x4b, 0x00 }; +static CVI_U8 data_ili9881d_73[] = { 0x4c, 0x01 }; +static CVI_U8 data_ili9881d_74[] = { 0x4d, 0x45 }; +static CVI_U8 data_ili9881d_75[] = { 0x4e, 0x9b }; +static CVI_U8 data_ili9881d_76[] = { 0x4f, 0x57 }; +static CVI_U8 data_ili9881d_77[] = { 0x50, 0x29 }; +static CVI_U8 data_ili9881d_78[] = { 0x51, 0x27 }; +static CVI_U8 data_ili9881d_79[] = { 0x52, 0x22 }; +static CVI_U8 data_ili9881d_80[] = { 0x53, 0x22 }; +static CVI_U8 data_ili9881d_81[] = { 0x54, 0x22 }; +static CVI_U8 data_ili9881d_82[] = { 0x55, 0x22 }; +static CVI_U8 data_ili9881d_83[] = { 0x56, 0x22 }; +static CVI_U8 data_ili9881d_84[] = { 0x57, 0x01 }; +static CVI_U8 data_ili9881d_85[] = { 0x58, 0x45 }; +static CVI_U8 data_ili9881d_86[] = { 0x59, 0x8a }; +static CVI_U8 data_ili9881d_87[] = { 0x5a, 0x46 }; +static CVI_U8 data_ili9881d_88[] = { 0x5b, 0x28 }; +static CVI_U8 data_ili9881d_89[] = { 0x5c, 0x26 }; +static CVI_U8 data_ili9881d_90[] = { 0x5d, 0x22 }; +static CVI_U8 data_ili9881d_91[] = { 0x5e, 0x22 }; +static CVI_U8 data_ili9881d_92[] = { 0x5f, 0x22 }; +static CVI_U8 data_ili9881d_93[] = { 0x60, 0x22 }; +static CVI_U8 data_ili9881d_94[] = { 0x61, 0x22 }; +static CVI_U8 data_ili9881d_95[] = { 0x62, 0x06 }; +static CVI_U8 data_ili9881d_96[] = { 0x63, 0x01 }; +static CVI_U8 data_ili9881d_97[] = { 0x64, 0x00 }; +static CVI_U8 data_ili9881d_98[] = { 0x65, 0xa4 }; +static CVI_U8 data_ili9881d_99[] = { 0x66, 0xa5 }; +static CVI_U8 data_ili9881d_100[] = { 0x67, 0x58 }; +static CVI_U8 data_ili9881d_101[] = { 0x68, 0x5a }; +static CVI_U8 data_ili9881d_102[] = { 0x69, 0x54 }; +static CVI_U8 data_ili9881d_103[] = { 0x6a, 0x56 }; +static CVI_U8 data_ili9881d_104[] = { 0x6b, 0x06 }; +static CVI_U8 data_ili9881d_105[] = { 0x6c, 0x02 }; +static CVI_U8 data_ili9881d_106[] = { 0x6d, 0x08 }; +static CVI_U8 data_ili9881d_107[] = { 0x6e, 0x02 }; +static CVI_U8 data_ili9881d_108[] = { 0x6f, 0x02 }; +static CVI_U8 data_ili9881d_109[] = { 0x70, 0x02 }; +static CVI_U8 data_ili9881d_110[] = { 0x71, 0x02 }; +static CVI_U8 data_ili9881d_111[] = { 0x72, 0x02 }; +static CVI_U8 data_ili9881d_112[] = { 0x73, 0x02 }; +static CVI_U8 data_ili9881d_113[] = { 0x74, 0x02 }; +static CVI_U8 data_ili9881d_114[] = { 0x75, 0x02 }; +static CVI_U8 data_ili9881d_115[] = { 0x76, 0x02 }; +static CVI_U8 data_ili9881d_116[] = { 0x77, 0x02 }; +static CVI_U8 data_ili9881d_117[] = { 0x78, 0x02 }; +static CVI_U8 data_ili9881d_118[] = { 0x79, 0x01 }; +static CVI_U8 data_ili9881d_119[] = { 0x7a, 0x00 }; +static CVI_U8 data_ili9881d_120[] = { 0x7b, 0xa4 }; +static CVI_U8 data_ili9881d_121[] = { 0x7c, 0xa5 }; +static CVI_U8 data_ili9881d_122[] = { 0x7d, 0x59 }; +static CVI_U8 data_ili9881d_123[] = { 0x7e, 0x5b }; +static CVI_U8 data_ili9881d_124[] = { 0x7f, 0x55 }; +static CVI_U8 data_ili9881d_125[] = { 0x80, 0x57 }; +static CVI_U8 data_ili9881d_126[] = { 0x81, 0x07 }; +static CVI_U8 data_ili9881d_127[] = { 0x82, 0x02 }; +static CVI_U8 data_ili9881d_128[] = { 0x83, 0x09 }; +static CVI_U8 data_ili9881d_129[] = { 0x84, 0x02 }; +static CVI_U8 data_ili9881d_130[] = { 0x85, 0x02 }; +static CVI_U8 data_ili9881d_131[] = { 0x86, 0x02 }; +static CVI_U8 data_ili9881d_132[] = { 0x87, 0x02 }; +static CVI_U8 data_ili9881d_133[] = { 0x88, 0x02 }; +static CVI_U8 data_ili9881d_134[] = { 0x89, 0x02 }; +static CVI_U8 data_ili9881d_135[] = { 0x8a, 0x02 }; +static CVI_U8 data_ili9881d_136[] = { 0x8b, 0x02 }; +static CVI_U8 data_ili9881d_137[] = { 0x8c, 0x02 }; +static CVI_U8 data_ili9881d_138[] = { 0x8d, 0x02 }; +static CVI_U8 data_ili9881d_139[] = { 0x8e, 0x02 }; +static CVI_U8 data_ili9881d_140[] = { 0xa0, 0x35 }; +static CVI_U8 data_ili9881d_141[] = { 0xa1, 0x00 }; +static CVI_U8 data_ili9881d_142[] = { 0xa2, 0x00 }; +static CVI_U8 data_ili9881d_143[] = { 0xa3, 0x00 }; +static CVI_U8 data_ili9881d_144[] = { 0xa4, 0x00 }; +static CVI_U8 data_ili9881d_145[] = { 0xa5, 0x00 }; +static CVI_U8 data_ili9881d_146[] = { 0xa6, 0x00 }; +static CVI_U8 data_ili9881d_147[] = { 0xa7, 0x00 }; +static CVI_U8 data_ili9881d_148[] = { 0xa8, 0x00 }; +static CVI_U8 data_ili9881d_149[] = { 0xa9, 0x00 }; +static CVI_U8 data_ili9881d_150[] = { 0xaa, 0x00 }; +static CVI_U8 data_ili9881d_151[] = { 0xab, 0x00 }; +static CVI_U8 data_ili9881d_152[] = { 0xac, 0x00 }; +static CVI_U8 data_ili9881d_153[] = { 0xad, 0x00 }; +static CVI_U8 data_ili9881d_154[] = { 0xae, 0xff }; +static CVI_U8 data_ili9881d_155[] = { 0xaf, 0x00 }; +static CVI_U8 data_ili9881d_156[] = { 0xb0, 0x00 }; +static CVI_U8 data_ili9881d_157[] = { 0xff, 0x98, 0x81, 0x02 }; +static CVI_U8 data_ili9881d_158[] = { + 0xa0, 0x00, 0x0e, 0x1a, 0x11, 0x13, 0x25, 0x19, 0x1c, 0x6b, + 0x1b, 0x28, 0x66, 0x1b, 0x19, 0x4d, 0x22, 0x27, 0x53, 0x63, + 0x2e +}; +static CVI_U8 data_ili9881d_159[] = { + 0xc0, 0x00, 0x0e, 0x1a, 0x11, 0x13, 0x25, 0x19, 0x1c, 0x6b, + 0x1b, 0x28, 0x66, 0x1b, 0x19, 0x4d, 0x22, 0x27, 0x53, 0x63, + 0x2e +}; +//================GIP code finish ================// +static CVI_U8 data_ili9881d_160[] = { 0x18, 0xf4 }; +static CVI_U8 data_ili9881d_161[] = { 0xff, 0x98, 0x81, 0x04 }; +static CVI_U8 data_ili9881d_162[] = { 0x5d, 0x8b }; +static CVI_U8 data_ili9881d_163[] = { 0x5e, 0x8b }; +static CVI_U8 data_ili9881d_164[] = { 0x60, 0x68 }; +static CVI_U8 data_ili9881d_165[] = { 0x62, 0x52 }; +static CVI_U8 data_ili9881d_166[] = { 0x82, 0x38 }; +static CVI_U8 data_ili9881d_167[] = { 0x84, 0x38 }; +static CVI_U8 data_ili9881d_168[] = { 0x86, 0x1c }; +static CVI_U8 data_ili9881d_169[] = { 0x66, 0x04 }; +static CVI_U8 data_ili9881d_170[] = { 0xc1, 0x70 }; +static CVI_U8 data_ili9881d_171[] = { 0x70, 0x60 }; +static CVI_U8 data_ili9881d_172[] = { 0x71, 0x00 }; +static CVI_U8 data_ili9881d_173[] = { 0x5b, 0x33 }; +static CVI_U8 data_ili9881d_174[] = { 0x6c, 0x10 }; +static CVI_U8 data_ili9881d_175[] = { 0x77, 0x03 }; +static CVI_U8 data_ili9881d_176[] = { 0x7b, 0x02 }; +static CVI_U8 data_ili9881d_177[] = { 0xff, 0x98, 0x81, 0x01 }; +static CVI_U8 data_ili9881d_178[] = { 0xf0, 0x00 }; +static CVI_U8 data_ili9881d_179[] = { 0xf1, 0xc8 }; +static CVI_U8 data_ili9881d_180[] = { 0xff, 0x98, 0x81, 0x05 }; +static CVI_U8 data_ili9881d_181[] = { 0x22, 0x3a }; +static CVI_U8 data_ili9881d_182[] = { 0xff, 0x98, 0x81, 0x00 }; +static CVI_U8 data_ili9881d_183[] = { 0x35, 0x00 }; +static CVI_U8 data_ili9881d_184[] = { 0x11, 0x00 }; +static CVI_U8 data_ili9881d_185[] = { 0x29, 0x00 }; + +const struct dsc_instr dsi_init_cmds_ili9881d_720x1280[] = { + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881d_0 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_1 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_2 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_3 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_4 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_5 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_6 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_7 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_8 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_11 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_16 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_17 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_18 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_19 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_20 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_21 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_22 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_23 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_24 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_25 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_26 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_27 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_28 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_29 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_30 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_31 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_32 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_33 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_34 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_35 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_36 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_37 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_38 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_39 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_40 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_41 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_42 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_43 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_44 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_45 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_46 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_47 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_48 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_49 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_50 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_51 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_52 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_53 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_54 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_55 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_56 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_57 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_58 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_59 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_60 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_61 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_62 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_63 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_64 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_65 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_66 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_67 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_68 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_69 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_70 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_71 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_72 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_73 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_74 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_75 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_76 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_77 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_78 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_79 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_80 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_81 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_82 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_83 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_84 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_85 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_86 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_87 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_88 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_89 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_90 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_91 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_92 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_93 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_94 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_95 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_96 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_97 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_98 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_99 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_100 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_101 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_102 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_103 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_104 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_105 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_106 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_107 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_108 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_109 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_110 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_111 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_112 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_113 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_114 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_115 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_116 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_117 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_118 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_119 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_120 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_121 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_122 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_123 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_124 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_125 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_126 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_127 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_128 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_129 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_130 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_131 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_132 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_133 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_134 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_135 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_136 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_137 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_138 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_139 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_140 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_141 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_142 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_143 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_144 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_145 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_146 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_147 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_148 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_149 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_150 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_151 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_152 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_153 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_154 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_155 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_156 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881d_157 }, + {.delay = 0, .data_type = 0x29, .size = 21, .data = data_ili9881d_158 }, + {.delay = 0, .data_type = 0x29, .size = 21, .data = data_ili9881d_159 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_160 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881d_161 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_162 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_163 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_164 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_165 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_166 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_167 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_168 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_169 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_170 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_171 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_172 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_173 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_174 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_175 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_176 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881d_177 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_178 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_179 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881d_180 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_181 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881d_182 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_183 }, + {.delay = 120, .data_type = 0x15, .size = 2, .data = data_ili9881d_184 }, + {.delay = 20, .data_type = 0x15, .size = 2, .data = data_ili9881d_185 } +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_ILI9881D_H_ diff --git a/middleware/v2/component/panel/cv180x/dsi_jd9366ab.h b/middleware/v2/component/panel/cv180x/dsi_jd9366ab.h new file mode 100644 index 000000000..f284f738c --- /dev/null +++ b/middleware/v2/component/panel/cv180x/dsi_jd9366ab.h @@ -0,0 +1,394 @@ +#ifndef _MIPI_TX_PARAM_JD9366AB_H_ +#define _MIPI_TX_PARAM_JD9366AB_H_ + +#include +#include + +const struct combo_dev_cfg_s dev_cfg_jd9366ab_800x1280 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, MIPI_TX_LANE_3, MIPI_TX_LANE_2}, + .lane_pn_swap = {true, true, true, true, true}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = 6, + .vid_hbp_pixels = 40, + .vid_hfp_pixels = 112, + .vid_hline_pixels = 800, + .vid_vsa_lines = 4, + .vid_vbp_lines = 15, + .vid_vfp_lines = 21, + .vid_active_lines = 1280, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = false, + }, + .pixel_clk = 70000, +}; + +const struct hs_settle_s hs_timing_cfg_jd9366ab_800x1280 = { .prepare = 6, .zero = 16, .trail = 1 }; + +static CVI_U8 data_jd9366ab_0[] = { 0xe0, 0x00 }; +static CVI_U8 data_jd9366ab_1[] = { 0xe1, 0x93 }; +static CVI_U8 data_jd9366ab_2[] = { 0xe2, 0x65 }; +static CVI_U8 data_jd9366ab_3[] = { 0xe3, 0xf8 }; +static CVI_U8 data_jd9366ab_4[] = { 0x80, 0x03 }; +static CVI_U8 data_jd9366ab_5[] = { 0xe0, 0x04 }; +static CVI_U8 data_jd9366ab_6[] = { 0x2d, 0x03 }; +static CVI_U8 data_jd9366ab_7[] = { 0xe0, 0x01 }; +static CVI_U8 data_jd9366ab_8[] = { 0x00, 0x00 }; +static CVI_U8 data_jd9366ab_9[] = { 0x01, 0xb7 }; +static CVI_U8 data_jd9366ab_10[] = { 0x17, 0x00 }; +static CVI_U8 data_jd9366ab_11[] = { 0x18, 0xcf }; +static CVI_U8 data_jd9366ab_12[] = { 0x19, 0x01 }; +static CVI_U8 data_jd9366ab_13[] = { 0x1a, 0x00 }; +static CVI_U8 data_jd9366ab_14[] = { 0x1b, 0xcf }; +static CVI_U8 data_jd9366ab_15[] = { 0x1c, 0x01 }; +static CVI_U8 data_jd9366ab_16[] = { 0x1f, 0x3e }; +static CVI_U8 data_jd9366ab_17[] = { 0x20, 0x28 }; +static CVI_U8 data_jd9366ab_18[] = { 0x21, 0x28 }; +static CVI_U8 data_jd9366ab_19[] = { 0x22, 0x0e }; +static CVI_U8 data_jd9366ab_20[] = { 0x24, 0xc8 }; +static CVI_U8 data_jd9366ab_21[] = { 0x26, 0xf1 }; +static CVI_U8 data_jd9366ab_22[] = { 0x37, 0x29 }; +static CVI_U8 data_jd9366ab_23[] = { 0x38, 0x05 }; +static CVI_U8 data_jd9366ab_24[] = { 0x39, 0x08 }; +static CVI_U8 data_jd9366ab_25[] = { 0x3a, 0x12 }; +static CVI_U8 data_jd9366ab_26[] = { 0x3c, 0x78 }; +static CVI_U8 data_jd9366ab_27[] = { 0x3d, 0xff }; +static CVI_U8 data_jd9366ab_28[] = { 0x3e, 0xff }; +static CVI_U8 data_jd9366ab_29[] = { 0x3f, 0xff }; +static CVI_U8 data_jd9366ab_30[] = { 0x40, 0x06 }; +static CVI_U8 data_jd9366ab_31[] = { 0x41, 0xa0 }; +static CVI_U8 data_jd9366ab_32[] = { 0x43, 0x15 }; +static CVI_U8 data_jd9366ab_33[] = { 0x44, 0x12 }; +static CVI_U8 data_jd9366ab_34[] = { 0x45, 0x50 }; +static CVI_U8 data_jd9366ab_35[] = { 0x4b, 0x04 }; +static CVI_U8 data_jd9366ab_36[] = { 0x55, 0x0f }; +static CVI_U8 data_jd9366ab_37[] = { 0x56, 0x01 }; +static CVI_U8 data_jd9366ab_38[] = { 0x57, 0x89 }; +static CVI_U8 data_jd9366ab_39[] = { 0x58, 0x0a }; +static CVI_U8 data_jd9366ab_40[] = { 0x59, 0x2a }; +static CVI_U8 data_jd9366ab_41[] = { 0x5a, 0x31 }; +static CVI_U8 data_jd9366ab_42[] = { 0x5b, 0x15 }; +static CVI_U8 data_jd9366ab_43[] = { 0x5d, 0x7c }; +static CVI_U8 data_jd9366ab_44[] = { 0x5e, 0x50 }; +static CVI_U8 data_jd9366ab_45[] = { 0x5f, 0x3b }; +static CVI_U8 data_jd9366ab_46[] = { 0x60, 0x2b }; +static CVI_U8 data_jd9366ab_47[] = { 0x61, 0x25 }; +static CVI_U8 data_jd9366ab_48[] = { 0x62, 0x15 }; +static CVI_U8 data_jd9366ab_49[] = { 0x63, 0x1a }; +static CVI_U8 data_jd9366ab_50[] = { 0x64, 0x04 }; +static CVI_U8 data_jd9366ab_51[] = { 0x65, 0x1c }; +static CVI_U8 data_jd9366ab_52[] = { 0x66, 0x1a }; +static CVI_U8 data_jd9366ab_53[] = { 0x67, 0x19 }; +static CVI_U8 data_jd9366ab_54[] = { 0x68, 0x36 }; +static CVI_U8 data_jd9366ab_55[] = { 0x69, 0x27 }; +static CVI_U8 data_jd9366ab_56[] = { 0x6a, 0x2f }; +static CVI_U8 data_jd9366ab_57[] = { 0x6b, 0x23 }; +static CVI_U8 data_jd9366ab_58[] = { 0x6c, 0x21 }; +static CVI_U8 data_jd9366ab_59[] = { 0x6d, 0x17 }; +static CVI_U8 data_jd9366ab_60[] = { 0x6e, 0x05 }; +static CVI_U8 data_jd9366ab_61[] = { 0x6f, 0x00 }; +static CVI_U8 data_jd9366ab_62[] = { 0x70, 0x7c }; +static CVI_U8 data_jd9366ab_63[] = { 0x71, 0x50 }; +static CVI_U8 data_jd9366ab_64[] = { 0x72, 0x3b }; +static CVI_U8 data_jd9366ab_65[] = { 0x73, 0x2b }; +static CVI_U8 data_jd9366ab_66[] = { 0x74, 0x25 }; +static CVI_U8 data_jd9366ab_67[] = { 0x75, 0x15 }; +static CVI_U8 data_jd9366ab_68[] = { 0x76, 0x1a }; +static CVI_U8 data_jd9366ab_69[] = { 0x77, 0x04 }; +static CVI_U8 data_jd9366ab_70[] = { 0x78, 0x1c }; +static CVI_U8 data_jd9366ab_71[] = { 0x79, 0x1a }; +static CVI_U8 data_jd9366ab_72[] = { 0x7a, 0x19 }; +static CVI_U8 data_jd9366ab_73[] = { 0x7b, 0x36 }; +static CVI_U8 data_jd9366ab_74[] = { 0x7c, 0x27 }; +static CVI_U8 data_jd9366ab_75[] = { 0x7d, 0x2f }; +static CVI_U8 data_jd9366ab_76[] = { 0x7e, 0x23 }; +static CVI_U8 data_jd9366ab_77[] = { 0x7f, 0x21 }; +static CVI_U8 data_jd9366ab_78[] = { 0x80, 0x17 }; +static CVI_U8 data_jd9366ab_79[] = { 0x81, 0x05 }; +static CVI_U8 data_jd9366ab_80[] = { 0x82, 0x00 }; +static CVI_U8 data_jd9366ab_81[] = { 0xe0, 0x02 }; +static CVI_U8 data_jd9366ab_82[] = { 0x00, 0x00 }; +static CVI_U8 data_jd9366ab_83[] = { 0x01, 0x04 }; +static CVI_U8 data_jd9366ab_84[] = { 0x02, 0x08 }; +static CVI_U8 data_jd9366ab_85[] = { 0x03, 0x05 }; +static CVI_U8 data_jd9366ab_86[] = { 0x04, 0x09 }; +static CVI_U8 data_jd9366ab_87[] = { 0x05, 0x06 }; +static CVI_U8 data_jd9366ab_88[] = { 0x06, 0x0a }; +static CVI_U8 data_jd9366ab_89[] = { 0x07, 0x07 }; +static CVI_U8 data_jd9366ab_90[] = { 0x08, 0x0b }; +static CVI_U8 data_jd9366ab_91[] = { 0x09, 0x1f }; +static CVI_U8 data_jd9366ab_92[] = { 0x0a, 0x1f }; +static CVI_U8 data_jd9366ab_93[] = { 0x0b, 0x1f }; +static CVI_U8 data_jd9366ab_94[] = { 0x0c, 0x1f }; +static CVI_U8 data_jd9366ab_95[] = { 0x0d, 0x1f }; +static CVI_U8 data_jd9366ab_96[] = { 0x0e, 0x1f }; +static CVI_U8 data_jd9366ab_97[] = { 0x0f, 0x17 }; +static CVI_U8 data_jd9366ab_98[] = { 0x10, 0x37 }; +static CVI_U8 data_jd9366ab_99[] = { 0x11, 0x10 }; +static CVI_U8 data_jd9366ab_100[] = { 0x12, 0x1f }; +static CVI_U8 data_jd9366ab_101[] = { 0x13, 0x1f }; +static CVI_U8 data_jd9366ab_102[] = { 0x14, 0x1f }; +static CVI_U8 data_jd9366ab_103[] = { 0x15, 0x1f }; +static CVI_U8 data_jd9366ab_104[] = { 0x16, 0x00 }; +static CVI_U8 data_jd9366ab_105[] = { 0x17, 0x04 }; +static CVI_U8 data_jd9366ab_106[] = { 0x18, 0x08 }; +static CVI_U8 data_jd9366ab_107[] = { 0x19, 0x05 }; +static CVI_U8 data_jd9366ab_108[] = { 0x1a, 0x09 }; +static CVI_U8 data_jd9366ab_109[] = { 0x1b, 0x06 }; +static CVI_U8 data_jd9366ab_110[] = { 0x1c, 0x0a }; +static CVI_U8 data_jd9366ab_111[] = { 0x1d, 0x07 }; +static CVI_U8 data_jd9366ab_112[] = { 0x1e, 0x0b }; +static CVI_U8 data_jd9366ab_113[] = { 0x1f, 0x1f }; +static CVI_U8 data_jd9366ab_114[] = { 0x20, 0x1f }; +static CVI_U8 data_jd9366ab_115[] = { 0x21, 0x1f }; +static CVI_U8 data_jd9366ab_116[] = { 0x22, 0x1f }; +static CVI_U8 data_jd9366ab_117[] = { 0x23, 0x1f }; +static CVI_U8 data_jd9366ab_118[] = { 0x24, 0x1f }; +static CVI_U8 data_jd9366ab_119[] = { 0x25, 0x17 }; +static CVI_U8 data_jd9366ab_120[] = { 0x26, 0x37 }; +static CVI_U8 data_jd9366ab_121[] = { 0x27, 0x10 }; +static CVI_U8 data_jd9366ab_122[] = { 0x28, 0x1f }; +static CVI_U8 data_jd9366ab_123[] = { 0x29, 0x1f }; +static CVI_U8 data_jd9366ab_124[] = { 0x2a, 0x1f }; +static CVI_U8 data_jd9366ab_125[] = { 0x2b, 0x1f }; +static CVI_U8 data_jd9366ab_126[] = { 0x58, 0x01 }; +static CVI_U8 data_jd9366ab_127[] = { 0x59, 0x00 }; +static CVI_U8 data_jd9366ab_128[] = { 0x5a, 0x00 }; +static CVI_U8 data_jd9366ab_129[] = { 0x5b, 0x00 }; +static CVI_U8 data_jd9366ab_130[] = { 0x5c, 0x0c }; +static CVI_U8 data_jd9366ab_131[] = { 0x5d, 0x60 }; +static CVI_U8 data_jd9366ab_132[] = { 0x5e, 0x00 }; +static CVI_U8 data_jd9366ab_133[] = { 0x5f, 0x00 }; +static CVI_U8 data_jd9366ab_134[] = { 0x60, 0x30 }; +static CVI_U8 data_jd9366ab_135[] = { 0x61, 0x00 }; +static CVI_U8 data_jd9366ab_136[] = { 0x62, 0x00 }; +static CVI_U8 data_jd9366ab_137[] = { 0x63, 0x03 }; +static CVI_U8 data_jd9366ab_138[] = { 0x64, 0x6a }; +static CVI_U8 data_jd9366ab_139[] = { 0x65, 0x45 }; +static CVI_U8 data_jd9366ab_140[] = { 0x66, 0x14 }; +static CVI_U8 data_jd9366ab_141[] = { 0x67, 0x73 }; +static CVI_U8 data_jd9366ab_142[] = { 0x68, 0x10 }; +static CVI_U8 data_jd9366ab_143[] = { 0x69, 0x06 }; +static CVI_U8 data_jd9366ab_144[] = { 0x6a, 0x6a }; +static CVI_U8 data_jd9366ab_145[] = { 0x6b, 0x00 }; +static CVI_U8 data_jd9366ab_146[] = { 0x6c, 0x00 }; +static CVI_U8 data_jd9366ab_147[] = { 0x6d, 0x03 }; +static CVI_U8 data_jd9366ab_148[] = { 0x6e, 0x00 }; +static CVI_U8 data_jd9366ab_149[] = { 0x6f, 0x08 }; +static CVI_U8 data_jd9366ab_150[] = { 0x70, 0x00 }; +static CVI_U8 data_jd9366ab_151[] = { 0x71, 0x00 }; +static CVI_U8 data_jd9366ab_152[] = { 0x72, 0x06 }; +static CVI_U8 data_jd9366ab_153[] = { 0x73, 0x7b }; +static CVI_U8 data_jd9366ab_154[] = { 0x74, 0x00 }; +static CVI_U8 data_jd9366ab_155[] = { 0x75, 0x80 }; +static CVI_U8 data_jd9366ab_156[] = { 0x76, 0x00 }; +static CVI_U8 data_jd9366ab_157[] = { 0x77, 0x05 }; +static CVI_U8 data_jd9366ab_158[] = { 0x78, 0x1b }; +static CVI_U8 data_jd9366ab_159[] = { 0x79, 0x00 }; +static CVI_U8 data_jd9366ab_160[] = { 0x7a, 0x00 }; +static CVI_U8 data_jd9366ab_161[] = { 0x7b, 0x00 }; +static CVI_U8 data_jd9366ab_162[] = { 0x7c, 0x00 }; +static CVI_U8 data_jd9366ab_163[] = { 0x7d, 0x03 }; +static CVI_U8 data_jd9366ab_164[] = { 0x7e, 0x7b }; +static CVI_U8 data_jd9366ab_165[] = { 0xe0, 0x01 }; +static CVI_U8 data_jd9366ab_166[] = { 0x0e, 0x01 }; +static CVI_U8 data_jd9366ab_167[] = { 0xe0, 0x03 }; +static CVI_U8 data_jd9366ab_168[] = { 0x98, 0x2f }; +static CVI_U8 data_jd9366ab_169[] = { 0xe0, 0x04 }; +static CVI_U8 data_jd9366ab_170[] = { 0x09, 0x10 }; +static CVI_U8 data_jd9366ab_171[] = { 0x2b, 0x2b }; +static CVI_U8 data_jd9366ab_172[] = { 0x2e, 0x44 }; +static CVI_U8 data_jd9366ab_173[] = { 0xe0, 0x00 }; +static CVI_U8 data_jd9366ab_174[] = { 0xe6, 0x02 }; +static CVI_U8 data_jd9366ab_175[] = { 0xe7, 0x06 }; +static CVI_U8 data_jd9366ab_176[] = { 0x11 }; +static CVI_U8 data_jd9366ab_177[] = { 0x29 }; +static CVI_U8 data_jd9366ab_178[] = { 0x35, 0x00 }; +const struct dsc_instr dsi_init_cmds_jd9366ab_800x1280[] = { + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_0 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_1 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_2 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_3 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_4 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_5 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_6 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_7 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_8 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_11 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_16 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_17 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_18 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_19 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_20 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_21 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_22 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_23 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_24 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_25 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_26 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_27 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_28 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_29 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_30 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_31 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_32 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_33 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_34 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_35 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_36 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_37 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_38 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_39 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_40 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_41 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_42 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_43 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_44 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_45 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_46 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_47 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_48 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_49 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_50 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_51 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_52 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_53 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_54 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_55 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_56 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_57 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_58 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_59 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_60 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_61 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_62 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_63 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_64 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_65 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_66 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_67 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_68 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_69 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_70 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_71 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_72 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_73 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_74 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_75 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_76 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_77 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_78 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_79 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_80 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_81 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_82 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_83 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_84 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_85 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_86 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_87 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_88 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_89 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_90 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_91 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_92 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_93 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_94 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_95 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_96 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_97 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_98 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_99 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_100 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_101 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_102 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_103 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_104 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_105 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_106 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_107 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_108 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_109 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_110 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_111 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_112 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_113 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_114 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_115 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_116 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_117 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_118 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_119 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_120 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_121 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_122 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_123 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_124 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_125 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_126 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_127 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_128 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_129 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_130 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_131 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_132 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_133 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_134 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_135 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_136 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_137 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_138 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_139 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_140 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_141 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_142 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_143 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_144 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_145 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_146 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_147 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_148 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_149 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_150 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_151 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_152 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_153 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_154 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_155 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_156 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_157 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_158 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_159 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_160 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_161 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_162 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_163 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_164 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_165 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_166 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_167 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_168 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_169 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_170 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_171 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_172 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_173 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_174 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_175 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_jd9366ab_176 }, + {.delay = 5, .data_type = 0x05, .size = 1, .data = data_jd9366ab_177 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_178 } +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_JD9366AB_H_ diff --git a/middleware/v2/component/panel/cv180x/dsi_nt35521.h b/middleware/v2/component/panel/cv180x/dsi_nt35521.h new file mode 100644 index 000000000..704e83cae --- /dev/null +++ b/middleware/v2/component/panel/cv180x/dsi_nt35521.h @@ -0,0 +1,200 @@ +#ifndef _MIPI_TX_PARAM_NT35521_H_ +#define _MIPI_TX_PARAM_NT35521_H_ + +#include +#include + +const struct combo_dev_cfg_s dev_cfg_nt35521_800x1280 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_CLK, MIPI_TX_LANE_0, MIPI_TX_LANE_2, MIPI_TX_LANE_3, MIPI_TX_LANE_1}, + .lane_pn_swap = {false, false, false, false, false}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = 80, + .vid_hbp_pixels = 80, + .vid_hfp_pixels = 168, + .vid_hline_pixels = 800, + .vid_vsa_lines = 6, + .vid_vbp_lines = 40, + .vid_vfp_lines = 18, + .vid_active_lines = 1280, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 90962, +}; + +const struct hs_settle_s hs_timing_cfg_nt35521_800x1280 = { .prepare = 6, .zero = 32, .trail = 1 }; + +//=====================Page 0 relative=================== +static CVI_U8 data_nt35521_0[] = { 0xf0, 0x55, 0xaa, 0x52, 0x08, 0x00 }; +static CVI_U8 data_nt35521_1[] = { 0xb1, 0x6c, 0x01 }; +static CVI_U8 data_nt35521_2[] = { 0xb5, 0xc8, 0x00 }; +static CVI_U8 data_nt35521_3[] = { 0xbc, 0x00 }; +static CVI_U8 data_nt35521_4[] = { 0xbd, 0x96, 0xb0, 0x0c, 0x08, 0x01 }; +static CVI_U8 data_nt35521_5[] = { 0xc8, 0x80 }; +//=====================Page 1 relative=================== +static CVI_U8 data_nt35521_6[] = { 0xf0, 0x55, 0xaa, 0x52, 0x08, 0x01 }; +static CVI_U8 data_nt35521_7[] = { 0xb3, 0x26 }; +static CVI_U8 data_nt35521_8[] = { 0xb4, 0x0f }; +static CVI_U8 data_nt35521_9[] = { 0xbb, 0x15 }; +static CVI_U8 data_nt35521_10[] = { 0xbc, 0xa8 }; +static CVI_U8 data_nt35521_11[] = { 0xbd, 0xa8 }; +static CVI_U8 data_nt35521_12[] = { 0xbe, 0x28 }; +//=====================Page 2 relative=================== +static CVI_U8 data_nt35521_13[] = { 0xf0, 0x55, 0xaa, 0x52, 0x08, 0x02 }; +static CVI_U8 data_nt35521_14[] = { 0xee, 0x01 }; +static CVI_U8 data_nt35521_15[] = { + 0xb0, 0x00, 0x00, 0x00, 0x13, 0x00, 0x33, 0x00, 0x4f, 0x00, + 0x65, 0x00, 0x79, 0x00, 0x8b, 0x00, 0x9c +}; +static CVI_U8 data_nt35521_16[] = { + 0xb1, 0x00, 0xac, 0x00, 0xe0, 0x01, 0x09, 0x01, 0x4b, 0x01, + 0x80, 0x01, 0xd1, 0x02, 0x13, 0x02, 0x14 +}; +static CVI_U8 data_nt35521_17[] = { + 0xb2, 0x02, 0x50, 0x02, 0x91, 0x02, 0xba, 0x02, 0xf0, 0x03, + 0x12, 0x03, 0x3d, 0x03, 0x4a, 0x03, 0x57 +}; +static CVI_U8 data_nt35521_18[] = { + 0xb3, 0x03, 0x5f, 0x03, 0x74, 0x03, 0x8f, 0x03, 0xb8, 0x03, + 0xfc, 0x03, 0xff +}; +static CVI_U8 data_nt35521_19[] = { + 0xe9, 0x52, 0x60, 0x63, 0x11, 0x21, 0x52, 0x60, 0x63, 0x11, + 0x21 +}; +static CVI_U8 data_nt35521_20[] = { + 0xea, 0x52, 0x60, 0x63, 0x11, 0x21, 0x52, 0x60, 0x63, 0x11, + 0x21 +}; +static CVI_U8 data_nt35521_21[] = { + 0xeb, 0x52, 0x60, 0x63, 0x11, 0x21, 0x52, 0x60, 0x63, 0x11, + 0x21 +}; +//=====================Page 3 relative=================== +static CVI_U8 data_nt35521_22[] = { 0xf0, 0x55, 0xaa, 0x52, 0x08, 0x03 }; +static CVI_U8 data_nt35521_23[] = { 0xb2, 0x00, 0x0b, 0x08, 0x00, 0x00 }; +static CVI_U8 data_nt35521_24[] = { 0xb3, 0x00, 0x09, 0x06, 0x00, 0x00 }; +static CVI_U8 data_nt35521_25[] = { 0xba, 0x44, 0x00, 0x00, 0x10 }; +static CVI_U8 data_nt35521_26[] = { 0xc0, 0x00, 0x34, 0x00 }; +static CVI_U8 data_nt35521_27[] = { 0xc1, 0x00, 0x00, 0x34 }; +//=====================Page 4 relative=================== +static CVI_U8 data_nt35521_28[] = { 0xf0, 0x55, 0xaa, 0x52, 0x08, 0x04 }; +static CVI_U8 data_nt35521_29[] = { 0xb1, 0x03, 0x02, 0x00, 0x15, 0x16 }; +//=====================Page 5 relative=================== +static CVI_U8 data_nt35521_30[] = { 0xf0, 0x55, 0xaa, 0x52, 0x08, 0x05 }; +static CVI_U8 data_nt35521_31[] = { 0xb0, 0x06 }; +static CVI_U8 data_nt35521_32[] = { 0xb2, 0x06, 0x00 }; +static CVI_U8 data_nt35521_33[] = { 0xb3, 0x0e, 0x00, 0x00, 0x00, 0x00 }; +static CVI_U8 data_nt35521_34[] = { 0xb4, 0x06, 0x00, 0x00, 0x00, 0x00 }; +static CVI_U8 data_nt35521_35[] = { 0xb7, 0x06, 0x00, 0x00 }; +static CVI_U8 data_nt35521_36[] = { 0xbc, 0x00, 0x00, 0x00, 0x02 }; +static CVI_U8 data_nt35521_37[] = { 0xbd, 0x01, 0x03, 0x00, 0x03, 0x03 }; +static CVI_U8 data_nt35521_38[] = { 0xc0, 0x07, 0x70 }; +static CVI_U8 data_nt35521_39[] = { 0xc4, 0x00, 0x00, 0x3c }; +static CVI_U8 data_nt35521_40[] = { 0xc5, 0x00, 0x00, 0x3c }; +static CVI_U8 data_nt35521_41[] = { 0xd1, 0x00, 0x05, 0x01, 0x00, 0x00 }; +static CVI_U8 data_nt35521_42[] = { 0xe3, 0x84 }; +static CVI_U8 data_nt35521_43[] = { 0xe5, 0x1a }; +static CVI_U8 data_nt35521_44[] = { 0xe6, 0x1a }; +static CVI_U8 data_nt35521_45[] = { 0xe8, 0x1a }; +static CVI_U8 data_nt35521_46[] = { 0xe9, 0x1a }; +static CVI_U8 data_nt35521_47[] = { 0xea, 0x1a }; +//=====================Page 6 relative=================== +static CVI_U8 data_nt35521_48[] = { 0xf0, 0x55, 0xaa, 0x52, 0x08, 0x06 }; +static CVI_U8 data_nt35521_49[] = { 0xb0, 0x30, 0x31, 0x2c, 0x2d, 0x14 }; +static CVI_U8 data_nt35521_50[] = { 0xb1, 0x16, 0x10, 0x12, 0x00, 0x35 }; +static CVI_U8 data_nt35521_51[] = { 0xb2, 0x35, 0x35, 0x35, 0x02, 0x31 }; +static CVI_U8 data_nt35521_52[] = { 0xb3, 0x31, 0x31, 0x35, 0x35, 0x35 }; +static CVI_U8 data_nt35521_53[] = { 0xb4, 0x35, 0x35, 0x35, 0x31, 0x31 }; +static CVI_U8 data_nt35521_54[] = { 0xb5, 0x31, 0x03, 0x35, 0x35, 0x35 }; +static CVI_U8 data_nt35521_55[] = { 0xb6, 0x35, 0x01, 0x13, 0x11, 0x17 }; +static CVI_U8 data_nt35521_56[] = { 0xb7, 0x15, 0x2d, 0x2c, 0x31, 0x30 }; +static CVI_U8 data_nt35521_57[] = { 0xf0, 0x55, 0xaa, 0x52, 0x00, 0x00 }; +static CVI_U8 data_nt35521_58[] = { 0x35, 0x00 }; +static CVI_U8 data_nt35521_59[] = { 0x11 }; +static CVI_U8 data_nt35521_60[] = { 0x29 }; +#ifdef _MIPI_TX_BIST_MODE +//=====================BIST relative=================== +static CVI_U8 data_nt35521_61[] = { 0x10 }; +static CVI_U8 data_nt35521_62[] = { 0xF0, 0x55, 0xAA, 0x52, 0x08, 0x00 }; +static CVI_U8 data_nt35521_63[] = { 0xEE, 0x87, 0x78, 0xff, 0xff }; +#endif + +const struct dsc_instr dsi_init_cmds_nt35521_800x1280[] = { +#ifdef _MIPI_TX_BIST_MODE + //=====================BIST relative=================== + { .delay = 0, .data_type = 0x05, .size = 1, .data = data_nt35521_61 }, + { .delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_62 }, + { .delay = 0, .data_type = 0x29, .size = 5, .data = data_nt35521_63 }, +#else + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_0 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_nt35521_1 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_nt35521_2 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_3 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_4 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_5 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_6 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_7 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_8 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_11 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_12 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_14 }, + {.delay = 0, .data_type = 0x29, .size = 17, .data = data_nt35521_15 }, + {.delay = 0, .data_type = 0x29, .size = 17, .data = data_nt35521_16 }, + {.delay = 0, .data_type = 0x29, .size = 17, .data = data_nt35521_17 }, + {.delay = 0, .data_type = 0x29, .size = 13, .data = data_nt35521_18 }, + {.delay = 0, .data_type = 0x29, .size = 11, .data = data_nt35521_19 }, + {.delay = 0, .data_type = 0x29, .size = 11, .data = data_nt35521_20 }, + {.delay = 0, .data_type = 0x29, .size = 11, .data = data_nt35521_21 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_22 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_23 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_24 }, + {.delay = 0, .data_type = 0x29, .size = 5, .data = data_nt35521_25 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_nt35521_26 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_nt35521_27 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_28 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_29 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_30 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_31 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_nt35521_32 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_33 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_34 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_nt35521_35 }, + {.delay = 0, .data_type = 0x29, .size = 5, .data = data_nt35521_36 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_37 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_nt35521_38 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_nt35521_39 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_nt35521_40 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_41 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_42 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_43 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_44 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_45 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_46 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_47 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_48 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_49 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_50 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_51 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_52 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_53 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_54 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_55 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_56 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_57 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_58 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_nt35521_59 }, + {.delay = 20, .data_type = 0x05, .size = 1, .data = data_nt35521_60 } +#endif +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_NT35521_H_ diff --git a/middleware/v2/component/panel/cv180x/dsi_ota7290b.h b/middleware/v2/component/panel/cv180x/dsi_ota7290b.h new file mode 100644 index 000000000..6da973b6a --- /dev/null +++ b/middleware/v2/component/panel/cv180x/dsi_ota7290b.h @@ -0,0 +1,547 @@ +#ifndef _MIPI_TX_PARAM_OTA7290B_H_ +#define _MIPI_TX_PARAM_OTA7290B_H_ + +#include +#include + +// Not support BTA +const struct combo_dev_cfg_s dev_cfg_ota7290b_320x1280 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, MIPI_TX_LANE_2, MIPI_TX_LANE_3}, + .lane_pn_swap = {false, false, false, false, false}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = 30, + .vid_hbp_pixels = 50, + .vid_hfp_pixels = 150, + .vid_hline_pixels = 320, + .vid_vsa_lines = 20, + .vid_vbp_lines = 30, + .vid_vfp_lines = 150, + .vid_active_lines = 1280, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 52910, +}; + +const struct hs_settle_s hs_timing_cfg_ota7290b_320x1280 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_ota7290b_0[] = { 0xb0, 0x5a }; +static CVI_U8 data_ota7290b_1[] = { 0xb1, 0x00 }; +static CVI_U8 data_ota7290b_2[] = { 0x89, 0x01 }; +#ifdef _MIPI_TX_BIST_MODE_ +static CVI_U8 data_ota7290b_3[] = { 0x91, 0x16 }; +#else +static CVI_U8 data_ota7290b_3[] = { 0x91, 0x17 }; +#endif +static CVI_U8 data_ota7290b_4[] = { 0xb1, 0x03 }; +static CVI_U8 data_ota7290b_5[] = { 0x2c, 0x28 }; +static CVI_U8 data_ota7290b_6[] = { 0x00, 0xf1 }; +static CVI_U8 data_ota7290b_7[] = { 0x01, 0x18 }; +static CVI_U8 data_ota7290b_8[] = { 0x02, 0x00 }; +static CVI_U8 data_ota7290b_9[] = { 0x03, 0x00 }; +static CVI_U8 data_ota7290b_10[] = { 0x04, 0x00 }; +static CVI_U8 data_ota7290b_11[] = { 0x05, 0x00 }; +static CVI_U8 data_ota7290b_12[] = { 0x06, 0x00 }; +static CVI_U8 data_ota7290b_13[] = { 0x07, 0x00 }; +static CVI_U8 data_ota7290b_14[] = { 0x08, 0x00 }; +static CVI_U8 data_ota7290b_15[] = { 0x09, 0x00 }; +static CVI_U8 data_ota7290b_16[] = { 0x0a, 0x01 }; +static CVI_U8 data_ota7290b_17[] = { 0x0b, 0x01 }; +static CVI_U8 data_ota7290b_18[] = { 0x0c, 0x00 }; +static CVI_U8 data_ota7290b_19[] = { 0x0d, 0x00 }; +static CVI_U8 data_ota7290b_20[] = { 0x0e, 0x24 }; +static CVI_U8 data_ota7290b_21[] = { 0x0f, 0x1c }; +static CVI_U8 data_ota7290b_22[] = { 0x10, 0xc9 }; +static CVI_U8 data_ota7290b_23[] = { 0x11, 0x60 }; +static CVI_U8 data_ota7290b_24[] = { 0x12, 0x70 }; +static CVI_U8 data_ota7290b_25[] = { 0x13, 0x01 }; +static CVI_U8 data_ota7290b_26[] = { 0x14, 0xe7 }; +static CVI_U8 data_ota7290b_27[] = { 0x15, 0xff }; +static CVI_U8 data_ota7290b_28[] = { 0x16, 0x3d }; +static CVI_U8 data_ota7290b_29[] = { 0x17, 0x0e }; +static CVI_U8 data_ota7290b_30[] = { 0x18, 0x01 }; +static CVI_U8 data_ota7290b_31[] = { 0x19, 0x00 }; +static CVI_U8 data_ota7290b_32[] = { 0x1a, 0x00 }; +static CVI_U8 data_ota7290b_33[] = { 0x1b, 0xfc }; +static CVI_U8 data_ota7290b_34[] = { 0x1c, 0x0b }; +static CVI_U8 data_ota7290b_35[] = { 0x1d, 0xa0 }; +static CVI_U8 data_ota7290b_36[] = { 0x1e, 0x03 }; +static CVI_U8 data_ota7290b_37[] = { 0x1f, 0x04 }; +static CVI_U8 data_ota7290b_38[] = { 0x20, 0x0c }; +static CVI_U8 data_ota7290b_39[] = { 0x21, 0x00 }; +static CVI_U8 data_ota7290b_40[] = { 0x22, 0x04 }; +static CVI_U8 data_ota7290b_41[] = { 0x23, 0x81 }; +static CVI_U8 data_ota7290b_42[] = { 0x24, 0x1f }; +static CVI_U8 data_ota7290b_43[] = { 0x25, 0x10 }; +static CVI_U8 data_ota7290b_44[] = { 0x26, 0x9b }; +static CVI_U8 data_ota7290b_45[] = { 0x2d, 0x01 }; +static CVI_U8 data_ota7290b_46[] = { 0x2e, 0x84 }; +static CVI_U8 data_ota7290b_47[] = { 0x2f, 0x00 }; +static CVI_U8 data_ota7290b_48[] = { 0x30, 0x02 }; +static CVI_U8 data_ota7290b_49[] = { 0x31, 0x08 }; +static CVI_U8 data_ota7290b_50[] = { 0x32, 0x01 }; +static CVI_U8 data_ota7290b_51[] = { 0x33, 0x1c }; +static CVI_U8 data_ota7290b_52[] = { 0x34, 0x40 }; +static CVI_U8 data_ota7290b_53[] = { 0x35, 0xff }; +static CVI_U8 data_ota7290b_54[] = { 0x36, 0xff }; +static CVI_U8 data_ota7290b_55[] = { 0x37, 0xff }; +static CVI_U8 data_ota7290b_56[] = { 0x38, 0xff }; +static CVI_U8 data_ota7290b_57[] = { 0x39, 0xff }; +static CVI_U8 data_ota7290b_58[] = { 0x3a, 0x05 }; +static CVI_U8 data_ota7290b_59[] = { 0x3b, 0x00 }; +static CVI_U8 data_ota7290b_60[] = { 0x3c, 0x00 }; +static CVI_U8 data_ota7290b_61[] = { 0x3d, 0x00 }; +static CVI_U8 data_ota7290b_62[] = { 0x3e, 0x0f }; +static CVI_U8 data_ota7290b_63[] = { 0x3f, 0x8c }; +static CVI_U8 data_ota7290b_64[] = { 0x40, 0x2a }; +static CVI_U8 data_ota7290b_65[] = { 0x41, 0xfc }; +static CVI_U8 data_ota7290b_66[] = { 0x42, 0x01 }; +static CVI_U8 data_ota7290b_67[] = { 0x43, 0x40 }; +static CVI_U8 data_ota7290b_68[] = { 0x44, 0x05 }; +static CVI_U8 data_ota7290b_69[] = { 0x45, 0xe8 }; +static CVI_U8 data_ota7290b_70[] = { 0x46, 0x16 }; +static CVI_U8 data_ota7290b_71[] = { 0x47, 0x00 }; +static CVI_U8 data_ota7290b_72[] = { 0x48, 0x00 }; +static CVI_U8 data_ota7290b_73[] = { 0x49, 0x88 }; +static CVI_U8 data_ota7290b_74[] = { 0x4a, 0x08 }; +static CVI_U8 data_ota7290b_75[] = { 0x4b, 0x05 }; +static CVI_U8 data_ota7290b_76[] = { 0x4c, 0x03 }; +static CVI_U8 data_ota7290b_77[] = { 0x4d, 0xd0 }; +static CVI_U8 data_ota7290b_78[] = { 0x4e, 0x13 }; +static CVI_U8 data_ota7290b_79[] = { 0x4f, 0xff }; +static CVI_U8 data_ota7290b_80[] = { 0x50, 0x0a }; +static CVI_U8 data_ota7290b_81[] = { 0x51, 0x53 }; +static CVI_U8 data_ota7290b_82[] = { 0x52, 0x26 }; +static CVI_U8 data_ota7290b_83[] = { 0x53, 0x22 }; +static CVI_U8 data_ota7290b_84[] = { 0x54, 0x09 }; +static CVI_U8 data_ota7290b_85[] = { 0x55, 0x22 }; +static CVI_U8 data_ota7290b_86[] = { 0x56, 0x00 }; +static CVI_U8 data_ota7290b_87[] = { 0x57, 0x1c }; +static CVI_U8 data_ota7290b_88[] = { 0x58, 0x03 }; +static CVI_U8 data_ota7290b_89[] = { 0x59, 0x3f }; +static CVI_U8 data_ota7290b_90[] = { 0x5a, 0x28 }; +static CVI_U8 data_ota7290b_91[] = { 0x5b, 0x01 }; +static CVI_U8 data_ota7290b_92[] = { 0x5c, 0xcc }; +static CVI_U8 data_ota7290b_93[] = { 0x5d, 0x21 }; +static CVI_U8 data_ota7290b_94[] = { 0x5e, 0x84 }; +static CVI_U8 data_ota7290b_95[] = { 0x5f, 0x84 }; +static CVI_U8 data_ota7290b_96[] = { 0x60, 0x8e }; +static CVI_U8 data_ota7290b_97[] = { 0x61, 0x89 }; +static CVI_U8 data_ota7290b_98[] = { 0x62, 0xf0 }; +static CVI_U8 data_ota7290b_99[] = { 0x63, 0xb9 }; +static CVI_U8 data_ota7290b_100[] = { 0x64, 0xc6 }; +static CVI_U8 data_ota7290b_101[] = { 0x65, 0x96 }; +static CVI_U8 data_ota7290b_102[] = { 0x66, 0x0a }; +static CVI_U8 data_ota7290b_103[] = { 0x67, 0x62 }; +static CVI_U8 data_ota7290b_104[] = { 0x68, 0x90 }; +static CVI_U8 data_ota7290b_105[] = { 0x69, 0x12 }; +static CVI_U8 data_ota7290b_106[] = { 0x6a, 0x42 }; +static CVI_U8 data_ota7290b_107[] = { 0x6b, 0x48 }; +static CVI_U8 data_ota7290b_108[] = { 0x6c, 0xe8 }; +static CVI_U8 data_ota7290b_109[] = { 0x6d, 0x98 }; +static CVI_U8 data_ota7290b_110[] = { 0x6e, 0x08 }; +static CVI_U8 data_ota7290b_111[] = { 0x6f, 0x9f }; +static CVI_U8 data_ota7290b_112[] = { 0x70, 0x6b }; +static CVI_U8 data_ota7290b_113[] = { 0x71, 0x6c }; +static CVI_U8 data_ota7290b_114[] = { 0x72, 0xa9 }; +static CVI_U8 data_ota7290b_115[] = { 0x73, 0x20 }; +static CVI_U8 data_ota7290b_116[] = { 0x74, 0x06 }; +static CVI_U8 data_ota7290b_117[] = { 0x75, 0x29 }; +static CVI_U8 data_ota7290b_118[] = { 0x76, 0x00 }; +static CVI_U8 data_ota7290b_119[] = { 0x77, 0x00 }; +static CVI_U8 data_ota7290b_120[] = { 0x78, 0x0f }; +static CVI_U8 data_ota7290b_121[] = { 0x79, 0xe0 }; +static CVI_U8 data_ota7290b_122[] = { 0x7a, 0x01 }; +static CVI_U8 data_ota7290b_123[] = { 0x7b, 0xff }; +static CVI_U8 data_ota7290b_124[] = { 0x7c, 0xff }; +static CVI_U8 data_ota7290b_125[] = { 0x7d, 0xff }; +static CVI_U8 data_ota7290b_126[] = { 0x7e, 0x4f }; +static CVI_U8 data_ota7290b_127[] = { 0x7f, 0xfe }; +static CVI_U8 data_ota7290b_128[] = { 0xb1, 0x02 }; +static CVI_U8 data_ota7290b_129[] = { 0x00, 0xff }; +static CVI_U8 data_ota7290b_130[] = { 0x01, 0x05 }; +static CVI_U8 data_ota7290b_131[] = { 0x02, 0xa0 }; +static CVI_U8 data_ota7290b_132[] = { 0x03, 0x00 }; +static CVI_U8 data_ota7290b_133[] = { 0x04, 0x54 }; +static CVI_U8 data_ota7290b_134[] = { 0x05, 0x38 }; +static CVI_U8 data_ota7290b_135[] = { 0x06, 0xa0 }; +static CVI_U8 data_ota7290b_136[] = { 0x07, 0x0a }; +static CVI_U8 data_ota7290b_137[] = { 0x08, 0xc0 }; +static CVI_U8 data_ota7290b_138[] = { 0x09, 0x00 }; +static CVI_U8 data_ota7290b_139[] = { 0x0a, 0x00 }; +static CVI_U8 data_ota7290b_140[] = { 0x0b, 0x14 }; +static CVI_U8 data_ota7290b_141[] = { 0x0c, 0xe6 }; +static CVI_U8 data_ota7290b_142[] = { 0x0d, 0x0d }; +static CVI_U8 data_ota7290b_143[] = { 0x0f, 0x08 }; +static CVI_U8 data_ota7290b_144[] = { 0x10, 0x79 }; +static CVI_U8 data_ota7290b_145[] = { 0x11, 0x38 }; +static CVI_U8 data_ota7290b_146[] = { 0x12, 0x73 }; +static CVI_U8 data_ota7290b_147[] = { 0x13, 0xb3 }; +static CVI_U8 data_ota7290b_148[] = { 0x14, 0x29 }; +static CVI_U8 data_ota7290b_149[] = { 0x15, 0x80 }; +static CVI_U8 data_ota7290b_150[] = { 0x16, 0x07 }; +static CVI_U8 data_ota7290b_151[] = { 0x17, 0x8a }; +static CVI_U8 data_ota7290b_152[] = { 0x18, 0x8d }; +static CVI_U8 data_ota7290b_153[] = { 0x19, 0xbf }; +static CVI_U8 data_ota7290b_154[] = { 0x1a, 0x69 }; +static CVI_U8 data_ota7290b_155[] = { 0x1b, 0x0e }; +static CVI_U8 data_ota7290b_156[] = { 0x1c, 0xff }; +static CVI_U8 data_ota7290b_157[] = { 0x1d, 0xff }; +static CVI_U8 data_ota7290b_158[] = { 0x1e, 0xff }; +static CVI_U8 data_ota7290b_159[] = { 0x1f, 0xff }; +static CVI_U8 data_ota7290b_160[] = { 0x20, 0xff }; +static CVI_U8 data_ota7290b_161[] = { 0x21, 0xff }; +static CVI_U8 data_ota7290b_162[] = { 0x22, 0xff }; +static CVI_U8 data_ota7290b_163[] = { 0x23, 0xff }; +static CVI_U8 data_ota7290b_164[] = { 0x24, 0xff }; +static CVI_U8 data_ota7290b_165[] = { 0x25, 0xff }; +static CVI_U8 data_ota7290b_166[] = { 0x26, 0xff }; +static CVI_U8 data_ota7290b_167[] = { 0x27, 0x1f }; +static CVI_U8 data_ota7290b_168[] = { 0x28, 0xff }; +static CVI_U8 data_ota7290b_169[] = { 0x29, 0xff }; +static CVI_U8 data_ota7290b_170[] = { 0x2a, 0xff }; +static CVI_U8 data_ota7290b_171[] = { 0x2b, 0xff }; +static CVI_U8 data_ota7290b_172[] = { 0x2c, 0xff }; +static CVI_U8 data_ota7290b_173[] = { 0x2d, 0x07 }; +static CVI_U8 data_ota7290b_174[] = { 0x33, 0x06 }; +static CVI_U8 data_ota7290b_175[] = { 0x35, 0x7e }; +static CVI_U8 data_ota7290b_176[] = { 0x36, 0x06 }; +static CVI_U8 data_ota7290b_177[] = { 0x38, 0x7e }; +static CVI_U8 data_ota7290b_178[] = { 0x3a, 0x80 }; +static CVI_U8 data_ota7290b_179[] = { 0x3b, 0x01 }; +static CVI_U8 data_ota7290b_180[] = { 0x3c, 0x00 }; +static CVI_U8 data_ota7290b_181[] = { 0x3d, 0x2a }; +static CVI_U8 data_ota7290b_182[] = { 0x3e, 0x00 }; +static CVI_U8 data_ota7290b_183[] = { 0x3f, 0x40 }; +static CVI_U8 data_ota7290b_184[] = { 0x40, 0x05 }; +static CVI_U8 data_ota7290b_185[] = { 0x41, 0x00 }; +static CVI_U8 data_ota7290b_186[] = { 0x42, 0xa8 }; +static CVI_U8 data_ota7290b_187[] = { 0x43, 0x00 }; +static CVI_U8 data_ota7290b_188[] = { 0x44, 0x00 }; +static CVI_U8 data_ota7290b_189[] = { 0x45, 0x05 }; +static CVI_U8 data_ota7290b_190[] = { 0x46, 0x00 }; +static CVI_U8 data_ota7290b_191[] = { 0x47, 0x00 }; +static CVI_U8 data_ota7290b_192[] = { 0x48, 0x9b }; +static CVI_U8 data_ota7290b_193[] = { 0x49, 0xd2 }; +static CVI_U8 data_ota7290b_194[] = { 0x4a, 0x81 }; +static CVI_U8 data_ota7290b_195[] = { 0x4b, 0x02 }; +static CVI_U8 data_ota7290b_196[] = { 0x4c, 0x15 }; +static CVI_U8 data_ota7290b_197[] = { 0x4d, 0xc0 }; +static CVI_U8 data_ota7290b_198[] = { 0x4e, 0x0f }; +static CVI_U8 data_ota7290b_199[] = { 0x4f, 0x61 }; +static CVI_U8 data_ota7290b_200[] = { 0x50, 0x78 }; +static CVI_U8 data_ota7290b_201[] = { 0x51, 0x7a }; +static CVI_U8 data_ota7290b_202[] = { 0x52, 0x34 }; +static CVI_U8 data_ota7290b_203[] = { 0x53, 0x99 }; +static CVI_U8 data_ota7290b_204[] = { 0x54, 0xa2 }; +static CVI_U8 data_ota7290b_205[] = { 0x55, 0x02 }; +static CVI_U8 data_ota7290b_206[] = { 0x56, 0x14 }; +static CVI_U8 data_ota7290b_207[] = { 0x57, 0xb8 }; +static CVI_U8 data_ota7290b_208[] = { 0x58, 0xdc }; +static CVI_U8 data_ota7290b_209[] = { 0x59, 0x34 }; +static CVI_U8 data_ota7290b_210[] = { 0x5a, 0x1e }; +static CVI_U8 data_ota7290b_211[] = { 0x5b, 0x8f }; +static CVI_U8 data_ota7290b_212[] = { 0x5c, 0xc7 }; +static CVI_U8 data_ota7290b_213[] = { 0x5d, 0xe3 }; +static CVI_U8 data_ota7290b_214[] = { 0x5e, 0xf1 }; +static CVI_U8 data_ota7290b_215[] = { 0x5f, 0x78 }; +static CVI_U8 data_ota7290b_216[] = { 0x60, 0x3c }; +static CVI_U8 data_ota7290b_217[] = { 0x61, 0x36 }; +static CVI_U8 data_ota7290b_218[] = { 0x62, 0x1e }; +static CVI_U8 data_ota7290b_219[] = { 0x63, 0x1b }; +static CVI_U8 data_ota7290b_220[] = { 0x64, 0x8f }; +static CVI_U8 data_ota7290b_221[] = { 0x65, 0xc7 }; +static CVI_U8 data_ota7290b_222[] = { 0x66, 0xe3 }; +static CVI_U8 data_ota7290b_223[] = { 0x67, 0x31 }; +static CVI_U8 data_ota7290b_224[] = { 0x68, 0x0c }; +static CVI_U8 data_ota7290b_225[] = { 0x69, 0x89 }; +static CVI_U8 data_ota7290b_226[] = { 0x6a, 0x30 }; +static CVI_U8 data_ota7290b_227[] = { 0x6b, 0x8c }; +static CVI_U8 data_ota7290b_228[] = { 0x6c, 0x8d }; +static CVI_U8 data_ota7290b_229[] = { 0x6d, 0x8d }; +static CVI_U8 data_ota7290b_230[] = { 0x6e, 0x8d }; +static CVI_U8 data_ota7290b_231[] = { 0x6f, 0x8d }; +static CVI_U8 data_ota7290b_232[] = { 0x70, 0xc7 }; +static CVI_U8 data_ota7290b_233[] = { 0x71, 0xe3 }; +static CVI_U8 data_ota7290b_234[] = { 0x72, 0x31 }; +static CVI_U8 data_ota7290b_235[] = { 0x73, 0x00 }; +static CVI_U8 data_ota7290b_236[] = { 0x74, 0x00 }; +static CVI_U8 data_ota7290b_237[] = { 0x75, 0x00 }; +static CVI_U8 data_ota7290b_238[] = { 0x76, 0x00 }; +static CVI_U8 data_ota7290b_239[] = { 0x77, 0x00 }; +static CVI_U8 data_ota7290b_240[] = { 0x78, 0x00 }; +static CVI_U8 data_ota7290b_241[] = { 0x79, 0x00 }; +static CVI_U8 data_ota7290b_242[] = { 0x7a, 0xc6 }; +static CVI_U8 data_ota7290b_243[] = { 0x7b, 0xc6 }; +static CVI_U8 data_ota7290b_244[] = { 0x7c, 0xc6 }; +static CVI_U8 data_ota7290b_245[] = { 0x7d, 0xc6 }; +static CVI_U8 data_ota7290b_246[] = { 0x7e, 0xc6 }; +static CVI_U8 data_ota7290b_247[] = { 0x7f, 0xe3 }; +static CVI_U8 data_ota7290b_248[] = { 0x0b, 0x00 }; +static CVI_U8 data_ota7290b_249[] = { 0xb1, 0x03 }; +static CVI_U8 data_ota7290b_250[] = { 0x2c, 0x2c }; +static CVI_U8 data_ota7290b_251[] = { 0xb1, 0x00 }; +static CVI_U8 data_ota7290b_252[] = { 0x89, 0x03 }; +const struct dsc_instr dsi_init_cmds_ota7290b_320x1280[] = { + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_0 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_2 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_3 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_4 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_5 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_6 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_7 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_8 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_11 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_16 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_17 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_18 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_19 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_20 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_21 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_22 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_23 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_24 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_25 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_26 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_27 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_28 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_29 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_30 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_31 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_32 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_33 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_34 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_35 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_36 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_37 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_38 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_39 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_40 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_41 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_42 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_43 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_44 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_45 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_46 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_47 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_48 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_49 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_50 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_51 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_52 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_53 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_54 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_55 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_56 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_57 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_58 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_59 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_60 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_61 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_62 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_63 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_64 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_65 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_66 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_67 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_68 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_69 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_70 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_71 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_72 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_73 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_74 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_75 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_76 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_77 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_78 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_79 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_80 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_81 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_82 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_83 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_84 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_85 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_86 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_87 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_88 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_89 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_90 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_91 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_92 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_93 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_94 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_95 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_96 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_97 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_98 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_99 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_100 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_101 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_102 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_103 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_104 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_105 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_106 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_107 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_108 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_109 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_110 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_111 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_112 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_113 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_114 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_115 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_116 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_117 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_118 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_119 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_120 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_121 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_122 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_123 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_124 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_125 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_126 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_127 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_128 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_129 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_130 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_131 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_132 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_133 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_134 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_135 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_136 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_137 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_138 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_139 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_140 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_141 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_142 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_143 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_144 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_145 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_146 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_147 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_148 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_149 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_150 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_151 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_152 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_153 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_154 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_155 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_156 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_157 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_158 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_159 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_160 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_161 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_162 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_163 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_164 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_165 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_166 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_167 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_168 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_169 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_170 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_171 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_172 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_173 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_174 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_175 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_176 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_177 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_178 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_179 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_180 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_181 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_182 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_183 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_184 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_185 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_186 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_187 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_188 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_189 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_190 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_191 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_192 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_193 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_194 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_195 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_196 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_197 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_198 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_199 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_200 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_201 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_202 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_203 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_204 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_205 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_206 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_207 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_208 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_209 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_210 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_211 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_212 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_213 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_214 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_215 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_216 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_217 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_218 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_219 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_220 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_221 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_222 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_223 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_224 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_225 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_226 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_227 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_228 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_229 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_230 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_231 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_232 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_233 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_234 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_235 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_236 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_237 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_238 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_239 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_240 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_241 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_242 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_243 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_244 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_245 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_246 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_247 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_248 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_249 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_250 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_251 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_252 } +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_OTA7290B_H_ diff --git a/middleware/v2/component/panel/cv180x/dsi_ota7290b_1920.h b/middleware/v2/component/panel/cv180x/dsi_ota7290b_1920.h new file mode 100644 index 000000000..4483cf2b2 --- /dev/null +++ b/middleware/v2/component/panel/cv180x/dsi_ota7290b_1920.h @@ -0,0 +1,554 @@ +#ifndef _MIPI_TX_PARAM_OTA7290B_1920_H_ +#define _MIPI_TX_PARAM_OTA7290B_1920_H_ + +#include +#include + +// Not support BTA +const struct combo_dev_cfg_s dev_cfg_ota7290b_440x1920 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_3, MIPI_TX_LANE_2, MIPI_TX_LANE_CLK, MIPI_TX_LANE_1, MIPI_TX_LANE_0}, + .lane_pn_swap = {true, true, true, true, true}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = 30, + .vid_hbp_pixels = 50, + .vid_hfp_pixels = 150, + .vid_hline_pixels = 440, + .vid_vsa_lines = 20, + .vid_vbp_lines = 30, + .vid_vfp_lines = 150, + .vid_active_lines = 1920, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 85224, +}; + +const struct hs_settle_s hs_timing_cfg_ota7290b_440x1920 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_ota7290b_1920_0[] = { 0x11, 0x00 }; +static CVI_U8 data_ota7290b_1920_1[] = { 0xb0, 0x5a }; +static CVI_U8 data_ota7290b_1920_2[] = { 0xb0, 0x5a }; +static CVI_U8 data_ota7290b_1920_3[] = { 0xb1, 0x00 }; +static CVI_U8 data_ota7290b_1920_4[] = { 0x89, 0x01 }; +#ifdef _MIPI_TX_BIST_MODE_ +static CVI_U8 data_ota7290b_1920_5[] = { 0x91, 0x16 }; +#else +static CVI_U8 data_ota7290b_1920_5[] = { 0x91, 0x17 }; +#endif +static CVI_U8 data_ota7290b_1920_6[] = { 0xb1, 0x03 }; +static CVI_U8 data_ota7290b_1920_7[] = { 0x2c, 0x28 }; +static CVI_U8 data_ota7290b_1920_8[] = { 0x00, 0xb7 }; +static CVI_U8 data_ota7290b_1920_9[] = { 0x01, 0x1b }; +static CVI_U8 data_ota7290b_1920_10[] = { 0x02, 0x00 }; +static CVI_U8 data_ota7290b_1920_11[] = { 0x03, 0x00 }; +static CVI_U8 data_ota7290b_1920_12[] = { 0x04, 0x00 }; +static CVI_U8 data_ota7290b_1920_13[] = { 0x05, 0x00 }; +static CVI_U8 data_ota7290b_1920_14[] = { 0x06, 0x00 }; +static CVI_U8 data_ota7290b_1920_15[] = { 0x07, 0x00 }; +static CVI_U8 data_ota7290b_1920_16[] = { 0x08, 0x00 }; +static CVI_U8 data_ota7290b_1920_17[] = { 0x09, 0x00 }; +static CVI_U8 data_ota7290b_1920_18[] = { 0x0a, 0x01 }; +static CVI_U8 data_ota7290b_1920_19[] = { 0x0b, 0x3c }; +static CVI_U8 data_ota7290b_1920_20[] = { 0x0c, 0x00 }; +static CVI_U8 data_ota7290b_1920_21[] = { 0x0d, 0x00 }; +static CVI_U8 data_ota7290b_1920_22[] = { 0x0e, 0x24 }; +static CVI_U8 data_ota7290b_1920_23[] = { 0x0f, 0x1c }; +static CVI_U8 data_ota7290b_1920_24[] = { 0x10, 0xc9 }; +static CVI_U8 data_ota7290b_1920_25[] = { 0x11, 0x60 }; +static CVI_U8 data_ota7290b_1920_26[] = { 0x12, 0x70 }; +static CVI_U8 data_ota7290b_1920_27[] = { 0x13, 0x01 }; +static CVI_U8 data_ota7290b_1920_28[] = { 0x14, 0xe3 }; +static CVI_U8 data_ota7290b_1920_29[] = { 0x15, 0xff }; +static CVI_U8 data_ota7290b_1920_30[] = { 0x16, 0x3d }; +static CVI_U8 data_ota7290b_1920_31[] = { 0x17, 0x0e }; +static CVI_U8 data_ota7290b_1920_32[] = { 0x18, 0x01 }; +static CVI_U8 data_ota7290b_1920_33[] = { 0x19, 0x00 }; +static CVI_U8 data_ota7290b_1920_34[] = { 0x1a, 0x00 }; +static CVI_U8 data_ota7290b_1920_35[] = { 0x1b, 0xfc }; +static CVI_U8 data_ota7290b_1920_36[] = { 0x1c, 0x0b }; +static CVI_U8 data_ota7290b_1920_37[] = { 0x1d, 0xa0 }; +static CVI_U8 data_ota7290b_1920_38[] = { 0x1e, 0x03 }; +static CVI_U8 data_ota7290b_1920_39[] = { 0x1f, 0x04 }; +static CVI_U8 data_ota7290b_1920_40[] = { 0x20, 0x0c }; +static CVI_U8 data_ota7290b_1920_41[] = { 0x21, 0x00 }; +static CVI_U8 data_ota7290b_1920_42[] = { 0x22, 0x04 }; +static CVI_U8 data_ota7290b_1920_43[] = { 0x23, 0x81 }; +static CVI_U8 data_ota7290b_1920_44[] = { 0x24, 0x1f }; +static CVI_U8 data_ota7290b_1920_45[] = { 0x25, 0x10 }; +static CVI_U8 data_ota7290b_1920_46[] = { 0x26, 0x9b }; +static CVI_U8 data_ota7290b_1920_47[] = { 0x2d, 0x01 }; +static CVI_U8 data_ota7290b_1920_48[] = { 0x2e, 0x84 }; +static CVI_U8 data_ota7290b_1920_49[] = { 0x2f, 0x00 }; +static CVI_U8 data_ota7290b_1920_50[] = { 0x30, 0x02 }; +static CVI_U8 data_ota7290b_1920_51[] = { 0x31, 0x08 }; +static CVI_U8 data_ota7290b_1920_52[] = { 0x32, 0x01 }; +static CVI_U8 data_ota7290b_1920_53[] = { 0x33, 0x1c }; +static CVI_U8 data_ota7290b_1920_54[] = { 0x34, 0x70 }; +static CVI_U8 data_ota7290b_1920_55[] = { 0x35, 0xff }; +static CVI_U8 data_ota7290b_1920_56[] = { 0x36, 0xff }; +static CVI_U8 data_ota7290b_1920_57[] = { 0x37, 0xff }; +static CVI_U8 data_ota7290b_1920_58[] = { 0x38, 0xff }; +static CVI_U8 data_ota7290b_1920_59[] = { 0x39, 0xff }; +static CVI_U8 data_ota7290b_1920_60[] = { 0x3a, 0x05 }; +static CVI_U8 data_ota7290b_1920_61[] = { 0x3b, 0x00 }; +static CVI_U8 data_ota7290b_1920_62[] = { 0x3c, 0x00 }; +static CVI_U8 data_ota7290b_1920_63[] = { 0x3d, 0x00 }; +static CVI_U8 data_ota7290b_1920_64[] = { 0x3e, 0x0f }; +static CVI_U8 data_ota7290b_1920_65[] = { 0x3f, 0x8c }; +static CVI_U8 data_ota7290b_1920_66[] = { 0x40, 0x2a }; +static CVI_U8 data_ota7290b_1920_67[] = { 0x41, 0xfc }; +static CVI_U8 data_ota7290b_1920_68[] = { 0x42, 0x01 }; +static CVI_U8 data_ota7290b_1920_69[] = { 0x43, 0x40 }; +static CVI_U8 data_ota7290b_1920_70[] = { 0x44, 0x05 }; +static CVI_U8 data_ota7290b_1920_71[] = { 0x45, 0xe8 }; +static CVI_U8 data_ota7290b_1920_72[] = { 0x46, 0x16 }; +static CVI_U8 data_ota7290b_1920_73[] = { 0x47, 0x00 }; +static CVI_U8 data_ota7290b_1920_74[] = { 0x48, 0x00 }; +static CVI_U8 data_ota7290b_1920_75[] = { 0x49, 0x88 }; +static CVI_U8 data_ota7290b_1920_76[] = { 0x4a, 0x08 }; +static CVI_U8 data_ota7290b_1920_77[] = { 0x4b, 0x05 }; +static CVI_U8 data_ota7290b_1920_78[] = { 0x4c, 0x03 }; +static CVI_U8 data_ota7290b_1920_79[] = { 0x4d, 0xd0 }; +static CVI_U8 data_ota7290b_1920_80[] = { 0x4e, 0x13 }; +static CVI_U8 data_ota7290b_1920_81[] = { 0x4f, 0xff }; +static CVI_U8 data_ota7290b_1920_82[] = { 0x50, 0x0a }; +static CVI_U8 data_ota7290b_1920_83[] = { 0x51, 0x53 }; +static CVI_U8 data_ota7290b_1920_84[] = { 0x52, 0x26 }; +static CVI_U8 data_ota7290b_1920_85[] = { 0x53, 0x22 }; +static CVI_U8 data_ota7290b_1920_86[] = { 0x54, 0x09 }; +static CVI_U8 data_ota7290b_1920_87[] = { 0x55, 0x22 }; +static CVI_U8 data_ota7290b_1920_88[] = { 0x56, 0x00 }; +static CVI_U8 data_ota7290b_1920_89[] = { 0x57, 0x1c }; +static CVI_U8 data_ota7290b_1920_90[] = { 0x58, 0x03 }; +static CVI_U8 data_ota7290b_1920_91[] = { 0x59, 0x3f }; +static CVI_U8 data_ota7290b_1920_92[] = { 0x5a, 0x28 }; +static CVI_U8 data_ota7290b_1920_93[] = { 0x5b, 0x01 }; +static CVI_U8 data_ota7290b_1920_94[] = { 0x5c, 0xcc }; +static CVI_U8 data_ota7290b_1920_95[] = { 0x5d, 0x20 }; +static CVI_U8 data_ota7290b_1920_96[] = { 0x5e, 0xe8 }; +static CVI_U8 data_ota7290b_1920_97[] = { 0x5f, 0x1d }; +static CVI_U8 data_ota7290b_1920_98[] = { 0x60, 0xe1 }; +static CVI_U8 data_ota7290b_1920_99[] = { 0x61, 0x73 }; +static CVI_U8 data_ota7290b_1920_100[] = { 0x62, 0x8d }; +static CVI_U8 data_ota7290b_1920_101[] = { 0x63, 0x2d }; +static CVI_U8 data_ota7290b_1920_102[] = { 0x64, 0x25 }; +static CVI_U8 data_ota7290b_1920_103[] = { 0x65, 0x82 }; +static CVI_U8 data_ota7290b_1920_104[] = { 0x66, 0x09 }; +static CVI_U8 data_ota7290b_1920_105[] = { 0x67, 0x21 }; +static CVI_U8 data_ota7290b_1920_106[] = { 0x68, 0x84 }; +static CVI_U8 data_ota7290b_1920_107[] = { 0x69, 0x10 }; +static CVI_U8 data_ota7290b_1920_108[] = { 0x6a, 0x42 }; +static CVI_U8 data_ota7290b_1920_109[] = { 0x6b, 0x08 }; +static CVI_U8 data_ota7290b_1920_110[] = { 0x6c, 0x21 }; +static CVI_U8 data_ota7290b_1920_111[] = { 0x6d, 0x84 }; +static CVI_U8 data_ota7290b_1920_112[] = { 0x6e, 0x10 }; +static CVI_U8 data_ota7290b_1920_113[] = { 0x6f, 0x42 }; +static CVI_U8 data_ota7290b_1920_114[] = { 0x70, 0x08 }; +static CVI_U8 data_ota7290b_1920_115[] = { 0x71, 0x21 }; +static CVI_U8 data_ota7290b_1920_116[] = { 0x72, 0x84 }; +static CVI_U8 data_ota7290b_1920_117[] = { 0x73, 0x10 }; +static CVI_U8 data_ota7290b_1920_118[] = { 0x74, 0x42 }; +static CVI_U8 data_ota7290b_1920_119[] = { 0x75, 0x08 }; +static CVI_U8 data_ota7290b_1920_120[] = { 0x76, 0x00 }; +static CVI_U8 data_ota7290b_1920_121[] = { 0x77, 0x00 }; +static CVI_U8 data_ota7290b_1920_122[] = { 0x78, 0x0f }; +static CVI_U8 data_ota7290b_1920_123[] = { 0x79, 0xe0 }; +static CVI_U8 data_ota7290b_1920_124[] = { 0x7a, 0x01 }; +static CVI_U8 data_ota7290b_1920_125[] = { 0x7b, 0xff }; +static CVI_U8 data_ota7290b_1920_126[] = { 0x7c, 0xff }; +static CVI_U8 data_ota7290b_1920_127[] = { 0x7d, 0x0c }; +static CVI_U8 data_ota7290b_1920_128[] = { 0x7e, 0x41 }; +static CVI_U8 data_ota7290b_1920_129[] = { 0x7f, 0xfe }; +static CVI_U8 data_ota7290b_1920_130[] = { 0xb1, 0x02 }; +static CVI_U8 data_ota7290b_1920_131[] = { 0x00, 0xff }; +static CVI_U8 data_ota7290b_1920_132[] = { 0x01, 0x05 }; +static CVI_U8 data_ota7290b_1920_133[] = { 0x02, 0xdc }; +static CVI_U8 data_ota7290b_1920_134[] = { 0x03, 0x00 }; +static CVI_U8 data_ota7290b_1920_135[] = { 0x04, 0x3e }; +static CVI_U8 data_ota7290b_1920_136[] = { 0x05, 0x4e }; +static CVI_U8 data_ota7290b_1920_137[] = { 0x06, 0x90 }; +static CVI_U8 data_ota7290b_1920_138[] = { 0x07, 0x10 }; +static CVI_U8 data_ota7290b_1920_139[] = { 0x08, 0xc0 }; +static CVI_U8 data_ota7290b_1920_140[] = { 0x09, 0x01 }; +static CVI_U8 data_ota7290b_1920_141[] = { 0x0a, 0x00 }; +static CVI_U8 data_ota7290b_1920_142[] = { 0x0b, 0x14 }; +static CVI_U8 data_ota7290b_1920_143[] = { 0x0c, 0xe6 }; +static CVI_U8 data_ota7290b_1920_144[] = { 0x0d, 0x0d }; +static CVI_U8 data_ota7290b_1920_145[] = { 0x0f, 0x08 }; +static CVI_U8 data_ota7290b_1920_146[] = { 0x10, 0xf9 }; +static CVI_U8 data_ota7290b_1920_147[] = { 0x11, 0xf5 }; +static CVI_U8 data_ota7290b_1920_148[] = { 0x12, 0xa2 }; +static CVI_U8 data_ota7290b_1920_149[] = { 0x13, 0x03 }; +static CVI_U8 data_ota7290b_1920_150[] = { 0x14, 0x5e }; +static CVI_U8 data_ota7290b_1920_151[] = { 0x15, 0xcf }; +static CVI_U8 data_ota7290b_1920_152[] = { 0x16, 0x63 }; +static CVI_U8 data_ota7290b_1920_153[] = { 0x17, 0x01 }; +static CVI_U8 data_ota7290b_1920_154[] = { 0x18, 0xe9 }; +static CVI_U8 data_ota7290b_1920_155[] = { 0x19, 0x5e }; +static CVI_U8 data_ota7290b_1920_156[] = { 0x1a, 0x59 }; +static CVI_U8 data_ota7290b_1920_157[] = { 0x1b, 0x0e }; +static CVI_U8 data_ota7290b_1920_158[] = { 0x1c, 0xff }; +static CVI_U8 data_ota7290b_1920_159[] = { 0x1d, 0xff }; +static CVI_U8 data_ota7290b_1920_160[] = { 0x1e, 0xff }; +static CVI_U8 data_ota7290b_1920_161[] = { 0x1f, 0xff }; +static CVI_U8 data_ota7290b_1920_162[] = { 0x20, 0xff }; +static CVI_U8 data_ota7290b_1920_163[] = { 0x21, 0xff }; +static CVI_U8 data_ota7290b_1920_164[] = { 0x22, 0xff }; +static CVI_U8 data_ota7290b_1920_165[] = { 0x23, 0xff }; +static CVI_U8 data_ota7290b_1920_166[] = { 0x24, 0xff }; +static CVI_U8 data_ota7290b_1920_167[] = { 0x25, 0xff }; +static CVI_U8 data_ota7290b_1920_168[] = { 0x26, 0xff }; +static CVI_U8 data_ota7290b_1920_169[] = { 0x27, 0x1f }; +static CVI_U8 data_ota7290b_1920_170[] = { 0x28, 0xff }; +static CVI_U8 data_ota7290b_1920_171[] = { 0x29, 0xff }; +static CVI_U8 data_ota7290b_1920_172[] = { 0x2a, 0xff }; +static CVI_U8 data_ota7290b_1920_173[] = { 0x2b, 0xff }; +static CVI_U8 data_ota7290b_1920_174[] = { 0x2c, 0xff }; +static CVI_U8 data_ota7290b_1920_175[] = { 0x2d, 0x07 }; +static CVI_U8 data_ota7290b_1920_176[] = { 0x33, 0x00 }; +static CVI_U8 data_ota7290b_1920_177[] = { 0x35, 0x7e }; +static CVI_U8 data_ota7290b_1920_178[] = { 0x36, 0x00 }; +static CVI_U8 data_ota7290b_1920_179[] = { 0x38, 0x7e }; +static CVI_U8 data_ota7290b_1920_180[] = { 0x3a, 0x80 }; +static CVI_U8 data_ota7290b_1920_181[] = { 0x3b, 0x01 }; +static CVI_U8 data_ota7290b_1920_182[] = { 0x3c, 0xc0 }; +static CVI_U8 data_ota7290b_1920_183[] = { 0x3d, 0x2d }; +static CVI_U8 data_ota7290b_1920_184[] = { 0x3e, 0x00 }; +static CVI_U8 data_ota7290b_1920_185[] = { 0x3f, 0xb8 }; +static CVI_U8 data_ota7290b_1920_186[] = { 0x40, 0x05 }; +static CVI_U8 data_ota7290b_1920_187[] = { 0x41, 0x00 }; +static CVI_U8 data_ota7290b_1920_188[] = { 0x42, 0xb7 }; +static CVI_U8 data_ota7290b_1920_189[] = { 0x43, 0x00 }; +static CVI_U8 data_ota7290b_1920_190[] = { 0x44, 0xe0 }; +static CVI_U8 data_ota7290b_1920_191[] = { 0x45, 0x06 }; +static CVI_U8 data_ota7290b_1920_192[] = { 0x46, 0x00 }; +static CVI_U8 data_ota7290b_1920_193[] = { 0x47, 0x00 }; +static CVI_U8 data_ota7290b_1920_194[] = { 0x48, 0x9b }; +static CVI_U8 data_ota7290b_1920_195[] = { 0x49, 0xd2 }; +static CVI_U8 data_ota7290b_1920_196[] = { 0x4a, 0x71 }; +static CVI_U8 data_ota7290b_1920_197[] = { 0x4b, 0xe3 }; +static CVI_U8 data_ota7290b_1920_198[] = { 0x4c, 0x16 }; +static CVI_U8 data_ota7290b_1920_199[] = { 0x4d, 0xc0 }; +static CVI_U8 data_ota7290b_1920_200[] = { 0x4e, 0x0f }; +static CVI_U8 data_ota7290b_1920_201[] = { 0x4f, 0x61 }; +static CVI_U8 data_ota7290b_1920_202[] = { 0x50, 0x78 }; +static CVI_U8 data_ota7290b_1920_203[] = { 0x51, 0x7a }; +static CVI_U8 data_ota7290b_1920_204[] = { 0x52, 0x34 }; +static CVI_U8 data_ota7290b_1920_205[] = { 0x53, 0x99 }; +static CVI_U8 data_ota7290b_1920_206[] = { 0x54, 0xa2 }; +static CVI_U8 data_ota7290b_1920_207[] = { 0x55, 0x02 }; +static CVI_U8 data_ota7290b_1920_208[] = { 0x56, 0x24 }; +static CVI_U8 data_ota7290b_1920_209[] = { 0x57, 0xf8 }; +static CVI_U8 data_ota7290b_1920_210[] = { 0x58, 0xfc }; +static CVI_U8 data_ota7290b_1920_211[] = { 0x59, 0xf4 }; +static CVI_U8 data_ota7290b_1920_212[] = { 0x5a, 0xff }; +static CVI_U8 data_ota7290b_1920_213[] = { 0x5b, 0xff }; +static CVI_U8 data_ota7290b_1920_214[] = { 0x5c, 0xff }; +static CVI_U8 data_ota7290b_1920_215[] = { 0x5d, 0xb2 }; +static CVI_U8 data_ota7290b_1920_216[] = { 0x5e, 0xff }; +static CVI_U8 data_ota7290b_1920_217[] = { 0x5f, 0xff }; +static CVI_U8 data_ota7290b_1920_218[] = { 0x60, 0x8f }; +static CVI_U8 data_ota7290b_1920_219[] = { 0x61, 0x62 }; +static CVI_U8 data_ota7290b_1920_220[] = { 0x62, 0xb5 }; +static CVI_U8 data_ota7290b_1920_221[] = { 0x63, 0xb2 }; +static CVI_U8 data_ota7290b_1920_222[] = { 0x64, 0x5a }; +static CVI_U8 data_ota7290b_1920_223[] = { 0x65, 0xad }; +static CVI_U8 data_ota7290b_1920_224[] = { 0x66, 0x56 }; +static CVI_U8 data_ota7290b_1920_225[] = { 0x67, 0x2b }; +static CVI_U8 data_ota7290b_1920_226[] = { 0x68, 0x0c }; +static CVI_U8 data_ota7290b_1920_227[] = { 0x69, 0x01 }; +static CVI_U8 data_ota7290b_1920_228[] = { 0x6a, 0x01 }; +static CVI_U8 data_ota7290b_1920_229[] = { 0x6b, 0xfc }; +static CVI_U8 data_ota7290b_1920_230[] = { 0x6c, 0xfd }; +static CVI_U8 data_ota7290b_1920_231[] = { 0x6d, 0xfd }; +static CVI_U8 data_ota7290b_1920_232[] = { 0x6e, 0xfd }; +static CVI_U8 data_ota7290b_1920_233[] = { 0x6f, 0xfd }; +static CVI_U8 data_ota7290b_1920_234[] = { 0x70, 0xff }; +static CVI_U8 data_ota7290b_1920_235[] = { 0x71, 0xff }; +static CVI_U8 data_ota7290b_1920_236[] = { 0x72, 0x3f }; +static CVI_U8 data_ota7290b_1920_237[] = { 0x73, 0x00 }; +static CVI_U8 data_ota7290b_1920_238[] = { 0x74, 0x00 }; +static CVI_U8 data_ota7290b_1920_239[] = { 0x75, 0x00 }; +static CVI_U8 data_ota7290b_1920_240[] = { 0x76, 0x00 }; +static CVI_U8 data_ota7290b_1920_241[] = { 0x77, 0x00 }; +static CVI_U8 data_ota7290b_1920_242[] = { 0x78, 0x00 }; +static CVI_U8 data_ota7290b_1920_243[] = { 0x79, 0x00 }; +static CVI_U8 data_ota7290b_1920_244[] = { 0x7a, 0xdc }; +static CVI_U8 data_ota7290b_1920_245[] = { 0x7b, 0xdc }; +static CVI_U8 data_ota7290b_1920_246[] = { 0x7c, 0xdc }; +static CVI_U8 data_ota7290b_1920_247[] = { 0x7d, 0xdc }; +static CVI_U8 data_ota7290b_1920_248[] = { 0x7e, 0xdc }; +static CVI_U8 data_ota7290b_1920_249[] = { 0x7f, 0x6e }; +static CVI_U8 data_ota7290b_1920_250[] = { 0x0b, 0x04 }; +static CVI_U8 data_ota7290b_1920_251[] = { 0xb1, 0x03 }; +static CVI_U8 data_ota7290b_1920_252[] = { 0x2c, 0x2c }; +static CVI_U8 data_ota7290b_1920_253[] = { 0xb1, 0x00 }; +static CVI_U8 data_ota7290b_1920_254[] = { 0x89, 0x03 }; +static CVI_U8 data_ota7290b_1920_255[] = { 0x29, 0x00 }; + +const struct dsc_instr dsi_init_cmds_ota7290b_440x1920[] = { + {.delay = 250, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_0 }, + {.delay = 50, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_1 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_2 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_3 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_4 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_5 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_6 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_7 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_8 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_11 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_16 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_17 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_18 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_19 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_20 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_21 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_22 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_23 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_24 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_25 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_26 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_27 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_28 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_29 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_30 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_31 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_32 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_33 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_34 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_35 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_36 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_37 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_38 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_39 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_40 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_41 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_42 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_43 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_44 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_45 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_46 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_47 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_48 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_49 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_50 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_51 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_52 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_53 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_54 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_55 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_56 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_57 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_58 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_59 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_60 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_61 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_62 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_63 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_64 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_65 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_66 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_67 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_68 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_69 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_70 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_71 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_72 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_73 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_74 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_75 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_76 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_77 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_78 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_79 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_80 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_81 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_82 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_83 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_84 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_85 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_86 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_87 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_88 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_89 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_90 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_91 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_92 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_93 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_94 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_95 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_96 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_97 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_98 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_99 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_100 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_101 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_102 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_103 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_104 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_105 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_106 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_107 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_108 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_109 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_110 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_111 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_112 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_113 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_114 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_115 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_116 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_117 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_118 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_119 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_120 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_121 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_122 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_123 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_124 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_125 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_126 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_127 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_128 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_129 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_130 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_131 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_132 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_133 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_134 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_135 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_136 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_137 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_138 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_139 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_140 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_141 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_142 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_143 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_144 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_145 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_146 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_147 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_148 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_149 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_150 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_151 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_152 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_153 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_154 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_155 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_156 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_157 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_158 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_159 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_160 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_161 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_162 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_163 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_164 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_165 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_166 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_167 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_168 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_169 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_170 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_171 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_172 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_173 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_174 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_175 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_176 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_177 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_178 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_179 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_180 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_181 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_182 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_183 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_184 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_185 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_186 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_187 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_188 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_189 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_190 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_191 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_192 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_193 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_194 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_195 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_196 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_197 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_198 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_199 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_200 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_201 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_202 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_203 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_204 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_205 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_206 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_207 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_208 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_209 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_210 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_211 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_212 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_213 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_214 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_215 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_216 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_217 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_218 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_219 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_220 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_221 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_222 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_223 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_224 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_225 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_226 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_227 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_228 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_229 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_230 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_231 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_232 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_233 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_234 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_235 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_236 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_237 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_238 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_239 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_240 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_241 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_242 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_243 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_244 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_245 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_246 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_247 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_248 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_249 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_250 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_251 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_252 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_253 }, + {.delay = 200, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_254 }, + {.delay = 50, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_255 } +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_OTA7290B_1920_H_ diff --git a/middleware/v2/component/panel/cv180x/dsi_st7701.h b/middleware/v2/component/panel/cv180x/dsi_st7701.h new file mode 100644 index 000000000..a38a4a341 --- /dev/null +++ b/middleware/v2/component/panel/cv180x/dsi_st7701.h @@ -0,0 +1,161 @@ +#ifndef _MIPI_TX_PARAM_ST_7701_H_ +#define _MIPI_TX_PARAM_ST_7701_H_ + +#include +#include + +#define PANEL_NAME "NETEASE-2" + +#define ST7701_NETEASE_VACT 800 +#define ST7701_NETEASE_VSA 10 +#define ST7701_NETEASE_VBP 20 +#define ST7701_NETEASE_VFP 20 + +#define ST7701_NETEASE_HACT 480 +#define ST7701_NETEASE_HSA 10 +#define ST7701_NETEASE_HBP 50 +#define ST7701_NETEASE_HFP 50 + +#define PIXEL_CLK(x) ((x##_VACT + x##_VSA + x##_VBP + x##_VFP) \ + * (x##_HACT + x##_HSA + x##_HBP + x##_HFP) * 60 / 1000) + +const struct combo_dev_cfg_s dev_cfg_st7701_480x800 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_1, MIPI_TX_LANE_0, MIPI_TX_LANE_CLK, -1, -1}, + .lane_pn_swap = {false, false, false, false, false}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = ST7701_NETEASE_HSA, + .vid_hbp_pixels = ST7701_NETEASE_HBP, + .vid_hfp_pixels = ST7701_NETEASE_HFP, + .vid_hline_pixels = ST7701_NETEASE_HACT, + .vid_vsa_lines = ST7701_NETEASE_VSA, + .vid_vbp_lines = ST7701_NETEASE_VBP, + .vid_vfp_lines = ST7701_NETEASE_VFP, + .vid_active_lines = ST7701_NETEASE_VACT, + .vid_vsa_pos_polarity = true, + .vid_hsa_pos_polarity = false, + }, + .pixel_clk = PIXEL_CLK(ST7701_NETEASE), +}; + +const struct hs_settle_s hs_timing_cfg_st7701_480x800 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_st7701_0[] = { 0xff, 0x77, 0x01, 0x00, 0x00, 0x13 }; +static CVI_U8 data_st7701_1[] = { 0xef, 0x08 }; +static CVI_U8 data_st7701_2[] = { 0xff, 0x77, 0x01, 0x00, 0x00, 0x10 }; +static CVI_U8 data_st7701_3[] = { 0xc0, 0x63, 0x00 }; +static CVI_U8 data_st7701_4[] = { 0xc1, 0x11, 0x0c }; +static CVI_U8 data_st7701_5[] = { 0xc2, 0x07, 0x08 }; +static CVI_U8 data_st7701_6[] = { 0xcc, 0x10 }; +static CVI_U8 data_st7701_7[] = { + 0xb0, 0x00, 0x0c, 0x13, 0x0d, 0x10, 0x06, 0x01, 0x08, 0x07, + 0x1e, 0x04, 0x13, 0x10, 0x2d, 0x31, 0x10 +}; +static CVI_U8 data_st7701_8[] = { + 0xb1, 0x00, 0x0c, 0x13, 0x0d, 0x10, 0x06, 0x02, 0x08, 0x07, + 0x1f, 0x05, 0x12, 0x10, 0x27, 0x31, 0x1f +}; +static CVI_U8 data_st7701_9[] = { 0xff, 0x77, 0x01, 0x00, 0x00, 0x11 }; +static CVI_U8 data_st7701_10[] = { 0xb0, 0x70 }; +static CVI_U8 data_st7701_11[] = { 0xb1, 0x93 }; +static CVI_U8 data_st7701_12[] = { 0xb2, 0x87 }; +static CVI_U8 data_st7701_13[] = { 0xb3, 0x80 }; +static CVI_U8 data_st7701_14[] = { 0xb5, 0x49 }; +static CVI_U8 data_st7701_15[] = { 0xb7, 0x87 }; +static CVI_U8 data_st7701_16[] = { 0xb8, 0x21 }; +static CVI_U8 data_st7701_17[] = { 0xb9, 0x10, 0x1f }; +static CVI_U8 data_st7701_18[] = { 0xbb, 0x03 }; +static CVI_U8 data_st7701_19[] = { 0xc0, 0x89 }; +static CVI_U8 data_st7701_20[] = { 0xc1, 0x08 }; +static CVI_U8 data_st7701_21[] = { 0xc2, 0x08 }; +static CVI_U8 data_st7701_22[] = { 0xc8, 0xbe }; +static CVI_U8 data_st7701_23[] = { 0xd0, 0x88 }; +static CVI_U8 data_st7701_24[] = { + 0xe0, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0c +}; +static CVI_U8 data_st7701_25[] = { + 0xe1, 0x05, 0x8c, 0x07, 0x8c, 0x06, 0x8c, 0x08, 0x8c, 0x00, + 0x44, 0x44 +}; +static CVI_U8 data_st7701_26[] = { + 0xe2, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00 +}; +static CVI_U8 data_st7701_27[] = { 0xe3, 0x00, 0x00, 0x33, 0x33 }; +static CVI_U8 data_st7701_28[] = { 0xe4, 0x44, 0x44 }; +static CVI_U8 data_st7701_29[] = { + 0xe5, 0x0d, 0x3f, 0x0c, 0xa0, 0x0f, 0x41, 0x0c, 0xa0, 0x09, + 0x3b, 0x0c, 0xa0, 0x0b, 0x3d, 0x0c, 0xa0 +}; +static CVI_U8 data_st7701_30[] = { 0xe6, 0x00, 0x00, 0x33, 0x33 }; +static CVI_U8 data_st7701_31[] = { 0xe7, 0x44, 0x44 }; +static CVI_U8 data_st7701_32[] = { + 0xe8, 0x0e, 0x40, 0x0c, 0xa0, 0x10, 0x42, 0x0c, 0xa0, 0x0a, + 0x3c, 0x0c, 0xa0, 0x0c, 0x3e, 0x0c, 0xa0 +}; +static CVI_U8 data_st7701_33[] = { + 0xeb, 0x00, 0x01, 0xe4, 0xe4, 0x44, 0x00 +}; +static CVI_U8 data_st7701_34[] = { + 0xed, 0xf3, 0xc1, 0xba, 0x0f, 0x66, 0x77, 0x44, 0x55, 0x55, + 0x44, 0x77, 0x66, 0xf0, 0xab, 0x1c, 0x3f +}; +static CVI_U8 data_st7701_35[] = { + 0xef, 0x10, 0x0d, 0x04, 0x08, 0x3f, 0x1f +}; +static CVI_U8 data_st7701_36[] = { 0xff, 0x77, 0x01, 0x00, 0x00, 0x13 }; +static CVI_U8 data_st7701_37[] = { 0x11 }; +static CVI_U8 data_st7701_38[] = { 0x29 }; +static CVI_U8 data_st7701_39[] = { 0x36, 0x00 }; +static CVI_U8 data_st7701_40[] = { 0x35, 0x00 }; + +const struct dsc_instr dsi_init_cmds_st7701_480x800[] = { + {.delay = 0, .data_type = 0x39, .size = 6, .data = data_st7701_0 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_1 }, + {.delay = 0, .data_type = 0x39, .size = 6, .data = data_st7701_2 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_3 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_4 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_5 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_6 }, + {.delay = 0, .data_type = 0x39, .size = 17, .data = data_st7701_7 }, + {.delay = 0, .data_type = 0x39, .size = 17, .data = data_st7701_8 }, + {.delay = 0, .data_type = 0x39, .size = 6, .data = data_st7701_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_11 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_16 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_17 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_18 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_19 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_20 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_21 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_22 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_23 }, + {.delay = 0, .data_type = 0x39, .size = 7, .data = data_st7701_24 }, + {.delay = 0, .data_type = 0x39, .size = 12, .data = data_st7701_25 }, + {.delay = 0, .data_type = 0x39, .size = 13, .data = data_st7701_26 }, + {.delay = 0, .data_type = 0x39, .size = 5, .data = data_st7701_27 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_28 }, + {.delay = 0, .data_type = 0x39, .size = 17, .data = data_st7701_29 }, + {.delay = 0, .data_type = 0x39, .size = 5, .data = data_st7701_30 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_31 }, + {.delay = 0, .data_type = 0x39, .size = 17, .data = data_st7701_32 }, + {.delay = 0, .data_type = 0x39, .size = 7, .data = data_st7701_33 }, + {.delay = 0, .data_type = 0x39, .size = 17, .data = data_st7701_34 }, + {.delay = 0, .data_type = 0x39, .size = 7, .data = data_st7701_35 }, + {.delay = 0, .data_type = 0x39, .size = 6, .data = data_st7701_36 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_st7701_37 }, + {.delay = 20, .data_type = 0x05, .size = 1, .data = data_st7701_38 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_39 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_40 } +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_ST_7701_H_ diff --git a/middleware/v2/component/panel/cv180x/i80_st7789v.h b/middleware/v2/component/panel/cv180x/i80_st7789v.h new file mode 100644 index 000000000..3cd891c6e --- /dev/null +++ b/middleware/v2/component/panel/cv180x/i80_st7789v.h @@ -0,0 +1,94 @@ +#ifndef _I80_PARAM_ST7789V_H_ +#define _I80_PARAM_ST7789V_H_ + +#include + +#define COMMAND 0 +#define DATA 1 + +const VO_I80_CFG_S stI80Cfg = { + .lane_s = {.CS = 0, .RS = 1, .WR = 2, .RD = 3}, + .fmt = VO_I80_FORMAT_RGB565, + .cycle_time = 200, +}; + +const VO_I80_INSTR_S init_cmds[] = { + {.delay = 0, .data_type = COMMAND, .data = 0x11}, + {.delay = 0, .data_type = COMMAND, .data = 0x35}, + {.delay = 0, .data_type = DATA, .data = 0x00}, + {.delay = 0, .data_type = COMMAND, .data = 0x36}, + {.delay = 0, .data_type = DATA, .data = 0x00}, + {.delay = 0, .data_type = COMMAND, .data = 0x3A}, + {.delay = 0, .data_type = DATA, .data = 0x05}, + {.delay = 0, .data_type = COMMAND, .data = 0xB2}, + {.delay = 0, .data_type = DATA, .data = 0x0C}, + {.delay = 0, .data_type = DATA, .data = 0x0C}, + {.delay = 0, .data_type = DATA, .data = 0x00}, + {.delay = 0, .data_type = DATA, .data = 0x33}, + {.delay = 0, .data_type = DATA, .data = 0x33}, + {.delay = 0, .data_type = COMMAND, .data = 0xB7}, + {.delay = 0, .data_type = DATA, .data = 0x75}, + {.delay = 0, .data_type = COMMAND, .data = 0xBB}, + {.delay = 0, .data_type = DATA, .data = 0x19}, + {.delay = 0, .data_type = COMMAND, .data = 0xC0}, + {.delay = 0, .data_type = DATA, .data = 0x2C}, + {.delay = 0, .data_type = COMMAND, .data = 0xC2}, + {.delay = 0, .data_type = DATA, .data = 0x01}, + {.delay = 0, .data_type = COMMAND, .data = 0xC3}, + {.delay = 0, .data_type = DATA, .data = 0x0C}, + {.delay = 0, .data_type = COMMAND, .data = 0xC4}, + {.delay = 0, .data_type = DATA, .data = 0x20}, + {.delay = 0, .data_type = COMMAND, .data = 0xC6}, + {.delay = 0, .data_type = DATA, .data = 0x0F}, + {.delay = 0, .data_type = COMMAND, .data = 0xD0}, + {.delay = 0, .data_type = DATA, .data = 0xA4}, + {.delay = 0, .data_type = DATA, .data = 0xA1}, + {.delay = 0, .data_type = COMMAND, .data = 0xE0}, + {.delay = 0, .data_type = DATA, .data = 0xD0}, + {.delay = 0, .data_type = DATA, .data = 0x05}, + {.delay = 0, .data_type = DATA, .data = 0x0D}, + {.delay = 0, .data_type = DATA, .data = 0x13}, + {.delay = 0, .data_type = DATA, .data = 0x14}, + {.delay = 0, .data_type = DATA, .data = 0x2D}, + {.delay = 0, .data_type = DATA, .data = 0x3C}, + {.delay = 0, .data_type = DATA, .data = 0x52}, + {.delay = 0, .data_type = DATA, .data = 0x49}, + {.delay = 0, .data_type = DATA, .data = 0x13}, + {.delay = 0, .data_type = DATA, .data = 0x0B}, + {.delay = 0, .data_type = DATA, .data = 0x09}, + {.delay = 0, .data_type = DATA, .data = 0x1A}, + {.delay = 0, .data_type = DATA, .data = 0x1B}, + {.delay = 0, .data_type = COMMAND, .data = 0xE1}, + {.delay = 0, .data_type = DATA, .data = 0xD0}, + {.delay = 0, .data_type = DATA, .data = 0x05}, + {.delay = 0, .data_type = DATA, .data = 0x0C}, + {.delay = 0, .data_type = DATA, .data = 0x13}, + {.delay = 0, .data_type = DATA, .data = 0x14}, + {.delay = 0, .data_type = DATA, .data = 0x2F}, + {.delay = 0, .data_type = DATA, .data = 0x4C}, + {.delay = 0, .data_type = DATA, .data = 0x41}, + {.delay = 0, .data_type = DATA, .data = 0x4E}, + {.delay = 0, .data_type = DATA, .data = 0x2A}, + {.delay = 0, .data_type = DATA, .data = 0x1D}, + {.delay = 0, .data_type = DATA, .data = 0x1D}, + {.delay = 0, .data_type = DATA, .data = 0x1B}, + {.delay = 0, .data_type = DATA, .data = 0x1B}, + + {.delay = 0, .data_type = COMMAND, .data = 0x29}, + + {.delay = 0, .data_type = COMMAND, .data = 0x2A}, + {.delay = 0, .data_type = DATA, .data = 0x0 },//Xstart + {.delay = 0, .data_type = DATA, .data = 0x0 }, + {.delay = 0, .data_type = DATA, .data = 0x0 },//Xend + {.delay = 0, .data_type = DATA, .data = 0xEF}, + + {.delay = 0, .data_type = COMMAND, .data = 0x2B}, + {.delay = 0, .data_type = DATA, .data = 0x0 },//Ystart + {.delay = 0, .data_type = DATA, .data = 0x0 }, + {.delay = 0, .data_type = DATA, .data = 0x01},//Yend + {.delay = 0, .data_type = DATA, .data = 0x3F}, + + {.delay = 0, .data_type = COMMAND, .data = 0x2C}, +}; + +#endif // _I80_PARAM_ST7789V_H_ diff --git a/middleware/v2/component/panel/cv181x/dsi_3aml069lp01g.h b/middleware/v2/component/panel/cv181x/dsi_3aml069lp01g.h new file mode 100644 index 000000000..a2f903d2c --- /dev/null +++ b/middleware/v2/component/panel/cv181x/dsi_3aml069lp01g.h @@ -0,0 +1,203 @@ +#ifndef _MIPI_TX_PARAM__3AML069LP01G_H_ +#define _MIPI_TX_PARAM__3AML069LP01G_H_ + +#include +#include + +#define _3AML069LP01G_RX_VACT 1024 +#define _3AML069LP01G_RX_VSA 3 +#define _3AML069LP01G_RX_VBP 5 +#define _3AML069LP01G_RX_VFP 7 + +#define _3AML069LP01G_RX_HACT 600 +#define _3AML069LP01G_RX_HSA 20 +#define _3AML069LP01G_RX_HBP 20 +#define _3AML069LP01G_RX_HFP 90 + +#define PIXEL_CLK(x) ((x##_VACT + x##_VSA + x##_VBP + x##_VFP) \ + * (x##_HACT + x##_HSA + x##_HBP + x##_HFP) * 60 / 1000) + +const struct combo_dev_cfg_s dev_cfg_3AML069LP01G_600x1024 = { + .devno = 0, +#ifdef MIPI_PANEL_2_LANES + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, -1, -1}, +#else + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, MIPI_TX_LANE_2, MIPI_TX_LANE_3}, +#endif + .lane_pn_swap = {false, false, false, false, false}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = _3AML069LP01G_RX_HSA, + .vid_hbp_pixels = _3AML069LP01G_RX_HBP, + .vid_hfp_pixels = _3AML069LP01G_RX_HFP, + .vid_hline_pixels = _3AML069LP01G_RX_HACT, + .vid_vsa_lines = _3AML069LP01G_RX_VSA, + .vid_vbp_lines = _3AML069LP01G_RX_VBP, + .vid_vfp_lines = _3AML069LP01G_RX_VFP, + .vid_active_lines = _3AML069LP01G_RX_VACT, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = PIXEL_CLK(_3AML069LP01G_RX), +}; + +const struct hs_settle_s hs_timing_cfg_3AML069LP01G_600x1024 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_3aml069lp01g_0[] = { 0xee, 0x50 }; +static CVI_U8 data_3aml069lp01g_1[] = { 0xea, 0x85, 0x55 }; +static CVI_U8 data_3aml069lp01g_2[] = { 0x24, 0x20 }; +static CVI_U8 data_3aml069lp01g_3[] = { 0x30, 0x00 }; +static CVI_U8 data_3aml069lp01g_4[] = { 0x39, 0x02, 0x07, 0x10 }; +static CVI_U8 data_3aml069lp01g_5[] = { 0x79, 0x00 }; +static CVI_U8 data_3aml069lp01g_6[] = { 0x7b, 0x00 }; +static CVI_U8 data_3aml069lp01g_7[] = { 0x7a, 0x00 }; +static CVI_U8 data_3aml069lp01g_8[] = { 0x90, 0x50, 0xc0 }; +static CVI_U8 data_3aml069lp01g_9[] = { 0x93, 0x80 }; +static CVI_U8 data_3aml069lp01g_10[] = { 0x95, 0x74 }; +static CVI_U8 data_3aml069lp01g_11[] = { 0x97, 0x37 }; +static CVI_U8 data_3aml069lp01g_12[] = { 0x99, 0x00 }; +static CVI_U8 data_3aml069lp01g_13[] = { 0x56, 0x83 }; +static CVI_U8 data_3aml069lp01g_14[] = { 0x33, 0x83 }; +static CVI_U8 data_3aml069lp01g_15[] = { 0x34, 0x3f }; +static CVI_U8 data_3aml069lp01g_16[] = { 0xee, 0x60 }; +static CVI_U8 data_3aml069lp01g_17[] = { 0x30, 0x03 }; +static CVI_U8 data_3aml069lp01g_18[] = { 0x32, 0xd9 }; +static CVI_U8 data_3aml069lp01g_19[] = { 0x3b, 0x00 }; +static CVI_U8 data_3aml069lp01g_20[] = { 0x3c, 0x07 }; +static CVI_U8 data_3aml069lp01g_21[] = { 0x3d, 0x11 }; +static CVI_U8 data_3aml069lp01g_22[] = { 0x3e, 0x94 }; +static CVI_U8 data_3aml069lp01g_23[] = { 0x42, 0x55 }; +static CVI_U8 data_3aml069lp01g_24[] = { 0x43, 0x55 }; +static CVI_U8 data_3aml069lp01g_25[] = { 0x86, 0x20 }; +static CVI_U8 data_3aml069lp01g_26[] = { 0x8b, 0x90 }; +static CVI_U8 data_3aml069lp01g_27[] = { 0x8d, 0x40 }; +static CVI_U8 data_3aml069lp01g_28[] = { 0x91, 0x11 }; +static CVI_U8 data_3aml069lp01g_29[] = { 0x92, 0x11 }; +static CVI_U8 data_3aml069lp01g_30[] = { 0x93, 0x9f }; +static CVI_U8 data_3aml069lp01g_31[] = { 0x9a, 0x07 }; +static CVI_U8 data_3aml069lp01g_32[] = { 0x9b, 0x02, 0x00 }; +static CVI_U8 data_3aml069lp01g_33[] = { 0x47, 0x05, 0x1e, 0x2f, 0x39, 0x40 }; +static CVI_U8 data_3aml069lp01g_34[] = { 0x5a, 0x05, 0x1e, 0x2f, 0x39, 0x40 }; +static CVI_U8 data_3aml069lp01g_35[] = { 0x4c, 0x53, 0x4a, 0x5d, 0x40, 0x40 }; +static CVI_U8 data_3aml069lp01g_36[] = { 0x5f, 0x53, 0x4a, 0x5d, 0x40, 0x40 }; +static CVI_U8 data_3aml069lp01g_37[] = { 0x51, 0x42, 0x29, 0x3e, 0x3d, 0x48 }; +static CVI_U8 data_3aml069lp01g_38[] = { 0x64, 0x42, 0x29, 0x3e, 0x3d, 0x48 }; +static CVI_U8 data_3aml069lp01g_39[] = { 0x56, 0x4c, 0x57, 0x66, 0x7f }; +static CVI_U8 data_3aml069lp01g_40[] = { 0x56, 0x4c, 0x57, 0x66, 0x7f }; +static CVI_U8 data_3aml069lp01g_41[] = { 0xee, 0x70 }; +static CVI_U8 data_3aml069lp01g_42[] = { 0x00, 0x01, 0x04, 0x00, 0x01 }; +static CVI_U8 data_3aml069lp01g_43[] = { 0x04, 0x06, 0x09, 0x44, 0x01 }; +static CVI_U8 data_3aml069lp01g_44[] = { 0x0c, 0x05, 0x2d }; +static CVI_U8 data_3aml069lp01g_45[] = { 0x10, 0x05, 0x09, 0x00, 0x00, 0x00 }; +static CVI_U8 data_3aml069lp01g_46[] = { 0x15, 0x00, 0x19, 0x0c, 0x08, 0x00 }; +static CVI_U8 data_3aml069lp01g_47[] = { 0x20, 0x01, 0x05, 0x00, 0x00, 0x00 }; +static CVI_U8 data_3aml069lp01g_48[] = { 0x25, 0x00, 0x15, 0x0c, 0x07, 0x00 }; +static CVI_U8 data_3aml069lp01g_49[] = { 0x29, 0x05, 0x2d }; +static CVI_U8 data_3aml069lp01g_50[] = { 0x45, 0x01 }; +static CVI_U8 data_3aml069lp01g_51[] = { 0x46, 0xff, 0x00, 0x00, 0x00, 0x50 }; +static CVI_U8 data_3aml069lp01g_52[] = { 0x4b, 0x88 }; +static CVI_U8 data_3aml069lp01g_53[] = { 0x60, 0x3c, 0x05, 0x07, 0x19, 0x1d }; +static CVI_U8 data_3aml069lp01g_54[] = { 0x65, 0x1b, 0x1f, 0x11, 0x11, 0x3c }; +static CVI_U8 data_3aml069lp01g_55[] = { 0x6a, 0x3c, 0x3c, 0x3c, 0x15, 0x15 }; +static CVI_U8 data_3aml069lp01g_56[] = { 0x6f, 0x13, 0x13, 0x17, 0x17, 0x01 }; +static CVI_U8 data_3aml069lp01g_57[] = { 0x74, 0x03, 0x3c }; +static CVI_U8 data_3aml069lp01g_58[] = { 0x80, 0x3c, 0x04, 0x06, 0x18, 0x1c }; +static CVI_U8 data_3aml069lp01g_59[] = { 0x85, 0x1a, 0x1e, 0x10, 0x10, 0x3c }; +static CVI_U8 data_3aml069lp01g_60[] = { 0x8a, 0x3c, 0x3c, 0x3c, 0x14, 0x14 }; +static CVI_U8 data_3aml069lp01g_61[] = { 0x8f, 0x12, 0x12, 0x16, 0x16, 0x00 }; +static CVI_U8 data_3aml069lp01g_62[] = { 0x94, 0x02, 0x3c }; +static CVI_U8 data_3aml069lp01g_63[] = { 0xea, 0x00, 0x00 }; +static CVI_U8 data_3aml069lp01g_64[] = { 0xee, 0x00 }; +static CVI_U8 data_3aml069lp01g_65[] = { 0x11 }; +static CVI_U8 data_3aml069lp01g_66[] = { 0x29 }; +#ifdef _MIPI_TX_BIST_MODE +static CVI_U8 data_3aml069lp01g_67[] = { 0xee, 0x60 }; +static CVI_U8 data_3aml069lp01g_68[] = { 0xea, 0x7a, 0xaa }; + +static CVI_U8 data_3aml069lp01g_69[] = { 0x21, 0x10 }; +static CVI_U8 data_3aml069lp01g_70[] = { 0x11 }; +static CVI_U8 data_3aml069lp01g_71[] = { 0x29 }; +#endif +const struct dsc_instr dsi_init_cmds_3AML069LP01G_600x1024[] = { + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_0 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_1 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_2 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_3 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_3aml069lp01g_4 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_5 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_6 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_7 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_8 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_11 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_16 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_17 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_18 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_19 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_20 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_21 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_22 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_23 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_24 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_25 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_26 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_27 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_28 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_29 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_30 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_31 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_32 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_33 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_34 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_35 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_36 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_37 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_38 }, + {.delay = 0, .data_type = 0x29, .size = 5, .data = data_3aml069lp01g_39 }, + {.delay = 0, .data_type = 0x29, .size = 5, .data = data_3aml069lp01g_40 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_41 }, + {.delay = 0, .data_type = 0x29, .size = 5, .data = data_3aml069lp01g_42 }, + {.delay = 0, .data_type = 0x29, .size = 5, .data = data_3aml069lp01g_43 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_44 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_45 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_46 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_47 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_48 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_49 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_50 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_51 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_52 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_53 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_54 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_55 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_56 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_57 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_58 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_59 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_60 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_3aml069lp01g_61 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_62 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_63 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_64 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_3aml069lp01g_65 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_3aml069lp01g_66 } +#ifdef _MIPI_TX_BIST_MODE + { .delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_67 }, + { .delay = 200, .data_type = 0x29, .size = 3, .data = data_3aml069lp01g_68 }, + + { .delay = 0, .data_type = 0x15, .size = 2, .data = data_3aml069lp01g_69 }, + { .delay = 40, .data_type = 0x05, .size = 1, .data = data_3aml069lp01g_70 }, + { .delay = 1, .data_type = 0x05, .size = 1, .data = data_3aml069lp01g_71 }, +#endif +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM__3AML069LP01G_H_ diff --git a/middleware/v2/component/panel/cv181x/dsi_gm8775c.h b/middleware/v2/component/panel/cv181x/dsi_gm8775c.h new file mode 100644 index 000000000..0344a4bf0 --- /dev/null +++ b/middleware/v2/component/panel/cv181x/dsi_gm8775c.h @@ -0,0 +1,160 @@ +#ifndef _MIPI_TX_PARAM_GM8775C_1080P_H_ +#define _MIPI_TX_PARAM_GM8775C_1080P_H_ + +#include +#include "linux/cvi_comm_mipi_tx.h" + +#define _BIST_COLOR 0 + +#define _HX8775C_RX_HACT 1920 +#define _HX8775C_RX_HFP 88 +#define _HX8775C_RX_HSA 44 +#define _HX8775C_RX_HBP 148 + +#define _HX8775C_RX_VACT 1080 +#define _HX8775C_RX_VFP 4 +#define _HX8775C_RX_VSA 5 +#define _HX8775C_RX_VBP 36 + +#define PIXEL_CLK(x) ((x##_VACT + x##_VSA + x##_VBP + x##_VFP) \ + * (x##_HACT + x##_HSA + x##_HBP + x##_HFP) * 60 / 1000) + +struct combo_dev_cfg_s dev_cfg_gm8775c = { + .devno = 0, +#ifdef MIPI_PANEL_2_LANES + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, -1, -1}, +#else + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, MIPI_TX_LANE_2, MIPI_TX_LANE_3}, +#endif + .lane_pn_swap = {true, true, true, true, true}, + + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = _HX8775C_RX_HSA, + .vid_hbp_pixels = _HX8775C_RX_HBP, + .vid_hfp_pixels = _HX8775C_RX_HFP, + .vid_hline_pixels = _HX8775C_RX_HACT, + .vid_vsa_lines = _HX8775C_RX_VSA, + .vid_vbp_lines = _HX8775C_RX_VBP, + .vid_vfp_lines = _HX8775C_RX_VFP, + .vid_active_lines = _HX8775C_RX_VACT, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = PIXEL_CLK(_HX8775C_RX), +}; + +const struct hs_settle_s hs_timing_cfg_gm8775c = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_gm8775c_0[] = { 0x27, 0xAA }; +static CVI_U8 data_gm8775c_1[] = { 0x48, 0x02 }; +static CVI_U8 data_gm8775c_2[] = { 0xB6, 0x20 }; +static CVI_U8 data_gm8775c_3[] = { 0x01, 0x80 }; +static CVI_U8 data_gm8775c_4[] = { 0x02, 0x38 }; +static CVI_U8 data_gm8775c_5[] = { 0x03, 0x47 }; +static CVI_U8 data_gm8775c_6[] = { 0x04, 0x58 }; +static CVI_U8 data_gm8775c_7[] = { 0x05, 0x2c }; +static CVI_U8 data_gm8775c_8[] = { 0x06, 0x94 }; +static CVI_U8 data_gm8775c_9[] = { 0x07, 0x00 }; +static CVI_U8 data_gm8775c_10[] = { 0x08, 0x04 }; +static CVI_U8 data_gm8775c_11[] = { 0x09, 0x05 }; +static CVI_U8 data_gm8775c_12[] = { 0x0A, 0x24 }; + +//use mipi clk +static CVI_U8 data_gm8775c_13[] = { 0x0B, 0x82 }; +static CVI_U8 data_gm8775c_14[] = { 0x0C, 0x14 }; + +static CVI_U8 data_gm8775c_15[] = { 0x0D, 0x01 }; +static CVI_U8 data_gm8775c_16[] = { 0x0E, 0x80 }; +static CVI_U8 data_gm8775c_17[] = { 0x0F, 0x20 }; +static CVI_U8 data_gm8775c_18[] = { 0x10, 0x20 }; +static CVI_U8 data_gm8775c_19[] = { 0x11, 0x03 }; +static CVI_U8 data_gm8775c_20[] = { 0x12, 0x1B }; +static CVI_U8 data_gm8775c_21[] = { 0x13, 0x53 }; +static CVI_U8 data_gm8775c_22[] = { 0x14, 0x01 }; +static CVI_U8 data_gm8775c_23[] = { 0x15, 0x23 }; +static CVI_U8 data_gm8775c_24[] = { 0x16, 0x40 }; +static CVI_U8 data_gm8775c_25[] = { 0x17, 0x00 }; +static CVI_U8 data_gm8775c_26[] = { 0x18, 0x01 }; +static CVI_U8 data_gm8775c_27[] = { 0x19, 0x23 }; +static CVI_U8 data_gm8775c_28[] = { 0x1A, 0x40 }; +static CVI_U8 data_gm8775c_29[] = { 0x1B, 0x00 }; +static CVI_U8 data_gm8775c_30[] = { 0x1E, 0x46 }; +static CVI_U8 data_gm8775c_31[] = { 0x51, 0x30 }; +static CVI_U8 data_gm8775c_32[] = { 0x1F, 0x10 }; +//debug +// static CVI_U8 data_gm8775c_35[] = { 0x7B, 0x4E }; +// static CVI_U8 data_gm8775c_36[] = { 0x7C, 0x4F }; +// static CVI_U8 data_gm8775c_37[] = { 0x7D, 0x4D }; + +#if _BIST_COLOR +static CVI_U8 data_gm8775c_33[] = { 0x2A, 0x4D }; +#else +static CVI_U8 data_gm8775c_34[] = { 0x2A, 0x01 }; + +// static CVI_U8 data_gm8775c_35[] = { 0x6A, 0x08 }; +// static CVI_U8 data_gm8775c_36[] = { 0x6C, 0x9E }; +// static CVI_U8 data_gm8775c_37[] = { 0x6D, 0x07 }; +// static CVI_U8 data_gm8775c_38[] = { 0x6E, 0x00 }; +// static CVI_U8 data_gm8775c_39[] = { 0x6F, 0x8A }; +// static CVI_U8 data_gm8775c_40[] = { 0x70, 0x19 }; +// static CVI_U8 data_gm8775c_41[] = { 0x71, 0x00 }; +#endif + +const struct dsc_instr dsi_init_cmds_gm8775c[] = { + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_0 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_1 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_2 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_3 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_4 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_5 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_6 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_7 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_8 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_9 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_10 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_11 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_12 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_13 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_14 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_15 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_16 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_17 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_18 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_19 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_20 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_21 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_22 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_23 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_24 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_25 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_26 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_27 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_28 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_29 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_30 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_31 }, + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_32 }, + //debug + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_35 }, + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_36 }, + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_37 }, +#if _BIST_COLOR + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_33 }, +#else + {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_34 } + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_35 }, + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_36 }, + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_37 }, + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_38 }, + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_39 }, + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_40 }, + // {.delay = 0, .data_type = 0x23, .size = 2, .data = data_gm8775c_41 } +#endif +}; +#endif +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_GM8775C_1080P_H_ diff --git a/middleware/v2/component/panel/cv181x/dsi_hx8394_evb.h b/middleware/v2/component/panel/cv181x/dsi_hx8394_evb.h new file mode 100644 index 000000000..48f4ba9fa --- /dev/null +++ b/middleware/v2/component/panel/cv181x/dsi_hx8394_evb.h @@ -0,0 +1,125 @@ +#ifndef _MIPI_TX_PARAM_HX8394_H_ +#define _MIPI_TX_PARAM_HX8394_H_ + +#include +#include + +const struct combo_dev_cfg_s dev_cfg_hx8394_720x1280 = { + .devno = 0, +#ifdef MIPI_PANEL_2_LANES + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, -1, -1}, +#else + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, MIPI_TX_LANE_2, MIPI_TX_LANE_3}, +#endif + .lane_pn_swap = {true, true, true, true, true}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = 64, + .vid_hbp_pixels = 36, + .vid_hfp_pixels = 128, + .vid_hline_pixels = 720, + .vid_vsa_lines = 16, + .vid_vbp_lines = 4, + .vid_vfp_lines = 6, + .vid_active_lines = 1280, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 74250, +}; + +const struct hs_settle_s hs_timing_cfg_hx8394_720x1280 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_hx8394_0[] = { 0xb9, 0xff, 0x83, 0x94 }; +static CVI_U8 data_hx8394_1[] = { + 0xb1, 0x50, 0x15, 0x75, 0x09, 0x32, 0x44, 0x71, 0x31, 0x4d, + 0x2f, 0x56, 0x73, 0x02, 0x02 +}; +static CVI_U8 data_hx8394_2[] = { +#ifdef MIPI_PANEL_2_LANES + 0xba, 0x61, 0x03, 0x68, 0x6b, 0xb2, 0xc0 +#else + 0xba, 0x63, 0x03, 0x68, 0x6b, 0xb2, 0xc0 +#endif +}; +static CVI_U8 data_hx8394_3[] = { 0xd2, 0x88 }; +static CVI_U8 data_hx8394_4[] = { 0xb2, 0x00, 0x80, 0x64, 0x10, 0x07 }; +static CVI_U8 data_hx8394_5[] = { + 0xb4, 0x01, 0x75, 0x01, 0x75, 0x01, 0x75, 0x01, 0x0c, 0x86, + 0x75, 0x00, 0x3f, 0x01, 0x75, 0x01, 0x75, 0x01, 0x75, 0x01, + 0x0c, 0x86 +}; +static CVI_U8 data_hx8394_6[] = { + 0xd3, 0x00, 0x00, 0x06, 0x06, 0x40, 0x1a, 0x08, 0x00, 0x32, + 0x10, 0x08, 0x00, 0x08, 0x54, 0x15, 0x10, 0x05, 0x04, 0x02, + 0x12, 0x10, 0x05, 0x07, 0x23, 0x23, 0x0c, 0x0c, 0x27, 0x10, + 0x07, 0x07, 0x10, 0x40 +}; +static CVI_U8 data_hx8394_7[] = { + 0xd5, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x20, + 0x21, 0x22, 0x23, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x19, 0x19, 0x18, 0x18, 0x18, 0x18, 0x1b, 0x1b, 0x1a, + 0x1a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18 +}; +static CVI_U8 data_hx8394_8[] = { + 0xd6, 0x03, 0x02, 0x01, 0x00, 0x07, 0x06, 0x05, 0x04, 0x23, + 0x22, 0x21, 0x20, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x58, + 0x58, 0x18, 0x18, 0x19, 0x19, 0x18, 0x18, 0x1b, 0x1b, 0x1a, + 0x1a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18 +}; +static CVI_U8 data_hx8394_9[] = { + 0xe0, 0x00, 0x1a, 0x24, 0x2c, 0x2e, 0x32, 0x34, 0x32, 0x66, + 0x73, 0x82, 0x7f, 0x85, 0x95, 0x97, 0x99, 0xa4, 0xa5, 0xa0, + 0xab, 0xba, 0x5a, 0x59, 0x5d, 0x61, 0x63, 0x6c, 0x72, 0x7f, + 0x00, 0x19, 0x24, 0x2c, 0x2e, 0x32, 0x34, 0x32, 0x66, 0x73, + 0x82, 0x7f, 0x85, 0x95, 0x97, 0x99, 0xa4, 0xa5, 0xa0, 0xab, + 0xba, 0x5a, 0x59, 0x5d, 0x61, 0x63, 0x6c, 0x72, 0x7f +}; +static CVI_U8 data_hx8394_10[] = { 0xcc, 0x03 }; +static CVI_U8 data_hx8394_11[] = { 0xc0, 0x1f, 0x73 }; +static CVI_U8 data_hx8394_12[] = { 0xb6, 0x42, 0x42 }; +static CVI_U8 data_hx8394_13[] = { 0xd4, 0x02 }; +static CVI_U8 data_hx8394_14[] = { 0xbd, 0x01 }; +static CVI_U8 data_hx8394_15[] = { 0xb1, 0x00 }; +static CVI_U8 data_hx8394_16[] = { 0xbd, 0x00 }; +static CVI_U8 data_hx8394_17[] = { + 0xbf, 0x40, 0x81, 0x50, 0x00, 0x1a, 0xfc, 0x01 +}; +static CVI_U8 data_hx8394_18[] = { 0xc6, 0xef }; +static CVI_U8 data_hx8394_19[] = { 0x36, 0x02 };// h-flip +static CVI_U8 data_hx8394_20[] = { 0x11 }; +static CVI_U8 data_hx8394_21[] = { 0x29 }; + +const struct dsc_instr dsi_init_cmds_hx8394_720x1280[] = { + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_hx8394_0 }, + {.delay = 0, .data_type = 0x29, .size = 15, .data = data_hx8394_1 }, + {.delay = 0, .data_type = 0x29, .size = 7, .data = data_hx8394_2 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8394_3 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_hx8394_4 }, + {.delay = 0, .data_type = 0x29, .size = 22, .data = data_hx8394_5 }, + {.delay = 0, .data_type = 0x29, .size = 34, .data = data_hx8394_6 }, + {.delay = 0, .data_type = 0x29, .size = 45, .data = data_hx8394_7 }, + {.delay = 0, .data_type = 0x29, .size = 45, .data = data_hx8394_8 }, + {.delay = 0, .data_type = 0x29, .size = 59, .data = data_hx8394_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8394_10 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_hx8394_11 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_hx8394_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8394_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8394_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8394_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8394_16 }, + {.delay = 0, .data_type = 0x29, .size = 8, .data = data_hx8394_17 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8394_18 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8394_19 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_hx8394_20 }, + {.delay = 20, .data_type = 0x05, .size = 1, .data = data_hx8394_21 } + +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_HX8394_H_ diff --git a/middleware/v2/component/panel/cv181x/dsi_hx8399_1080p.h b/middleware/v2/component/panel/cv181x/dsi_hx8399_1080p.h new file mode 100644 index 000000000..57b27c22a --- /dev/null +++ b/middleware/v2/component/panel/cv181x/dsi_hx8399_1080p.h @@ -0,0 +1,194 @@ +#ifndef _MIPI_TX_PARAM_HX8399_1080P_H_ +#define _MIPI_TX_PARAM_HX8399_1080P_H_ + +#include +#include + +#define HX8399_HACT 1080 +#define HX8399_HSA 5 +#define HX8399_HBP 148 +#define HX8399_HFP 5 + +#define HX8399_VACT 1920 +#define HX8399_VSA 6 +#define HX8399_VBP 2 +#define HX8399_VFP 2 + +#define PIXEL_CLK(x) ((x##_VACT + x##_VSA + x##_VBP + x##_VFP) \ + * (x##_HACT + x##_HSA + x##_HBP + x##_HFP) * 60 / 1000) + +const struct combo_dev_cfg_s dev_cfg_hx8399_1080x1920 = { + .devno = 0, +#ifdef MIPI_PANEL_2_LANES + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, -1, -1}, +#else + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, MIPI_TX_LANE_2, MIPI_TX_LANE_3}, +#endif + .lane_pn_swap = {true, true, true, true, true}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = HX8399_HSA, + .vid_hbp_pixels = HX8399_HBP, + .vid_hfp_pixels = HX8399_HFP, + .vid_hline_pixels = HX8399_HACT, + .vid_vsa_lines = HX8399_VSA, + .vid_vbp_lines = HX8399_VBP, + .vid_vfp_lines = HX8399_VFP, + .vid_active_lines = HX8399_VACT, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = PIXEL_CLK(HX8399), +}; + +const struct hs_settle_s hs_timing_cfg_hx8399_1080x1920 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_hx8399_0[] = { + 0xB9, 0xFF, 0x83, 0x99, +}; +static CVI_U8 data_hx8399_1[] = { + 0xD2, 0x77, +}; +static CVI_U8 data_hx8399_2[] = { + 0xB1, 0x02, 0x04, 0x74, + 0x94, 0x01, 0x32, 0x33, + 0x11, 0x11, 0xAB, 0x4D, + 0x56, 0x73, 0x02, 0x02, +}; +static CVI_U8 data_hx8399_3[] = { + 0xB2, 0x00, 0x80, 0x80, + 0xAE, 0x05, 0x07, 0x5A, + 0x11, 0x00, 0x00, 0x10, + 0x1E, 0x70, 0x03, 0xD4, +}; +static CVI_U8 data_hx8399_4[] = { + 0xB4, 0x00, 0xFF, 0x02, + 0xC0, 0x02, 0xC0, 0x00, + 0x00, 0x08, 0x00, 0x04, + 0x06, 0x00, 0x32, 0x04, + 0x0A, 0x08, 0x21, 0x03, + 0x01, 0x00, 0x0F, 0xB8, + 0x8B, 0x02, 0xC0, 0x02, + 0xC0, 0x00, 0x00, 0x08, + 0x00, 0x04, 0x06, 0x00, + 0x32, 0x04, 0x0A, 0x08, + 0x01, 0x00, 0x0F, 0xB8, + 0x01, +}; +static CVI_U8 data_hx8399_5[] = { + 0xD3, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x10, 0x04, + 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x05, 0x05, + 0x07, 0x00, 0x00, 0x00, + 0x05, 0x40, +}; +static CVI_U8 data_hx8399_6[] = { + 0xD5, 0x18, 0x18, 0x19, + 0x19, 0x18, 0x18, 0x21, + 0x20, 0x01, 0x00, 0x07, + 0x06, 0x05, 0x04, 0x03, + 0x02, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x2F, + 0x2F, 0x30, 0x30, 0x31, + 0x31, 0x18, 0x18, 0x18, + 0x18, +}; +static CVI_U8 data_hx8399_7[] = { + 0xD6, 0x18, 0x18, 0x19, + 0x19, 0x40, 0x40, 0x20, + 0x21, 0x06, 0x07, 0x00, + 0x01, 0x02, 0x03, 0x04, + 0x05, 0x40, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x2F, + 0x2F, 0x30, 0x30, 0x31, + 0x31, 0x40, 0x40, 0x40, + 0x40, +}; +static CVI_U8 data_hx8399_8[] = { + 0xD8, 0xA2, 0xAA, 0x02, + 0xA0, 0xA2, 0xA8, 0x02, + 0xA0, 0xB0, 0x00, 0x00, + 0x00, 0xB0, 0x00, 0x00, + 0x00, +}; +static CVI_U8 data_hx8399_9[] = { + 0xBD, 0x01, +}; +static CVI_U8 data_hx8399_10[] = { + 0xD8, 0xB0, 0x00, 0x00, + 0x00, 0xB0, 0x00, 0x00, + 0x00, 0xE2, 0xAA, 0x03, + 0xF0, 0xE2, 0xAA, 0x03, + 0xF0, +}; +static CVI_U8 data_hx8399_11[] = { + 0xBD, 0x02, +}; +static CVI_U8 data_hx8399_12[] = { + 0xD8, 0xE2, 0xAA, 0x03, + 0xF0, 0xE2, 0xAA, 0x03, + 0xF0, +}; +static CVI_U8 data_hx8399_13[] = { + 0xBD, 0x00, +}; +static CVI_U8 data_hx8399_14[] = { + 0xB6, 0x8D, 0x8D +}; +static CVI_U8 data_hx8399_15[] = { + 0xE0, 0x00, 0x0E, 0x19, + 0x13, 0x2E, 0x39, 0x48, + 0x44, 0x4D, 0x57, 0x5F, + 0x66, 0x6C, 0x76, 0x7F, + 0x85, 0x8A, 0x95, 0x9A, + 0xA4, 0x9B, 0xAB, 0xB0, + 0x5C, 0x58, 0x64, 0x77, + 0x00, 0x0E, 0x19, 0x13, + 0x2E, 0x39, 0x48, 0x44, + 0x4D, 0x57, 0x5F, 0x66, + 0x6C, 0x76, 0x7F, 0x85, + 0x8A, 0x95, 0x9A, 0xA4, + 0x9B, 0xAB, 0xB0, 0x5C, + 0x58, 0x64, 0x77, +}; +static CVI_U8 data_hx8399_16[] = { + 0xcc, 0x08, +}; +static CVI_U8 data_hx8399_17[] = { + 0x11, 0x00 +}; +static CVI_U8 data_hx8399_18[] = { + 0x29, 0x00 +}; + +const struct dsc_instr dsi_init_cmds_hx8399_1080x1920[] = { + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_hx8399_0 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8399_1 }, + {.delay = 0, .data_type = 0x29, .size = 16, .data = data_hx8399_2 }, + {.delay = 0, .data_type = 0x29, .size = 16, .data = data_hx8399_3 }, + {.delay = 0, .data_type = 0x29, .size = 45, .data = data_hx8399_4 }, + {.delay = 10, .data_type = 0x29, .size = 34, .data = data_hx8399_5 }, + {.delay = 10, .data_type = 0x29, .size = 33, .data = data_hx8399_6 }, + {.delay = 10, .data_type = 0x29, .size = 33, .data = data_hx8399_7 }, + {.delay = 0, .data_type = 0x29, .size = 17, .data = data_hx8399_8 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8399_9 }, + {.delay = 0, .data_type = 0x29, .size = 17, .data = data_hx8399_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8399_11 }, + {.delay = 0, .data_type = 0x29, .size = 9, .data = data_hx8399_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8399_13 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_hx8399_14 }, + {.delay = 10, .data_type = 0x29, .size = 55, .data = data_hx8399_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_hx8399_16 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_hx8399_17 }, + {.delay = 20, .data_type = 0x05, .size = 1, .data = data_hx8399_18 }, +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_HX8399_1080P_H_ diff --git a/middleware/v2/component/panel/cv181x/dsi_icn9707.h b/middleware/v2/component/panel/cv181x/dsi_icn9707.h new file mode 100644 index 000000000..5a0e42f4c --- /dev/null +++ b/middleware/v2/component/panel/cv181x/dsi_icn9707.h @@ -0,0 +1,130 @@ +#ifndef _MIPI_TX_PARAM_ICN9707_H_ +#define _MIPI_TX_PARAM_ICN9707_H_ + +#include +#include + +const struct combo_dev_cfg_s dev_cfg_icn9707_480x1920 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_3, MIPI_TX_LANE_2, MIPI_TX_LANE_CLK, MIPI_TX_LANE_1, MIPI_TX_LANE_0}, + .lane_pn_swap = {true, true, true, true, true}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = 4, + .vid_hbp_pixels = 53, + .vid_hfp_pixels = 53, + .vid_hline_pixels = 480, + .vid_vsa_lines = 4, + .vid_vbp_lines = 12, + .vid_vfp_lines = 32, + .vid_active_lines = 1920, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 69660, +}; + +const struct hs_settle_s hs_timing_cfg_icn9707_480x1920 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_icn9707_0[] = { 0xf0, 0x5a, 0x59 }; +static CVI_U8 data_icn9707_1[] = { 0xf1, 0xa5, 0xa6 }; +static CVI_U8 data_icn9707_2[] = { + 0xb4, 0x1d, 0x1c, 0x0b, 0x10, 0x11, 0x12, 0x13, 0x0c, 0x0d, + 0x0e, 0x0f, 0x00, 0x1e, 0x1f, 0x04, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03 +}; +static CVI_U8 data_icn9707_3[] = { + 0xb0, 0x60, 0x00, 0x00, 0x08, 0x66, 0x66, 0x33, 0x33, 0x66, + 0x00, 0x00, 0xaf, 0x00, 0x00, 0x0f +}; +static CVI_U8 data_icn9707_4[] = { + 0xb1, 0x53, 0xa0, 0x00, 0x85, 0x0e, 0x00, 0x00, 0x62, 0x00, + 0x00 +}; +static CVI_U8 data_icn9707_5[] = { + 0xb2, 0x37, 0x09, 0x08, 0x8b, 0x08, 0x00, 0x22, 0x00, 0x44, + 0xd9 +}; +static CVI_U8 data_icn9707_6[] = { 0xb6, 0x49, 0x49 }; +static CVI_U8 data_icn9707_7[] = { + 0xb7, 0x01, 0x01, 0x09, 0x0d, 0x11, 0x19, 0x1d, 0x15, 0x00, + 0x25, 0x21, 0x00, 0x00, 0x00, 0x00, 0x02, 0xf7, 0x38 +}; +static CVI_U8 data_icn9707_8[] = { 0xb8, 0x34, 0x53, 0x02, 0xcc }; +static CVI_U8 data_icn9707_9[] = { 0xba, 0x27, 0x33 }; +static CVI_U8 data_icn9707_10[] = { + 0xbd, 0x43, 0x0e, 0x0e, 0x4b, 0x4b, 0x14, 0x14 +}; +static CVI_U8 data_icn9707_11[] = { + 0xc1, 0x00, 0x0c, 0x20, 0x04, 0x00, 0x32, 0x32, 0x04 +}; +static CVI_U8 data_icn9707_12[] = { 0xc2, 0x31, 0xc0 }; +static CVI_U8 data_icn9707_13[] = { 0xc3, 0x22, 0x31 }; +static CVI_U8 data_icn9707_14[] = { + 0xc6, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00 +}; +static CVI_U8 data_icn9707_15[] = { + 0xc8, 0x7c, 0x66, 0x56, 0x49, 0x46, 0x37, 0x3a, 0x23, 0x3b, + 0x38, 0x38, 0x55, 0x43, 0x4c, 0x40, 0x3c, 0x2f, 0x1c, 0x06, + 0x7c, 0x65, 0x56, 0x4a, 0x46, 0x37, 0x3a, 0x23, 0x3a, 0x38, + 0x38, 0x55, 0x43, 0x4c, 0x40, 0x3c, 0x2f, 0x1c, 0x06 +}; +static CVI_U8 data_icn9707_16[] = { 0xd0, 0x07, 0xff, 0xff }; +static CVI_U8 data_icn9707_17[] = { 0xd2, 0x63, 0x0b, 0x08, 0x88 }; +static CVI_U8 data_icn9707_18[] = { + 0xd4, 0x00, 0x00, 0x00, 0x32, 0x04, 0x54 +}; +static CVI_U8 data_icn9707_19[] = { 0xf1, 0x5a, 0x59 }; +static CVI_U8 data_icn9707_20[] = { 0xf0, 0xa5, 0xa6 }; +static CVI_U8 data_icn9707_21[] = { 0x11 }; +static CVI_U8 data_icn9707_22[] = { 0x29 }; + +#ifdef _MIPI_TX_BIST_MODE +static CVI_U8 data_icn9707_23[] = { 0x01 }; +static CVI_U8 data_icn9707_24[] = { 0xF0, 0x5A, 0x59 }; +static CVI_U8 data_icn9707_25[] = { 0xF1, 0xA5, 0xA6 }; +static CVI_U8 data_icn9707_26[] = { 0xC0, 0x11 }; +static CVI_U8 data_icn9707_27[] = { 0x11 }; +static CVI_U8 data_icn9707_28[] = { 0x29 }; +#endif + +const struct dsc_instr dsi_init_cmds_icn9707_480x1920[] = { +#ifdef _MIPI_TX_BIST_MODE + { .delay = 120, .data_type = 0x05, .size = 1, .data = data_icn9707_23 }, + { .delay = 0, .data_type = 0x29, .size = 3, .data = data_icn9707_24 }, + { .delay = 0, .data_type = 0x29, .size = 1, .data = data_icn9707_25 }, + { .delay = 0, .data_type = 0x15, .size = 2, .data = data_icn9707_26 }, + { .delay = 200, .data_type = 0x05, .size = 1, .data = data_icn9707_27 }, + { .delay = 50, .data_type = 0x05, .size = 1, .data = data_icn9707_28 } +#else + {.delay = 1, .data_type = 0x29, .size = 3, .data = data_icn9707_0 }, + {.delay = 1, .data_type = 0x29, .size = 3, .data = data_icn9707_1 }, + {.delay = 1, .data_type = 0x29, .size = 23, .data = data_icn9707_2 }, + {.delay = 1, .data_type = 0x29, .size = 16, .data = data_icn9707_3 }, + {.delay = 1, .data_type = 0x29, .size = 11, .data = data_icn9707_4 }, + {.delay = 1, .data_type = 0x29, .size = 11, .data = data_icn9707_5 }, + {.delay = 1, .data_type = 0x29, .size = 3, .data = data_icn9707_6 }, + {.delay = 1, .data_type = 0x29, .size = 19, .data = data_icn9707_7 }, + {.delay = 1, .data_type = 0x29, .size = 5, .data = data_icn9707_8 }, + {.delay = 1, .data_type = 0x29, .size = 3, .data = data_icn9707_9 }, + {.delay = 1, .data_type = 0x29, .size = 8, .data = data_icn9707_10 }, + {.delay = 1, .data_type = 0x29, .size = 9, .data = data_icn9707_11 }, + {.delay = 1, .data_type = 0x29, .size = 3, .data = data_icn9707_12 }, + {.delay = 1, .data_type = 0x29, .size = 3, .data = data_icn9707_13 }, + {.delay = 1, .data_type = 0x29, .size = 9, .data = data_icn9707_14 }, + {.delay = 1, .data_type = 0x29, .size = 39, .data = data_icn9707_15 }, + {.delay = 1, .data_type = 0x29, .size = 4, .data = data_icn9707_16 }, + {.delay = 1, .data_type = 0x29, .size = 5, .data = data_icn9707_17 }, + {.delay = 1, .data_type = 0x29, .size = 7, .data = data_icn9707_18 }, + {.delay = 1, .data_type = 0x29, .size = 3, .data = data_icn9707_19 }, + {.delay = 1, .data_type = 0x29, .size = 3, .data = data_icn9707_20 }, + {.delay = 200, .data_type = 0x05, .size = 1, .data = data_icn9707_21 }, + {.delay = 50, .data_type = 0x05, .size = 1, .data = data_icn9707_22 } +#endif +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_ICN9707_H_ diff --git a/middleware/v2/component/panel/cv181x/dsi_ili9881c.h b/middleware/v2/component/panel/cv181x/dsi_ili9881c.h new file mode 100644 index 000000000..8ff5e47cc --- /dev/null +++ b/middleware/v2/component/panel/cv181x/dsi_ili9881c.h @@ -0,0 +1,429 @@ +#ifndef _MIPI_TX_PARAM_ILI9881C_H_ +#define _MIPI_TX_PARAM_ILI9881C_H_ + +#include +#include + +const struct combo_dev_cfg_s dev_cfg_ili9881c_720x1280 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, MIPI_TX_LANE_2, MIPI_TX_LANE_3}, + .lane_pn_swap = {false, false, false, false, false}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = 64, + .vid_hbp_pixels = 36, + .vid_hfp_pixels = 128, + .vid_hline_pixels = 720, + .vid_vsa_lines = 16, + .vid_vbp_lines = 4, + .vid_vfp_lines = 6, + .vid_active_lines = 1280, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 74250, +}; + +const struct hs_settle_s hs_timing_cfg_ili9881c_720x1280 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_ili9881c_0[] = { 0xff, 0x98, 0x81, 0x03 }; +static CVI_U8 data_ili9881c_1[] = { 0x01, 0x00 }; +static CVI_U8 data_ili9881c_2[] = { 0x02, 0x00 }; +static CVI_U8 data_ili9881c_3[] = { 0x03, 0x73 }; +static CVI_U8 data_ili9881c_4[] = { 0x04, 0x00 }; +static CVI_U8 data_ili9881c_5[] = { 0x05, 0x00 }; +static CVI_U8 data_ili9881c_6[] = { 0x06, 0x0a }; +static CVI_U8 data_ili9881c_7[] = { 0x07, 0x00 }; +static CVI_U8 data_ili9881c_8[] = { 0x08, 0x00 }; +static CVI_U8 data_ili9881c_9[] = { 0x09, 0x01 }; +static CVI_U8 data_ili9881c_10[] = { 0x0a, 0x00 }; +static CVI_U8 data_ili9881c_11[] = { 0x0b, 0x00 }; +static CVI_U8 data_ili9881c_12[] = { 0x0c, 0x01 }; +static CVI_U8 data_ili9881c_13[] = { 0x0d, 0x00 }; +static CVI_U8 data_ili9881c_14[] = { 0x0e, 0x00 }; +static CVI_U8 data_ili9881c_15[] = { 0x0f, 0x1d }; +static CVI_U8 data_ili9881c_16[] = { 0x10, 0x1d }; +static CVI_U8 data_ili9881c_17[] = { 0x11, 0x00 }; +static CVI_U8 data_ili9881c_18[] = { 0x12, 0x00 }; +static CVI_U8 data_ili9881c_19[] = { 0x13, 0x00 }; +static CVI_U8 data_ili9881c_20[] = { 0x14, 0x00 }; +static CVI_U8 data_ili9881c_21[] = { 0x15, 0x00 }; +static CVI_U8 data_ili9881c_22[] = { 0x16, 0x00 }; +static CVI_U8 data_ili9881c_23[] = { 0x17, 0x00 }; +static CVI_U8 data_ili9881c_24[] = { 0x18, 0x00 }; +static CVI_U8 data_ili9881c_25[] = { 0x19, 0x00 }; +static CVI_U8 data_ili9881c_26[] = { 0x1a, 0x00 }; +static CVI_U8 data_ili9881c_27[] = { 0x1b, 0x00 }; +static CVI_U8 data_ili9881c_28[] = { 0x1c, 0x00 }; +static CVI_U8 data_ili9881c_29[] = { 0x1d, 0x00 }; +static CVI_U8 data_ili9881c_30[] = { 0x1e, 0x40 }; +static CVI_U8 data_ili9881c_31[] = { 0x1f, 0x80 }; +static CVI_U8 data_ili9881c_32[] = { 0x20, 0x06 }; +static CVI_U8 data_ili9881c_33[] = { 0x21, 0x02 }; +static CVI_U8 data_ili9881c_34[] = { 0x22, 0x00 }; +static CVI_U8 data_ili9881c_35[] = { 0x23, 0x00 }; +static CVI_U8 data_ili9881c_36[] = { 0x24, 0x00 }; +static CVI_U8 data_ili9881c_37[] = { 0x25, 0x00 }; +static CVI_U8 data_ili9881c_38[] = { 0x26, 0x00 }; +static CVI_U8 data_ili9881c_39[] = { 0x27, 0x00 }; +static CVI_U8 data_ili9881c_40[] = { 0x28, 0x33 }; +static CVI_U8 data_ili9881c_41[] = { 0x29, 0x03 }; +static CVI_U8 data_ili9881c_42[] = { 0x2a, 0x00 }; +static CVI_U8 data_ili9881c_43[] = { 0x2b, 0x00 }; +static CVI_U8 data_ili9881c_44[] = { 0x2c, 0x00 }; +static CVI_U8 data_ili9881c_45[] = { 0x2d, 0x00 }; +static CVI_U8 data_ili9881c_46[] = { 0x2e, 0x00 }; +static CVI_U8 data_ili9881c_47[] = { 0x2f, 0x00 }; +static CVI_U8 data_ili9881c_48[] = { 0x30, 0x00 }; +static CVI_U8 data_ili9881c_49[] = { 0x31, 0x00 }; +static CVI_U8 data_ili9881c_50[] = { 0x32, 0x00 }; +static CVI_U8 data_ili9881c_51[] = { 0x33, 0x00 }; +static CVI_U8 data_ili9881c_52[] = { 0x34, 0x04 }; +static CVI_U8 data_ili9881c_53[] = { 0x35, 0x00 }; +static CVI_U8 data_ili9881c_54[] = { 0x36, 0x00 }; +static CVI_U8 data_ili9881c_55[] = { 0x37, 0x00 }; +static CVI_U8 data_ili9881c_56[] = { 0x38, 0x3c }; +static CVI_U8 data_ili9881c_57[] = { 0x39, 0x00 }; +static CVI_U8 data_ili9881c_58[] = { 0x3a, 0x40 }; +static CVI_U8 data_ili9881c_59[] = { 0x3b, 0x40 }; +static CVI_U8 data_ili9881c_60[] = { 0x3c, 0x00 }; +static CVI_U8 data_ili9881c_61[] = { 0x3d, 0x00 }; +static CVI_U8 data_ili9881c_62[] = { 0x3e, 0x00 }; +static CVI_U8 data_ili9881c_63[] = { 0x3f, 0x00 }; +static CVI_U8 data_ili9881c_64[] = { 0x40, 0x00 }; +static CVI_U8 data_ili9881c_65[] = { 0x41, 0x00 }; +static CVI_U8 data_ili9881c_66[] = { 0x42, 0x00 }; +static CVI_U8 data_ili9881c_67[] = { 0x43, 0x00 }; +static CVI_U8 data_ili9881c_68[] = { 0x44, 0x00 }; +static CVI_U8 data_ili9881c_69[] = { 0x50, 0x01 }; +static CVI_U8 data_ili9881c_70[] = { 0x51, 0x23 }; +static CVI_U8 data_ili9881c_71[] = { 0x52, 0x45 }; +static CVI_U8 data_ili9881c_72[] = { 0x53, 0x67 }; +static CVI_U8 data_ili9881c_73[] = { 0x54, 0x89 }; +static CVI_U8 data_ili9881c_74[] = { 0x55, 0xab }; +static CVI_U8 data_ili9881c_75[] = { 0x56, 0x01 }; +static CVI_U8 data_ili9881c_76[] = { 0x57, 0x23 }; +static CVI_U8 data_ili9881c_77[] = { 0x58, 0x45 }; +static CVI_U8 data_ili9881c_78[] = { 0x59, 0x67 }; +static CVI_U8 data_ili9881c_79[] = { 0x5a, 0x89 }; +static CVI_U8 data_ili9881c_80[] = { 0x5b, 0xab }; +static CVI_U8 data_ili9881c_81[] = { 0x5c, 0xcd }; +static CVI_U8 data_ili9881c_82[] = { 0x5d, 0xef }; +static CVI_U8 data_ili9881c_83[] = { 0x5e, 0x11 }; +static CVI_U8 data_ili9881c_84[] = { 0x5f, 0x01 }; +static CVI_U8 data_ili9881c_85[] = { 0x60, 0x00 }; +static CVI_U8 data_ili9881c_86[] = { 0x61, 0x15 }; +static CVI_U8 data_ili9881c_87[] = { 0x62, 0x14 }; +static CVI_U8 data_ili9881c_88[] = { 0x63, 0x0e }; +static CVI_U8 data_ili9881c_89[] = { 0x64, 0x0f }; +static CVI_U8 data_ili9881c_90[] = { 0x65, 0x0c }; +static CVI_U8 data_ili9881c_91[] = { 0x66, 0x0d }; +static CVI_U8 data_ili9881c_92[] = { 0x67, 0x06 }; +static CVI_U8 data_ili9881c_93[] = { 0x68, 0x02 }; +static CVI_U8 data_ili9881c_94[] = { 0x69, 0x07 }; +static CVI_U8 data_ili9881c_95[] = { 0x6a, 0x02 }; +static CVI_U8 data_ili9881c_96[] = { 0x6b, 0x02 }; +static CVI_U8 data_ili9881c_97[] = { 0x6c, 0x02 }; +static CVI_U8 data_ili9881c_98[] = { 0x6d, 0x02 }; +static CVI_U8 data_ili9881c_99[] = { 0x6e, 0x02 }; +static CVI_U8 data_ili9881c_100[] = { 0x6f, 0x02 }; +static CVI_U8 data_ili9881c_101[] = { 0x70, 0x02 }; +static CVI_U8 data_ili9881c_102[] = { 0x71, 0x02 }; +static CVI_U8 data_ili9881c_103[] = { 0x72, 0x02 }; +static CVI_U8 data_ili9881c_104[] = { 0x73, 0x02 }; +static CVI_U8 data_ili9881c_105[] = { 0x74, 0x02 }; +static CVI_U8 data_ili9881c_106[] = { 0x75, 0x01 }; +static CVI_U8 data_ili9881c_107[] = { 0x76, 0x00 }; +static CVI_U8 data_ili9881c_108[] = { 0x77, 0x14 }; +static CVI_U8 data_ili9881c_109[] = { 0x78, 0x15 }; +static CVI_U8 data_ili9881c_110[] = { 0x79, 0x0e }; +static CVI_U8 data_ili9881c_111[] = { 0x7a, 0x0f }; +static CVI_U8 data_ili9881c_112[] = { 0x7b, 0x0c }; +static CVI_U8 data_ili9881c_113[] = { 0x7c, 0x0d }; +static CVI_U8 data_ili9881c_114[] = { 0x7d, 0x06 }; +static CVI_U8 data_ili9881c_115[] = { 0x7e, 0x02 }; +static CVI_U8 data_ili9881c_116[] = { 0x7f, 0x07 }; +static CVI_U8 data_ili9881c_117[] = { 0x80, 0x02 }; +static CVI_U8 data_ili9881c_118[] = { 0x81, 0x02 }; +static CVI_U8 data_ili9881c_119[] = { 0x82, 0x02 }; +static CVI_U8 data_ili9881c_120[] = { 0x83, 0x02 }; +static CVI_U8 data_ili9881c_121[] = { 0x84, 0x02 }; +static CVI_U8 data_ili9881c_122[] = { 0x85, 0x02 }; +static CVI_U8 data_ili9881c_123[] = { 0x86, 0x02 }; +static CVI_U8 data_ili9881c_124[] = { 0x87, 0x02 }; +static CVI_U8 data_ili9881c_125[] = { 0x88, 0x02 }; +static CVI_U8 data_ili9881c_126[] = { 0x89, 0x02 }; +static CVI_U8 data_ili9881c_127[] = { 0x8a, 0x02 }; +static CVI_U8 data_ili9881c_128[] = { 0xff, 0x98, 0x81, 0x04 }; +static CVI_U8 data_ili9881c_129[] = { 0x6c, 0x15 }; +static CVI_U8 data_ili9881c_130[] = { 0x6e, 0x2b }; +static CVI_U8 data_ili9881c_131[] = { 0x6f, 0x33 }; +static CVI_U8 data_ili9881c_132[] = { 0x8d, 0x18 }; +static CVI_U8 data_ili9881c_133[] = { 0x87, 0xba }; +static CVI_U8 data_ili9881c_134[] = { 0x26, 0x76 }; +static CVI_U8 data_ili9881c_135[] = { 0xb2, 0xd1 }; +static CVI_U8 data_ili9881c_136[] = { 0xb5, 0x06 }; +static CVI_U8 data_ili9881c_137[] = { 0x3a, 0x24 }; +static CVI_U8 data_ili9881c_138[] = { 0x35, 0x1f }; +static CVI_U8 data_ili9881c_139[] = { 0xff, 0x98, 0x81, 0x01 }; +static CVI_U8 data_ili9881c_140[] = { 0x22, 0x09 }; +static CVI_U8 data_ili9881c_141[] = { 0x31, 0x00 }; +static CVI_U8 data_ili9881c_142[] = { 0x40, 0x33 }; +static CVI_U8 data_ili9881c_143[] = { 0x53, 0xa2 }; +static CVI_U8 data_ili9881c_144[] = { 0x55, 0x92 }; +static CVI_U8 data_ili9881c_145[] = { 0x50, 0x96 }; +static CVI_U8 data_ili9881c_146[] = { 0x51, 0x96 }; +static CVI_U8 data_ili9881c_147[] = { 0x60, 0x22 }; +static CVI_U8 data_ili9881c_148[] = { 0x61, 0x00 }; +static CVI_U8 data_ili9881c_149[] = { 0x62, 0x19 }; +static CVI_U8 data_ili9881c_150[] = { 0x63, 0x00 }; +static CVI_U8 data_ili9881c_151[] = { 0xa0, 0x08 }; +static CVI_U8 data_ili9881c_152[] = { 0xa1, 0x11 }; +static CVI_U8 data_ili9881c_153[] = { 0xa2, 0x19 }; +static CVI_U8 data_ili9881c_154[] = { 0xa3, 0x0d }; +static CVI_U8 data_ili9881c_155[] = { 0xa4, 0x0d }; +static CVI_U8 data_ili9881c_156[] = { 0xa5, 0x1e }; +static CVI_U8 data_ili9881c_157[] = { 0xa6, 0x14 }; +static CVI_U8 data_ili9881c_158[] = { 0xa7, 0x17 }; +static CVI_U8 data_ili9881c_159[] = { 0xa8, 0x4f }; +static CVI_U8 data_ili9881c_160[] = { 0xa9, 0x1a }; +static CVI_U8 data_ili9881c_161[] = { 0xaa, 0x27 }; +static CVI_U8 data_ili9881c_162[] = { 0xab, 0x49 }; +static CVI_U8 data_ili9881c_163[] = { 0xac, 0x1a }; +static CVI_U8 data_ili9881c_164[] = { 0xad, 0x18 }; +static CVI_U8 data_ili9881c_165[] = { 0xae, 0x4c }; +static CVI_U8 data_ili9881c_166[] = { 0xaf, 0x22 }; +static CVI_U8 data_ili9881c_167[] = { 0xb0, 0x27 }; +static CVI_U8 data_ili9881c_168[] = { 0xb1, 0x4b }; +static CVI_U8 data_ili9881c_169[] = { 0xb2, 0x60 }; +static CVI_U8 data_ili9881c_170[] = { 0xb3, 0x39 }; +static CVI_U8 data_ili9881c_171[] = { 0xc0, 0x08 }; +static CVI_U8 data_ili9881c_172[] = { 0xc1, 0x11 }; +static CVI_U8 data_ili9881c_173[] = { 0xc2, 0x19 }; +static CVI_U8 data_ili9881c_174[] = { 0xc3, 0x0d }; +static CVI_U8 data_ili9881c_175[] = { 0xc4, 0x0d }; +static CVI_U8 data_ili9881c_176[] = { 0xc5, 0x1e }; +static CVI_U8 data_ili9881c_177[] = { 0xc6, 0x14 }; +static CVI_U8 data_ili9881c_178[] = { 0xc7, 0x17 }; +static CVI_U8 data_ili9881c_179[] = { 0xc8, 0x4f }; +static CVI_U8 data_ili9881c_180[] = { 0xc9, 0x1a }; +static CVI_U8 data_ili9881c_181[] = { 0xca, 0x27 }; +static CVI_U8 data_ili9881c_182[] = { 0xcb, 0x49 }; +static CVI_U8 data_ili9881c_183[] = { 0xcc, 0x1a }; +static CVI_U8 data_ili9881c_184[] = { 0xcd, 0x18 }; +static CVI_U8 data_ili9881c_185[] = { 0xce, 0x4c }; +static CVI_U8 data_ili9881c_186[] = { 0xcf, 0x33 }; +static CVI_U8 data_ili9881c_187[] = { 0xd0, 0x27 }; +static CVI_U8 data_ili9881c_188[] = { 0xd1, 0x4b }; +static CVI_U8 data_ili9881c_189[] = { 0xd2, 0x60 }; +static CVI_U8 data_ili9881c_190[] = { 0xd3, 0x39 }; +static CVI_U8 data_ili9881c_191[] = { 0xff, 0x98, 0x81, 0x00 }; +static CVI_U8 data_ili9881c_192[] = { 0x36 }; +static CVI_U8 data_ili9881c_193[] = { 0x35 }; +static CVI_U8 data_ili9881c_194[] = { 0x11 }; +static CVI_U8 data_ili9881c_195[] = { 0x29 }; + +const struct dsc_instr dsi_init_cmds_ili9881c_720x1280[] = { + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881c_0 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_1 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_2 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_3 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_4 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_5 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_6 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_7 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_8 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_11 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_16 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_17 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_18 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_19 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_20 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_21 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_22 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_23 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_24 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_25 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_26 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_27 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_28 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_29 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_30 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_31 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_32 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_33 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_34 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_35 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_36 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_37 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_38 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_39 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_40 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_41 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_42 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_43 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_44 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_45 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_46 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_47 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_48 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_49 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_50 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_51 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_52 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_53 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_54 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_55 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_56 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_57 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_58 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_59 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_60 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_61 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_62 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_63 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_64 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_65 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_66 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_67 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_68 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_69 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_70 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_71 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_72 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_73 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_74 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_75 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_76 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_77 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_78 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_79 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_80 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_81 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_82 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_83 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_84 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_85 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_86 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_87 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_88 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_89 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_90 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_91 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_92 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_93 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_94 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_95 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_96 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_97 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_98 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_99 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_100 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_101 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_102 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_103 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_104 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_105 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_106 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_107 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_108 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_109 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_110 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_111 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_112 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_113 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_114 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_115 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_116 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_117 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_118 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_119 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_120 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_121 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_122 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_123 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_124 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_125 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_126 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_127 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881c_128 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_129 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_130 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_131 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_132 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_133 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_134 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_135 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_136 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_137 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_138 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881c_139 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_140 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_141 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_142 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_143 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_144 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_145 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_146 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_147 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_148 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_149 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_150 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_151 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_152 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_153 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_154 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_155 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_156 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_157 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_158 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_159 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_160 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_161 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_162 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_163 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_164 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_165 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_166 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_167 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_168 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_169 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_170 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_171 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_172 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_173 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_174 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_175 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_176 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_177 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_178 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_179 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_180 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_181 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_182 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_183 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_184 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_185 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_186 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_187 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_188 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_189 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881c_190 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881c_191 }, + {.delay = 0, .data_type = 0x05, .size = 1, .data = data_ili9881c_192 }, + {.delay = 0, .data_type = 0x05, .size = 1, .data = data_ili9881c_193 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_ili9881c_194 }, + {.delay = 20, .data_type = 0x05, .size = 1, .data = data_ili9881c_195 } +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_ILI9881C_H_ diff --git a/middleware/v2/component/panel/cv181x/dsi_ili9881d.h b/middleware/v2/component/panel/cv181x/dsi_ili9881d.h new file mode 100644 index 000000000..1b0b68a37 --- /dev/null +++ b/middleware/v2/component/panel/cv181x/dsi_ili9881d.h @@ -0,0 +1,418 @@ +#ifndef _MIPI_TX_PARAM_ILI9881D_H_ +#define _MIPI_TX_PARAM_ILI9881D_H_ + +#include +#include + +const struct combo_dev_cfg_s dev_cfg_ili9881d_720x1280 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_2, MIPI_TX_LANE_CLK, MIPI_TX_LANE_3}, + .lane_pn_swap = {false, false, false, false, false}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = 60, + .vid_hbp_pixels = 60, + .vid_hfp_pixels = 140, + .vid_hline_pixels = 720, + .vid_vsa_lines = 16, + .vid_vbp_lines = 24, + .vid_vfp_lines = 8, + .vid_active_lines = 1280, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 70118, +}; + +const struct hs_settle_s hs_timing_cfg_ili9881d_720x1280 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_ili9881d_0[] = { 0xff, 0x98, 0x81, 0x01 }; +static CVI_U8 data_ili9881d_1[] = { 0x91, 0x00 }; +static CVI_U8 data_ili9881d_2[] = { 0x92, 0x00 }; +static CVI_U8 data_ili9881d_3[] = { 0x93, 0x72 }; +static CVI_U8 data_ili9881d_4[] = { 0x94, 0x00 }; +static CVI_U8 data_ili9881d_5[] = { 0x95, 0x00 }; +static CVI_U8 data_ili9881d_6[] = { 0x96, 0x09 }; +static CVI_U8 data_ili9881d_7[] = { 0x97, 0x00 }; +static CVI_U8 data_ili9881d_8[] = { 0x98, 0x00 }; +static CVI_U8 data_ili9881d_9[] = { 0x09, 0x01 }; +static CVI_U8 data_ili9881d_10[] = { 0x0a, 0x00 }; +static CVI_U8 data_ili9881d_11[] = { 0x0b, 0x00 }; +static CVI_U8 data_ili9881d_12[] = { 0x0c, 0x01 }; +static CVI_U8 data_ili9881d_13[] = { 0x0d, 0x00 }; +static CVI_U8 data_ili9881d_14[] = { 0x0e, 0x00 }; +static CVI_U8 data_ili9881d_15[] = { 0x0f, 0x00 }; +static CVI_U8 data_ili9881d_16[] = { 0x10, 0x00 }; +static CVI_U8 data_ili9881d_17[] = { 0x11, 0x00 }; +static CVI_U8 data_ili9881d_18[] = { 0x12, 0x00 }; +static CVI_U8 data_ili9881d_19[] = { 0x13, 0x00 }; +static CVI_U8 data_ili9881d_20[] = { 0x14, 0x00 }; +static CVI_U8 data_ili9881d_21[] = { 0x15, 0x00 }; +static CVI_U8 data_ili9881d_22[] = { 0x16, 0x00 }; +static CVI_U8 data_ili9881d_23[] = { 0x17, 0x00 }; +static CVI_U8 data_ili9881d_24[] = { 0x18, 0x00 }; +static CVI_U8 data_ili9881d_25[] = { 0x19, 0x00 }; +static CVI_U8 data_ili9881d_26[] = { 0x1a, 0x00 }; +static CVI_U8 data_ili9881d_27[] = { 0x1b, 0x00 }; +static CVI_U8 data_ili9881d_28[] = { 0x1c, 0x00 }; +static CVI_U8 data_ili9881d_29[] = { 0x1d, 0x00 }; +static CVI_U8 data_ili9881d_30[] = { 0x1e, 0xc0 }; +static CVI_U8 data_ili9881d_31[] = { 0x1f, 0x40 }; +static CVI_U8 data_ili9881d_32[] = { 0x20, 0x05 }; +static CVI_U8 data_ili9881d_33[] = { 0x21, 0x02 }; +static CVI_U8 data_ili9881d_34[] = { 0x22, 0x00 }; +static CVI_U8 data_ili9881d_35[] = { 0x23, 0x00 }; +static CVI_U8 data_ili9881d_36[] = { 0x24, 0x00 }; +static CVI_U8 data_ili9881d_37[] = { 0x25, 0x00 }; +static CVI_U8 data_ili9881d_38[] = { 0x26, 0x00 }; +static CVI_U8 data_ili9881d_39[] = { 0x27, 0x00 }; +static CVI_U8 data_ili9881d_40[] = { 0x28, 0x33 }; +static CVI_U8 data_ili9881d_41[] = { 0x29, 0x02 }; +static CVI_U8 data_ili9881d_42[] = { 0x2a, 0x00 }; +static CVI_U8 data_ili9881d_43[] = { 0x2b, 0x00 }; +static CVI_U8 data_ili9881d_44[] = { 0x2c, 0x00 }; +static CVI_U8 data_ili9881d_45[] = { 0x2d, 0x00 }; +static CVI_U8 data_ili9881d_46[] = { 0x2e, 0x00 }; +static CVI_U8 data_ili9881d_47[] = { 0x2f, 0x00 }; +static CVI_U8 data_ili9881d_48[] = { 0x30, 0x00 }; +static CVI_U8 data_ili9881d_49[] = { 0x31, 0x00 }; +static CVI_U8 data_ili9881d_50[] = { 0x32, 0x00 }; +static CVI_U8 data_ili9881d_51[] = { 0x33, 0x00 }; +static CVI_U8 data_ili9881d_52[] = { 0x34, 0x04 }; +static CVI_U8 data_ili9881d_53[] = { 0x35, 0x00 }; +static CVI_U8 data_ili9881d_54[] = { 0x36, 0x00 }; +static CVI_U8 data_ili9881d_55[] = { 0x37, 0x00 }; +static CVI_U8 data_ili9881d_56[] = { 0x38, 0x3c }; +static CVI_U8 data_ili9881d_57[] = { 0x39, 0x07 }; +static CVI_U8 data_ili9881d_58[] = { 0x3a, 0x00 }; +static CVI_U8 data_ili9881d_59[] = { 0x3b, 0x00 }; +static CVI_U8 data_ili9881d_60[] = { 0x3c, 0x00 }; +static CVI_U8 data_ili9881d_61[] = { 0x40, 0x03 }; +static CVI_U8 data_ili9881d_62[] = { 0x41, 0x20 }; +static CVI_U8 data_ili9881d_63[] = { 0x42, 0x00 }; +static CVI_U8 data_ili9881d_64[] = { 0x43, 0x40 }; +static CVI_U8 data_ili9881d_65[] = { 0x44, 0x03 }; +static CVI_U8 data_ili9881d_66[] = { 0x45, 0x00 }; +static CVI_U8 data_ili9881d_67[] = { 0x46, 0x01 }; +static CVI_U8 data_ili9881d_68[] = { 0x47, 0x08 }; +static CVI_U8 data_ili9881d_69[] = { 0x48, 0x00 }; +static CVI_U8 data_ili9881d_70[] = { 0x49, 0x00 }; +static CVI_U8 data_ili9881d_71[] = { 0x4a, 0x00 }; +static CVI_U8 data_ili9881d_72[] = { 0x4b, 0x00 }; +static CVI_U8 data_ili9881d_73[] = { 0x4c, 0x01 }; +static CVI_U8 data_ili9881d_74[] = { 0x4d, 0x45 }; +static CVI_U8 data_ili9881d_75[] = { 0x4e, 0x9b }; +static CVI_U8 data_ili9881d_76[] = { 0x4f, 0x57 }; +static CVI_U8 data_ili9881d_77[] = { 0x50, 0x29 }; +static CVI_U8 data_ili9881d_78[] = { 0x51, 0x27 }; +static CVI_U8 data_ili9881d_79[] = { 0x52, 0x22 }; +static CVI_U8 data_ili9881d_80[] = { 0x53, 0x22 }; +static CVI_U8 data_ili9881d_81[] = { 0x54, 0x22 }; +static CVI_U8 data_ili9881d_82[] = { 0x55, 0x22 }; +static CVI_U8 data_ili9881d_83[] = { 0x56, 0x22 }; +static CVI_U8 data_ili9881d_84[] = { 0x57, 0x01 }; +static CVI_U8 data_ili9881d_85[] = { 0x58, 0x45 }; +static CVI_U8 data_ili9881d_86[] = { 0x59, 0x8a }; +static CVI_U8 data_ili9881d_87[] = { 0x5a, 0x46 }; +static CVI_U8 data_ili9881d_88[] = { 0x5b, 0x28 }; +static CVI_U8 data_ili9881d_89[] = { 0x5c, 0x26 }; +static CVI_U8 data_ili9881d_90[] = { 0x5d, 0x22 }; +static CVI_U8 data_ili9881d_91[] = { 0x5e, 0x22 }; +static CVI_U8 data_ili9881d_92[] = { 0x5f, 0x22 }; +static CVI_U8 data_ili9881d_93[] = { 0x60, 0x22 }; +static CVI_U8 data_ili9881d_94[] = { 0x61, 0x22 }; +static CVI_U8 data_ili9881d_95[] = { 0x62, 0x06 }; +static CVI_U8 data_ili9881d_96[] = { 0x63, 0x01 }; +static CVI_U8 data_ili9881d_97[] = { 0x64, 0x00 }; +static CVI_U8 data_ili9881d_98[] = { 0x65, 0xa4 }; +static CVI_U8 data_ili9881d_99[] = { 0x66, 0xa5 }; +static CVI_U8 data_ili9881d_100[] = { 0x67, 0x58 }; +static CVI_U8 data_ili9881d_101[] = { 0x68, 0x5a }; +static CVI_U8 data_ili9881d_102[] = { 0x69, 0x54 }; +static CVI_U8 data_ili9881d_103[] = { 0x6a, 0x56 }; +static CVI_U8 data_ili9881d_104[] = { 0x6b, 0x06 }; +static CVI_U8 data_ili9881d_105[] = { 0x6c, 0x02 }; +static CVI_U8 data_ili9881d_106[] = { 0x6d, 0x08 }; +static CVI_U8 data_ili9881d_107[] = { 0x6e, 0x02 }; +static CVI_U8 data_ili9881d_108[] = { 0x6f, 0x02 }; +static CVI_U8 data_ili9881d_109[] = { 0x70, 0x02 }; +static CVI_U8 data_ili9881d_110[] = { 0x71, 0x02 }; +static CVI_U8 data_ili9881d_111[] = { 0x72, 0x02 }; +static CVI_U8 data_ili9881d_112[] = { 0x73, 0x02 }; +static CVI_U8 data_ili9881d_113[] = { 0x74, 0x02 }; +static CVI_U8 data_ili9881d_114[] = { 0x75, 0x02 }; +static CVI_U8 data_ili9881d_115[] = { 0x76, 0x02 }; +static CVI_U8 data_ili9881d_116[] = { 0x77, 0x02 }; +static CVI_U8 data_ili9881d_117[] = { 0x78, 0x02 }; +static CVI_U8 data_ili9881d_118[] = { 0x79, 0x01 }; +static CVI_U8 data_ili9881d_119[] = { 0x7a, 0x00 }; +static CVI_U8 data_ili9881d_120[] = { 0x7b, 0xa4 }; +static CVI_U8 data_ili9881d_121[] = { 0x7c, 0xa5 }; +static CVI_U8 data_ili9881d_122[] = { 0x7d, 0x59 }; +static CVI_U8 data_ili9881d_123[] = { 0x7e, 0x5b }; +static CVI_U8 data_ili9881d_124[] = { 0x7f, 0x55 }; +static CVI_U8 data_ili9881d_125[] = { 0x80, 0x57 }; +static CVI_U8 data_ili9881d_126[] = { 0x81, 0x07 }; +static CVI_U8 data_ili9881d_127[] = { 0x82, 0x02 }; +static CVI_U8 data_ili9881d_128[] = { 0x83, 0x09 }; +static CVI_U8 data_ili9881d_129[] = { 0x84, 0x02 }; +static CVI_U8 data_ili9881d_130[] = { 0x85, 0x02 }; +static CVI_U8 data_ili9881d_131[] = { 0x86, 0x02 }; +static CVI_U8 data_ili9881d_132[] = { 0x87, 0x02 }; +static CVI_U8 data_ili9881d_133[] = { 0x88, 0x02 }; +static CVI_U8 data_ili9881d_134[] = { 0x89, 0x02 }; +static CVI_U8 data_ili9881d_135[] = { 0x8a, 0x02 }; +static CVI_U8 data_ili9881d_136[] = { 0x8b, 0x02 }; +static CVI_U8 data_ili9881d_137[] = { 0x8c, 0x02 }; +static CVI_U8 data_ili9881d_138[] = { 0x8d, 0x02 }; +static CVI_U8 data_ili9881d_139[] = { 0x8e, 0x02 }; +static CVI_U8 data_ili9881d_140[] = { 0xa0, 0x35 }; +static CVI_U8 data_ili9881d_141[] = { 0xa1, 0x00 }; +static CVI_U8 data_ili9881d_142[] = { 0xa2, 0x00 }; +static CVI_U8 data_ili9881d_143[] = { 0xa3, 0x00 }; +static CVI_U8 data_ili9881d_144[] = { 0xa4, 0x00 }; +static CVI_U8 data_ili9881d_145[] = { 0xa5, 0x00 }; +static CVI_U8 data_ili9881d_146[] = { 0xa6, 0x00 }; +static CVI_U8 data_ili9881d_147[] = { 0xa7, 0x00 }; +static CVI_U8 data_ili9881d_148[] = { 0xa8, 0x00 }; +static CVI_U8 data_ili9881d_149[] = { 0xa9, 0x00 }; +static CVI_U8 data_ili9881d_150[] = { 0xaa, 0x00 }; +static CVI_U8 data_ili9881d_151[] = { 0xab, 0x00 }; +static CVI_U8 data_ili9881d_152[] = { 0xac, 0x00 }; +static CVI_U8 data_ili9881d_153[] = { 0xad, 0x00 }; +static CVI_U8 data_ili9881d_154[] = { 0xae, 0xff }; +static CVI_U8 data_ili9881d_155[] = { 0xaf, 0x00 }; +static CVI_U8 data_ili9881d_156[] = { 0xb0, 0x00 }; +static CVI_U8 data_ili9881d_157[] = { 0xff, 0x98, 0x81, 0x02 }; +static CVI_U8 data_ili9881d_158[] = { + 0xa0, 0x00, 0x0e, 0x1a, 0x11, 0x13, 0x25, 0x19, 0x1c, 0x6b, + 0x1b, 0x28, 0x66, 0x1b, 0x19, 0x4d, 0x22, 0x27, 0x53, 0x63, + 0x2e +}; +static CVI_U8 data_ili9881d_159[] = { + 0xc0, 0x00, 0x0e, 0x1a, 0x11, 0x13, 0x25, 0x19, 0x1c, 0x6b, + 0x1b, 0x28, 0x66, 0x1b, 0x19, 0x4d, 0x22, 0x27, 0x53, 0x63, + 0x2e +}; +//================GIP code finish ================// +static CVI_U8 data_ili9881d_160[] = { 0x18, 0xf4 }; +static CVI_U8 data_ili9881d_161[] = { 0xff, 0x98, 0x81, 0x04 }; +static CVI_U8 data_ili9881d_162[] = { 0x5d, 0x8b }; +static CVI_U8 data_ili9881d_163[] = { 0x5e, 0x8b }; +static CVI_U8 data_ili9881d_164[] = { 0x60, 0x68 }; +static CVI_U8 data_ili9881d_165[] = { 0x62, 0x52 }; +static CVI_U8 data_ili9881d_166[] = { 0x82, 0x38 }; +static CVI_U8 data_ili9881d_167[] = { 0x84, 0x38 }; +static CVI_U8 data_ili9881d_168[] = { 0x86, 0x1c }; +static CVI_U8 data_ili9881d_169[] = { 0x66, 0x04 }; +static CVI_U8 data_ili9881d_170[] = { 0xc1, 0x70 }; +static CVI_U8 data_ili9881d_171[] = { 0x70, 0x60 }; +static CVI_U8 data_ili9881d_172[] = { 0x71, 0x00 }; +static CVI_U8 data_ili9881d_173[] = { 0x5b, 0x33 }; +static CVI_U8 data_ili9881d_174[] = { 0x6c, 0x10 }; +static CVI_U8 data_ili9881d_175[] = { 0x77, 0x03 }; +static CVI_U8 data_ili9881d_176[] = { 0x7b, 0x02 }; +static CVI_U8 data_ili9881d_177[] = { 0xff, 0x98, 0x81, 0x01 }; +static CVI_U8 data_ili9881d_178[] = { 0xf0, 0x00 }; +static CVI_U8 data_ili9881d_179[] = { 0xf1, 0xc8 }; +static CVI_U8 data_ili9881d_180[] = { 0xff, 0x98, 0x81, 0x05 }; +static CVI_U8 data_ili9881d_181[] = { 0x22, 0x3a }; +static CVI_U8 data_ili9881d_182[] = { 0xff, 0x98, 0x81, 0x00 }; +static CVI_U8 data_ili9881d_183[] = { 0x35, 0x00 }; +static CVI_U8 data_ili9881d_184[] = { 0x11, 0x00 }; +static CVI_U8 data_ili9881d_185[] = { 0x29, 0x00 }; + +const struct dsc_instr dsi_init_cmds_ili9881d_720x1280[] = { + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881d_0 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_1 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_2 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_3 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_4 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_5 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_6 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_7 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_8 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_11 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_16 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_17 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_18 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_19 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_20 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_21 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_22 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_23 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_24 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_25 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_26 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_27 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_28 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_29 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_30 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_31 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_32 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_33 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_34 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_35 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_36 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_37 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_38 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_39 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_40 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_41 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_42 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_43 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_44 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_45 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_46 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_47 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_48 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_49 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_50 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_51 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_52 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_53 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_54 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_55 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_56 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_57 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_58 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_59 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_60 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_61 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_62 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_63 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_64 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_65 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_66 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_67 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_68 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_69 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_70 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_71 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_72 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_73 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_74 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_75 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_76 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_77 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_78 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_79 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_80 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_81 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_82 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_83 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_84 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_85 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_86 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_87 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_88 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_89 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_90 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_91 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_92 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_93 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_94 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_95 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_96 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_97 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_98 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_99 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_100 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_101 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_102 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_103 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_104 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_105 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_106 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_107 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_108 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_109 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_110 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_111 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_112 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_113 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_114 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_115 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_116 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_117 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_118 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_119 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_120 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_121 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_122 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_123 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_124 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_125 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_126 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_127 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_128 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_129 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_130 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_131 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_132 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_133 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_134 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_135 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_136 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_137 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_138 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_139 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_140 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_141 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_142 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_143 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_144 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_145 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_146 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_147 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_148 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_149 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_150 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_151 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_152 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_153 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_154 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_155 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_156 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881d_157 }, + {.delay = 0, .data_type = 0x29, .size = 21, .data = data_ili9881d_158 }, + {.delay = 0, .data_type = 0x29, .size = 21, .data = data_ili9881d_159 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_160 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881d_161 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_162 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_163 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_164 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_165 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_166 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_167 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_168 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_169 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_170 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_171 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_172 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_173 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_174 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_175 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_176 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881d_177 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_178 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_179 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881d_180 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_181 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_ili9881d_182 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ili9881d_183 }, + {.delay = 120, .data_type = 0x15, .size = 2, .data = data_ili9881d_184 }, + {.delay = 20, .data_type = 0x15, .size = 2, .data = data_ili9881d_185 } +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_ILI9881D_H_ diff --git a/middleware/v2/component/panel/cv181x/dsi_jd9366ab.h b/middleware/v2/component/panel/cv181x/dsi_jd9366ab.h new file mode 100644 index 000000000..f284f738c --- /dev/null +++ b/middleware/v2/component/panel/cv181x/dsi_jd9366ab.h @@ -0,0 +1,394 @@ +#ifndef _MIPI_TX_PARAM_JD9366AB_H_ +#define _MIPI_TX_PARAM_JD9366AB_H_ + +#include +#include + +const struct combo_dev_cfg_s dev_cfg_jd9366ab_800x1280 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, MIPI_TX_LANE_3, MIPI_TX_LANE_2}, + .lane_pn_swap = {true, true, true, true, true}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = 6, + .vid_hbp_pixels = 40, + .vid_hfp_pixels = 112, + .vid_hline_pixels = 800, + .vid_vsa_lines = 4, + .vid_vbp_lines = 15, + .vid_vfp_lines = 21, + .vid_active_lines = 1280, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = false, + }, + .pixel_clk = 70000, +}; + +const struct hs_settle_s hs_timing_cfg_jd9366ab_800x1280 = { .prepare = 6, .zero = 16, .trail = 1 }; + +static CVI_U8 data_jd9366ab_0[] = { 0xe0, 0x00 }; +static CVI_U8 data_jd9366ab_1[] = { 0xe1, 0x93 }; +static CVI_U8 data_jd9366ab_2[] = { 0xe2, 0x65 }; +static CVI_U8 data_jd9366ab_3[] = { 0xe3, 0xf8 }; +static CVI_U8 data_jd9366ab_4[] = { 0x80, 0x03 }; +static CVI_U8 data_jd9366ab_5[] = { 0xe0, 0x04 }; +static CVI_U8 data_jd9366ab_6[] = { 0x2d, 0x03 }; +static CVI_U8 data_jd9366ab_7[] = { 0xe0, 0x01 }; +static CVI_U8 data_jd9366ab_8[] = { 0x00, 0x00 }; +static CVI_U8 data_jd9366ab_9[] = { 0x01, 0xb7 }; +static CVI_U8 data_jd9366ab_10[] = { 0x17, 0x00 }; +static CVI_U8 data_jd9366ab_11[] = { 0x18, 0xcf }; +static CVI_U8 data_jd9366ab_12[] = { 0x19, 0x01 }; +static CVI_U8 data_jd9366ab_13[] = { 0x1a, 0x00 }; +static CVI_U8 data_jd9366ab_14[] = { 0x1b, 0xcf }; +static CVI_U8 data_jd9366ab_15[] = { 0x1c, 0x01 }; +static CVI_U8 data_jd9366ab_16[] = { 0x1f, 0x3e }; +static CVI_U8 data_jd9366ab_17[] = { 0x20, 0x28 }; +static CVI_U8 data_jd9366ab_18[] = { 0x21, 0x28 }; +static CVI_U8 data_jd9366ab_19[] = { 0x22, 0x0e }; +static CVI_U8 data_jd9366ab_20[] = { 0x24, 0xc8 }; +static CVI_U8 data_jd9366ab_21[] = { 0x26, 0xf1 }; +static CVI_U8 data_jd9366ab_22[] = { 0x37, 0x29 }; +static CVI_U8 data_jd9366ab_23[] = { 0x38, 0x05 }; +static CVI_U8 data_jd9366ab_24[] = { 0x39, 0x08 }; +static CVI_U8 data_jd9366ab_25[] = { 0x3a, 0x12 }; +static CVI_U8 data_jd9366ab_26[] = { 0x3c, 0x78 }; +static CVI_U8 data_jd9366ab_27[] = { 0x3d, 0xff }; +static CVI_U8 data_jd9366ab_28[] = { 0x3e, 0xff }; +static CVI_U8 data_jd9366ab_29[] = { 0x3f, 0xff }; +static CVI_U8 data_jd9366ab_30[] = { 0x40, 0x06 }; +static CVI_U8 data_jd9366ab_31[] = { 0x41, 0xa0 }; +static CVI_U8 data_jd9366ab_32[] = { 0x43, 0x15 }; +static CVI_U8 data_jd9366ab_33[] = { 0x44, 0x12 }; +static CVI_U8 data_jd9366ab_34[] = { 0x45, 0x50 }; +static CVI_U8 data_jd9366ab_35[] = { 0x4b, 0x04 }; +static CVI_U8 data_jd9366ab_36[] = { 0x55, 0x0f }; +static CVI_U8 data_jd9366ab_37[] = { 0x56, 0x01 }; +static CVI_U8 data_jd9366ab_38[] = { 0x57, 0x89 }; +static CVI_U8 data_jd9366ab_39[] = { 0x58, 0x0a }; +static CVI_U8 data_jd9366ab_40[] = { 0x59, 0x2a }; +static CVI_U8 data_jd9366ab_41[] = { 0x5a, 0x31 }; +static CVI_U8 data_jd9366ab_42[] = { 0x5b, 0x15 }; +static CVI_U8 data_jd9366ab_43[] = { 0x5d, 0x7c }; +static CVI_U8 data_jd9366ab_44[] = { 0x5e, 0x50 }; +static CVI_U8 data_jd9366ab_45[] = { 0x5f, 0x3b }; +static CVI_U8 data_jd9366ab_46[] = { 0x60, 0x2b }; +static CVI_U8 data_jd9366ab_47[] = { 0x61, 0x25 }; +static CVI_U8 data_jd9366ab_48[] = { 0x62, 0x15 }; +static CVI_U8 data_jd9366ab_49[] = { 0x63, 0x1a }; +static CVI_U8 data_jd9366ab_50[] = { 0x64, 0x04 }; +static CVI_U8 data_jd9366ab_51[] = { 0x65, 0x1c }; +static CVI_U8 data_jd9366ab_52[] = { 0x66, 0x1a }; +static CVI_U8 data_jd9366ab_53[] = { 0x67, 0x19 }; +static CVI_U8 data_jd9366ab_54[] = { 0x68, 0x36 }; +static CVI_U8 data_jd9366ab_55[] = { 0x69, 0x27 }; +static CVI_U8 data_jd9366ab_56[] = { 0x6a, 0x2f }; +static CVI_U8 data_jd9366ab_57[] = { 0x6b, 0x23 }; +static CVI_U8 data_jd9366ab_58[] = { 0x6c, 0x21 }; +static CVI_U8 data_jd9366ab_59[] = { 0x6d, 0x17 }; +static CVI_U8 data_jd9366ab_60[] = { 0x6e, 0x05 }; +static CVI_U8 data_jd9366ab_61[] = { 0x6f, 0x00 }; +static CVI_U8 data_jd9366ab_62[] = { 0x70, 0x7c }; +static CVI_U8 data_jd9366ab_63[] = { 0x71, 0x50 }; +static CVI_U8 data_jd9366ab_64[] = { 0x72, 0x3b }; +static CVI_U8 data_jd9366ab_65[] = { 0x73, 0x2b }; +static CVI_U8 data_jd9366ab_66[] = { 0x74, 0x25 }; +static CVI_U8 data_jd9366ab_67[] = { 0x75, 0x15 }; +static CVI_U8 data_jd9366ab_68[] = { 0x76, 0x1a }; +static CVI_U8 data_jd9366ab_69[] = { 0x77, 0x04 }; +static CVI_U8 data_jd9366ab_70[] = { 0x78, 0x1c }; +static CVI_U8 data_jd9366ab_71[] = { 0x79, 0x1a }; +static CVI_U8 data_jd9366ab_72[] = { 0x7a, 0x19 }; +static CVI_U8 data_jd9366ab_73[] = { 0x7b, 0x36 }; +static CVI_U8 data_jd9366ab_74[] = { 0x7c, 0x27 }; +static CVI_U8 data_jd9366ab_75[] = { 0x7d, 0x2f }; +static CVI_U8 data_jd9366ab_76[] = { 0x7e, 0x23 }; +static CVI_U8 data_jd9366ab_77[] = { 0x7f, 0x21 }; +static CVI_U8 data_jd9366ab_78[] = { 0x80, 0x17 }; +static CVI_U8 data_jd9366ab_79[] = { 0x81, 0x05 }; +static CVI_U8 data_jd9366ab_80[] = { 0x82, 0x00 }; +static CVI_U8 data_jd9366ab_81[] = { 0xe0, 0x02 }; +static CVI_U8 data_jd9366ab_82[] = { 0x00, 0x00 }; +static CVI_U8 data_jd9366ab_83[] = { 0x01, 0x04 }; +static CVI_U8 data_jd9366ab_84[] = { 0x02, 0x08 }; +static CVI_U8 data_jd9366ab_85[] = { 0x03, 0x05 }; +static CVI_U8 data_jd9366ab_86[] = { 0x04, 0x09 }; +static CVI_U8 data_jd9366ab_87[] = { 0x05, 0x06 }; +static CVI_U8 data_jd9366ab_88[] = { 0x06, 0x0a }; +static CVI_U8 data_jd9366ab_89[] = { 0x07, 0x07 }; +static CVI_U8 data_jd9366ab_90[] = { 0x08, 0x0b }; +static CVI_U8 data_jd9366ab_91[] = { 0x09, 0x1f }; +static CVI_U8 data_jd9366ab_92[] = { 0x0a, 0x1f }; +static CVI_U8 data_jd9366ab_93[] = { 0x0b, 0x1f }; +static CVI_U8 data_jd9366ab_94[] = { 0x0c, 0x1f }; +static CVI_U8 data_jd9366ab_95[] = { 0x0d, 0x1f }; +static CVI_U8 data_jd9366ab_96[] = { 0x0e, 0x1f }; +static CVI_U8 data_jd9366ab_97[] = { 0x0f, 0x17 }; +static CVI_U8 data_jd9366ab_98[] = { 0x10, 0x37 }; +static CVI_U8 data_jd9366ab_99[] = { 0x11, 0x10 }; +static CVI_U8 data_jd9366ab_100[] = { 0x12, 0x1f }; +static CVI_U8 data_jd9366ab_101[] = { 0x13, 0x1f }; +static CVI_U8 data_jd9366ab_102[] = { 0x14, 0x1f }; +static CVI_U8 data_jd9366ab_103[] = { 0x15, 0x1f }; +static CVI_U8 data_jd9366ab_104[] = { 0x16, 0x00 }; +static CVI_U8 data_jd9366ab_105[] = { 0x17, 0x04 }; +static CVI_U8 data_jd9366ab_106[] = { 0x18, 0x08 }; +static CVI_U8 data_jd9366ab_107[] = { 0x19, 0x05 }; +static CVI_U8 data_jd9366ab_108[] = { 0x1a, 0x09 }; +static CVI_U8 data_jd9366ab_109[] = { 0x1b, 0x06 }; +static CVI_U8 data_jd9366ab_110[] = { 0x1c, 0x0a }; +static CVI_U8 data_jd9366ab_111[] = { 0x1d, 0x07 }; +static CVI_U8 data_jd9366ab_112[] = { 0x1e, 0x0b }; +static CVI_U8 data_jd9366ab_113[] = { 0x1f, 0x1f }; +static CVI_U8 data_jd9366ab_114[] = { 0x20, 0x1f }; +static CVI_U8 data_jd9366ab_115[] = { 0x21, 0x1f }; +static CVI_U8 data_jd9366ab_116[] = { 0x22, 0x1f }; +static CVI_U8 data_jd9366ab_117[] = { 0x23, 0x1f }; +static CVI_U8 data_jd9366ab_118[] = { 0x24, 0x1f }; +static CVI_U8 data_jd9366ab_119[] = { 0x25, 0x17 }; +static CVI_U8 data_jd9366ab_120[] = { 0x26, 0x37 }; +static CVI_U8 data_jd9366ab_121[] = { 0x27, 0x10 }; +static CVI_U8 data_jd9366ab_122[] = { 0x28, 0x1f }; +static CVI_U8 data_jd9366ab_123[] = { 0x29, 0x1f }; +static CVI_U8 data_jd9366ab_124[] = { 0x2a, 0x1f }; +static CVI_U8 data_jd9366ab_125[] = { 0x2b, 0x1f }; +static CVI_U8 data_jd9366ab_126[] = { 0x58, 0x01 }; +static CVI_U8 data_jd9366ab_127[] = { 0x59, 0x00 }; +static CVI_U8 data_jd9366ab_128[] = { 0x5a, 0x00 }; +static CVI_U8 data_jd9366ab_129[] = { 0x5b, 0x00 }; +static CVI_U8 data_jd9366ab_130[] = { 0x5c, 0x0c }; +static CVI_U8 data_jd9366ab_131[] = { 0x5d, 0x60 }; +static CVI_U8 data_jd9366ab_132[] = { 0x5e, 0x00 }; +static CVI_U8 data_jd9366ab_133[] = { 0x5f, 0x00 }; +static CVI_U8 data_jd9366ab_134[] = { 0x60, 0x30 }; +static CVI_U8 data_jd9366ab_135[] = { 0x61, 0x00 }; +static CVI_U8 data_jd9366ab_136[] = { 0x62, 0x00 }; +static CVI_U8 data_jd9366ab_137[] = { 0x63, 0x03 }; +static CVI_U8 data_jd9366ab_138[] = { 0x64, 0x6a }; +static CVI_U8 data_jd9366ab_139[] = { 0x65, 0x45 }; +static CVI_U8 data_jd9366ab_140[] = { 0x66, 0x14 }; +static CVI_U8 data_jd9366ab_141[] = { 0x67, 0x73 }; +static CVI_U8 data_jd9366ab_142[] = { 0x68, 0x10 }; +static CVI_U8 data_jd9366ab_143[] = { 0x69, 0x06 }; +static CVI_U8 data_jd9366ab_144[] = { 0x6a, 0x6a }; +static CVI_U8 data_jd9366ab_145[] = { 0x6b, 0x00 }; +static CVI_U8 data_jd9366ab_146[] = { 0x6c, 0x00 }; +static CVI_U8 data_jd9366ab_147[] = { 0x6d, 0x03 }; +static CVI_U8 data_jd9366ab_148[] = { 0x6e, 0x00 }; +static CVI_U8 data_jd9366ab_149[] = { 0x6f, 0x08 }; +static CVI_U8 data_jd9366ab_150[] = { 0x70, 0x00 }; +static CVI_U8 data_jd9366ab_151[] = { 0x71, 0x00 }; +static CVI_U8 data_jd9366ab_152[] = { 0x72, 0x06 }; +static CVI_U8 data_jd9366ab_153[] = { 0x73, 0x7b }; +static CVI_U8 data_jd9366ab_154[] = { 0x74, 0x00 }; +static CVI_U8 data_jd9366ab_155[] = { 0x75, 0x80 }; +static CVI_U8 data_jd9366ab_156[] = { 0x76, 0x00 }; +static CVI_U8 data_jd9366ab_157[] = { 0x77, 0x05 }; +static CVI_U8 data_jd9366ab_158[] = { 0x78, 0x1b }; +static CVI_U8 data_jd9366ab_159[] = { 0x79, 0x00 }; +static CVI_U8 data_jd9366ab_160[] = { 0x7a, 0x00 }; +static CVI_U8 data_jd9366ab_161[] = { 0x7b, 0x00 }; +static CVI_U8 data_jd9366ab_162[] = { 0x7c, 0x00 }; +static CVI_U8 data_jd9366ab_163[] = { 0x7d, 0x03 }; +static CVI_U8 data_jd9366ab_164[] = { 0x7e, 0x7b }; +static CVI_U8 data_jd9366ab_165[] = { 0xe0, 0x01 }; +static CVI_U8 data_jd9366ab_166[] = { 0x0e, 0x01 }; +static CVI_U8 data_jd9366ab_167[] = { 0xe0, 0x03 }; +static CVI_U8 data_jd9366ab_168[] = { 0x98, 0x2f }; +static CVI_U8 data_jd9366ab_169[] = { 0xe0, 0x04 }; +static CVI_U8 data_jd9366ab_170[] = { 0x09, 0x10 }; +static CVI_U8 data_jd9366ab_171[] = { 0x2b, 0x2b }; +static CVI_U8 data_jd9366ab_172[] = { 0x2e, 0x44 }; +static CVI_U8 data_jd9366ab_173[] = { 0xe0, 0x00 }; +static CVI_U8 data_jd9366ab_174[] = { 0xe6, 0x02 }; +static CVI_U8 data_jd9366ab_175[] = { 0xe7, 0x06 }; +static CVI_U8 data_jd9366ab_176[] = { 0x11 }; +static CVI_U8 data_jd9366ab_177[] = { 0x29 }; +static CVI_U8 data_jd9366ab_178[] = { 0x35, 0x00 }; +const struct dsc_instr dsi_init_cmds_jd9366ab_800x1280[] = { + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_0 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_1 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_2 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_3 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_4 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_5 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_6 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_7 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_8 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_11 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_16 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_17 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_18 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_19 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_20 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_21 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_22 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_23 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_24 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_25 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_26 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_27 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_28 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_29 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_30 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_31 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_32 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_33 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_34 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_35 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_36 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_37 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_38 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_39 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_40 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_41 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_42 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_43 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_44 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_45 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_46 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_47 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_48 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_49 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_50 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_51 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_52 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_53 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_54 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_55 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_56 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_57 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_58 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_59 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_60 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_61 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_62 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_63 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_64 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_65 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_66 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_67 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_68 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_69 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_70 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_71 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_72 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_73 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_74 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_75 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_76 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_77 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_78 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_79 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_80 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_81 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_82 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_83 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_84 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_85 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_86 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_87 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_88 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_89 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_90 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_91 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_92 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_93 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_94 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_95 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_96 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_97 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_98 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_99 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_100 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_101 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_102 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_103 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_104 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_105 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_106 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_107 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_108 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_109 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_110 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_111 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_112 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_113 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_114 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_115 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_116 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_117 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_118 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_119 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_120 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_121 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_122 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_123 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_124 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_125 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_126 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_127 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_128 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_129 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_130 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_131 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_132 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_133 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_134 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_135 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_136 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_137 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_138 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_139 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_140 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_141 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_142 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_143 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_144 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_145 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_146 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_147 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_148 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_149 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_150 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_151 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_152 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_153 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_154 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_155 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_156 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_157 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_158 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_159 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_160 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_161 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_162 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_163 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_164 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_165 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_166 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_167 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_168 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_169 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_170 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_171 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_172 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_173 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_174 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_175 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_jd9366ab_176 }, + {.delay = 5, .data_type = 0x05, .size = 1, .data = data_jd9366ab_177 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_jd9366ab_178 } +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_JD9366AB_H_ diff --git a/middleware/v2/component/panel/cv181x/dsi_nt35521.h b/middleware/v2/component/panel/cv181x/dsi_nt35521.h new file mode 100644 index 000000000..704e83cae --- /dev/null +++ b/middleware/v2/component/panel/cv181x/dsi_nt35521.h @@ -0,0 +1,200 @@ +#ifndef _MIPI_TX_PARAM_NT35521_H_ +#define _MIPI_TX_PARAM_NT35521_H_ + +#include +#include + +const struct combo_dev_cfg_s dev_cfg_nt35521_800x1280 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_CLK, MIPI_TX_LANE_0, MIPI_TX_LANE_2, MIPI_TX_LANE_3, MIPI_TX_LANE_1}, + .lane_pn_swap = {false, false, false, false, false}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = 80, + .vid_hbp_pixels = 80, + .vid_hfp_pixels = 168, + .vid_hline_pixels = 800, + .vid_vsa_lines = 6, + .vid_vbp_lines = 40, + .vid_vfp_lines = 18, + .vid_active_lines = 1280, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 90962, +}; + +const struct hs_settle_s hs_timing_cfg_nt35521_800x1280 = { .prepare = 6, .zero = 32, .trail = 1 }; + +//=====================Page 0 relative=================== +static CVI_U8 data_nt35521_0[] = { 0xf0, 0x55, 0xaa, 0x52, 0x08, 0x00 }; +static CVI_U8 data_nt35521_1[] = { 0xb1, 0x6c, 0x01 }; +static CVI_U8 data_nt35521_2[] = { 0xb5, 0xc8, 0x00 }; +static CVI_U8 data_nt35521_3[] = { 0xbc, 0x00 }; +static CVI_U8 data_nt35521_4[] = { 0xbd, 0x96, 0xb0, 0x0c, 0x08, 0x01 }; +static CVI_U8 data_nt35521_5[] = { 0xc8, 0x80 }; +//=====================Page 1 relative=================== +static CVI_U8 data_nt35521_6[] = { 0xf0, 0x55, 0xaa, 0x52, 0x08, 0x01 }; +static CVI_U8 data_nt35521_7[] = { 0xb3, 0x26 }; +static CVI_U8 data_nt35521_8[] = { 0xb4, 0x0f }; +static CVI_U8 data_nt35521_9[] = { 0xbb, 0x15 }; +static CVI_U8 data_nt35521_10[] = { 0xbc, 0xa8 }; +static CVI_U8 data_nt35521_11[] = { 0xbd, 0xa8 }; +static CVI_U8 data_nt35521_12[] = { 0xbe, 0x28 }; +//=====================Page 2 relative=================== +static CVI_U8 data_nt35521_13[] = { 0xf0, 0x55, 0xaa, 0x52, 0x08, 0x02 }; +static CVI_U8 data_nt35521_14[] = { 0xee, 0x01 }; +static CVI_U8 data_nt35521_15[] = { + 0xb0, 0x00, 0x00, 0x00, 0x13, 0x00, 0x33, 0x00, 0x4f, 0x00, + 0x65, 0x00, 0x79, 0x00, 0x8b, 0x00, 0x9c +}; +static CVI_U8 data_nt35521_16[] = { + 0xb1, 0x00, 0xac, 0x00, 0xe0, 0x01, 0x09, 0x01, 0x4b, 0x01, + 0x80, 0x01, 0xd1, 0x02, 0x13, 0x02, 0x14 +}; +static CVI_U8 data_nt35521_17[] = { + 0xb2, 0x02, 0x50, 0x02, 0x91, 0x02, 0xba, 0x02, 0xf0, 0x03, + 0x12, 0x03, 0x3d, 0x03, 0x4a, 0x03, 0x57 +}; +static CVI_U8 data_nt35521_18[] = { + 0xb3, 0x03, 0x5f, 0x03, 0x74, 0x03, 0x8f, 0x03, 0xb8, 0x03, + 0xfc, 0x03, 0xff +}; +static CVI_U8 data_nt35521_19[] = { + 0xe9, 0x52, 0x60, 0x63, 0x11, 0x21, 0x52, 0x60, 0x63, 0x11, + 0x21 +}; +static CVI_U8 data_nt35521_20[] = { + 0xea, 0x52, 0x60, 0x63, 0x11, 0x21, 0x52, 0x60, 0x63, 0x11, + 0x21 +}; +static CVI_U8 data_nt35521_21[] = { + 0xeb, 0x52, 0x60, 0x63, 0x11, 0x21, 0x52, 0x60, 0x63, 0x11, + 0x21 +}; +//=====================Page 3 relative=================== +static CVI_U8 data_nt35521_22[] = { 0xf0, 0x55, 0xaa, 0x52, 0x08, 0x03 }; +static CVI_U8 data_nt35521_23[] = { 0xb2, 0x00, 0x0b, 0x08, 0x00, 0x00 }; +static CVI_U8 data_nt35521_24[] = { 0xb3, 0x00, 0x09, 0x06, 0x00, 0x00 }; +static CVI_U8 data_nt35521_25[] = { 0xba, 0x44, 0x00, 0x00, 0x10 }; +static CVI_U8 data_nt35521_26[] = { 0xc0, 0x00, 0x34, 0x00 }; +static CVI_U8 data_nt35521_27[] = { 0xc1, 0x00, 0x00, 0x34 }; +//=====================Page 4 relative=================== +static CVI_U8 data_nt35521_28[] = { 0xf0, 0x55, 0xaa, 0x52, 0x08, 0x04 }; +static CVI_U8 data_nt35521_29[] = { 0xb1, 0x03, 0x02, 0x00, 0x15, 0x16 }; +//=====================Page 5 relative=================== +static CVI_U8 data_nt35521_30[] = { 0xf0, 0x55, 0xaa, 0x52, 0x08, 0x05 }; +static CVI_U8 data_nt35521_31[] = { 0xb0, 0x06 }; +static CVI_U8 data_nt35521_32[] = { 0xb2, 0x06, 0x00 }; +static CVI_U8 data_nt35521_33[] = { 0xb3, 0x0e, 0x00, 0x00, 0x00, 0x00 }; +static CVI_U8 data_nt35521_34[] = { 0xb4, 0x06, 0x00, 0x00, 0x00, 0x00 }; +static CVI_U8 data_nt35521_35[] = { 0xb7, 0x06, 0x00, 0x00 }; +static CVI_U8 data_nt35521_36[] = { 0xbc, 0x00, 0x00, 0x00, 0x02 }; +static CVI_U8 data_nt35521_37[] = { 0xbd, 0x01, 0x03, 0x00, 0x03, 0x03 }; +static CVI_U8 data_nt35521_38[] = { 0xc0, 0x07, 0x70 }; +static CVI_U8 data_nt35521_39[] = { 0xc4, 0x00, 0x00, 0x3c }; +static CVI_U8 data_nt35521_40[] = { 0xc5, 0x00, 0x00, 0x3c }; +static CVI_U8 data_nt35521_41[] = { 0xd1, 0x00, 0x05, 0x01, 0x00, 0x00 }; +static CVI_U8 data_nt35521_42[] = { 0xe3, 0x84 }; +static CVI_U8 data_nt35521_43[] = { 0xe5, 0x1a }; +static CVI_U8 data_nt35521_44[] = { 0xe6, 0x1a }; +static CVI_U8 data_nt35521_45[] = { 0xe8, 0x1a }; +static CVI_U8 data_nt35521_46[] = { 0xe9, 0x1a }; +static CVI_U8 data_nt35521_47[] = { 0xea, 0x1a }; +//=====================Page 6 relative=================== +static CVI_U8 data_nt35521_48[] = { 0xf0, 0x55, 0xaa, 0x52, 0x08, 0x06 }; +static CVI_U8 data_nt35521_49[] = { 0xb0, 0x30, 0x31, 0x2c, 0x2d, 0x14 }; +static CVI_U8 data_nt35521_50[] = { 0xb1, 0x16, 0x10, 0x12, 0x00, 0x35 }; +static CVI_U8 data_nt35521_51[] = { 0xb2, 0x35, 0x35, 0x35, 0x02, 0x31 }; +static CVI_U8 data_nt35521_52[] = { 0xb3, 0x31, 0x31, 0x35, 0x35, 0x35 }; +static CVI_U8 data_nt35521_53[] = { 0xb4, 0x35, 0x35, 0x35, 0x31, 0x31 }; +static CVI_U8 data_nt35521_54[] = { 0xb5, 0x31, 0x03, 0x35, 0x35, 0x35 }; +static CVI_U8 data_nt35521_55[] = { 0xb6, 0x35, 0x01, 0x13, 0x11, 0x17 }; +static CVI_U8 data_nt35521_56[] = { 0xb7, 0x15, 0x2d, 0x2c, 0x31, 0x30 }; +static CVI_U8 data_nt35521_57[] = { 0xf0, 0x55, 0xaa, 0x52, 0x00, 0x00 }; +static CVI_U8 data_nt35521_58[] = { 0x35, 0x00 }; +static CVI_U8 data_nt35521_59[] = { 0x11 }; +static CVI_U8 data_nt35521_60[] = { 0x29 }; +#ifdef _MIPI_TX_BIST_MODE +//=====================BIST relative=================== +static CVI_U8 data_nt35521_61[] = { 0x10 }; +static CVI_U8 data_nt35521_62[] = { 0xF0, 0x55, 0xAA, 0x52, 0x08, 0x00 }; +static CVI_U8 data_nt35521_63[] = { 0xEE, 0x87, 0x78, 0xff, 0xff }; +#endif + +const struct dsc_instr dsi_init_cmds_nt35521_800x1280[] = { +#ifdef _MIPI_TX_BIST_MODE + //=====================BIST relative=================== + { .delay = 0, .data_type = 0x05, .size = 1, .data = data_nt35521_61 }, + { .delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_62 }, + { .delay = 0, .data_type = 0x29, .size = 5, .data = data_nt35521_63 }, +#else + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_0 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_nt35521_1 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_nt35521_2 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_3 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_4 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_5 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_6 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_7 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_8 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_11 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_12 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_14 }, + {.delay = 0, .data_type = 0x29, .size = 17, .data = data_nt35521_15 }, + {.delay = 0, .data_type = 0x29, .size = 17, .data = data_nt35521_16 }, + {.delay = 0, .data_type = 0x29, .size = 17, .data = data_nt35521_17 }, + {.delay = 0, .data_type = 0x29, .size = 13, .data = data_nt35521_18 }, + {.delay = 0, .data_type = 0x29, .size = 11, .data = data_nt35521_19 }, + {.delay = 0, .data_type = 0x29, .size = 11, .data = data_nt35521_20 }, + {.delay = 0, .data_type = 0x29, .size = 11, .data = data_nt35521_21 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_22 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_23 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_24 }, + {.delay = 0, .data_type = 0x29, .size = 5, .data = data_nt35521_25 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_nt35521_26 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_nt35521_27 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_28 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_29 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_30 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_31 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_nt35521_32 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_33 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_34 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_nt35521_35 }, + {.delay = 0, .data_type = 0x29, .size = 5, .data = data_nt35521_36 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_37 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_nt35521_38 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_nt35521_39 }, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_nt35521_40 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_41 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_42 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_43 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_44 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_45 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_46 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_47 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_48 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_49 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_50 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_51 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_52 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_53 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_54 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_55 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_56 }, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_nt35521_57 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_nt35521_58 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_nt35521_59 }, + {.delay = 20, .data_type = 0x05, .size = 1, .data = data_nt35521_60 } +#endif +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_NT35521_H_ diff --git a/middleware/v2/component/panel/cv181x/dsi_ota7290b.h b/middleware/v2/component/panel/cv181x/dsi_ota7290b.h new file mode 100644 index 000000000..6da973b6a --- /dev/null +++ b/middleware/v2/component/panel/cv181x/dsi_ota7290b.h @@ -0,0 +1,547 @@ +#ifndef _MIPI_TX_PARAM_OTA7290B_H_ +#define _MIPI_TX_PARAM_OTA7290B_H_ + +#include +#include + +// Not support BTA +const struct combo_dev_cfg_s dev_cfg_ota7290b_320x1280 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_1, MIPI_TX_LANE_CLK, MIPI_TX_LANE_2, MIPI_TX_LANE_3}, + .lane_pn_swap = {false, false, false, false, false}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = 30, + .vid_hbp_pixels = 50, + .vid_hfp_pixels = 150, + .vid_hline_pixels = 320, + .vid_vsa_lines = 20, + .vid_vbp_lines = 30, + .vid_vfp_lines = 150, + .vid_active_lines = 1280, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 52910, +}; + +const struct hs_settle_s hs_timing_cfg_ota7290b_320x1280 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_ota7290b_0[] = { 0xb0, 0x5a }; +static CVI_U8 data_ota7290b_1[] = { 0xb1, 0x00 }; +static CVI_U8 data_ota7290b_2[] = { 0x89, 0x01 }; +#ifdef _MIPI_TX_BIST_MODE_ +static CVI_U8 data_ota7290b_3[] = { 0x91, 0x16 }; +#else +static CVI_U8 data_ota7290b_3[] = { 0x91, 0x17 }; +#endif +static CVI_U8 data_ota7290b_4[] = { 0xb1, 0x03 }; +static CVI_U8 data_ota7290b_5[] = { 0x2c, 0x28 }; +static CVI_U8 data_ota7290b_6[] = { 0x00, 0xf1 }; +static CVI_U8 data_ota7290b_7[] = { 0x01, 0x18 }; +static CVI_U8 data_ota7290b_8[] = { 0x02, 0x00 }; +static CVI_U8 data_ota7290b_9[] = { 0x03, 0x00 }; +static CVI_U8 data_ota7290b_10[] = { 0x04, 0x00 }; +static CVI_U8 data_ota7290b_11[] = { 0x05, 0x00 }; +static CVI_U8 data_ota7290b_12[] = { 0x06, 0x00 }; +static CVI_U8 data_ota7290b_13[] = { 0x07, 0x00 }; +static CVI_U8 data_ota7290b_14[] = { 0x08, 0x00 }; +static CVI_U8 data_ota7290b_15[] = { 0x09, 0x00 }; +static CVI_U8 data_ota7290b_16[] = { 0x0a, 0x01 }; +static CVI_U8 data_ota7290b_17[] = { 0x0b, 0x01 }; +static CVI_U8 data_ota7290b_18[] = { 0x0c, 0x00 }; +static CVI_U8 data_ota7290b_19[] = { 0x0d, 0x00 }; +static CVI_U8 data_ota7290b_20[] = { 0x0e, 0x24 }; +static CVI_U8 data_ota7290b_21[] = { 0x0f, 0x1c }; +static CVI_U8 data_ota7290b_22[] = { 0x10, 0xc9 }; +static CVI_U8 data_ota7290b_23[] = { 0x11, 0x60 }; +static CVI_U8 data_ota7290b_24[] = { 0x12, 0x70 }; +static CVI_U8 data_ota7290b_25[] = { 0x13, 0x01 }; +static CVI_U8 data_ota7290b_26[] = { 0x14, 0xe7 }; +static CVI_U8 data_ota7290b_27[] = { 0x15, 0xff }; +static CVI_U8 data_ota7290b_28[] = { 0x16, 0x3d }; +static CVI_U8 data_ota7290b_29[] = { 0x17, 0x0e }; +static CVI_U8 data_ota7290b_30[] = { 0x18, 0x01 }; +static CVI_U8 data_ota7290b_31[] = { 0x19, 0x00 }; +static CVI_U8 data_ota7290b_32[] = { 0x1a, 0x00 }; +static CVI_U8 data_ota7290b_33[] = { 0x1b, 0xfc }; +static CVI_U8 data_ota7290b_34[] = { 0x1c, 0x0b }; +static CVI_U8 data_ota7290b_35[] = { 0x1d, 0xa0 }; +static CVI_U8 data_ota7290b_36[] = { 0x1e, 0x03 }; +static CVI_U8 data_ota7290b_37[] = { 0x1f, 0x04 }; +static CVI_U8 data_ota7290b_38[] = { 0x20, 0x0c }; +static CVI_U8 data_ota7290b_39[] = { 0x21, 0x00 }; +static CVI_U8 data_ota7290b_40[] = { 0x22, 0x04 }; +static CVI_U8 data_ota7290b_41[] = { 0x23, 0x81 }; +static CVI_U8 data_ota7290b_42[] = { 0x24, 0x1f }; +static CVI_U8 data_ota7290b_43[] = { 0x25, 0x10 }; +static CVI_U8 data_ota7290b_44[] = { 0x26, 0x9b }; +static CVI_U8 data_ota7290b_45[] = { 0x2d, 0x01 }; +static CVI_U8 data_ota7290b_46[] = { 0x2e, 0x84 }; +static CVI_U8 data_ota7290b_47[] = { 0x2f, 0x00 }; +static CVI_U8 data_ota7290b_48[] = { 0x30, 0x02 }; +static CVI_U8 data_ota7290b_49[] = { 0x31, 0x08 }; +static CVI_U8 data_ota7290b_50[] = { 0x32, 0x01 }; +static CVI_U8 data_ota7290b_51[] = { 0x33, 0x1c }; +static CVI_U8 data_ota7290b_52[] = { 0x34, 0x40 }; +static CVI_U8 data_ota7290b_53[] = { 0x35, 0xff }; +static CVI_U8 data_ota7290b_54[] = { 0x36, 0xff }; +static CVI_U8 data_ota7290b_55[] = { 0x37, 0xff }; +static CVI_U8 data_ota7290b_56[] = { 0x38, 0xff }; +static CVI_U8 data_ota7290b_57[] = { 0x39, 0xff }; +static CVI_U8 data_ota7290b_58[] = { 0x3a, 0x05 }; +static CVI_U8 data_ota7290b_59[] = { 0x3b, 0x00 }; +static CVI_U8 data_ota7290b_60[] = { 0x3c, 0x00 }; +static CVI_U8 data_ota7290b_61[] = { 0x3d, 0x00 }; +static CVI_U8 data_ota7290b_62[] = { 0x3e, 0x0f }; +static CVI_U8 data_ota7290b_63[] = { 0x3f, 0x8c }; +static CVI_U8 data_ota7290b_64[] = { 0x40, 0x2a }; +static CVI_U8 data_ota7290b_65[] = { 0x41, 0xfc }; +static CVI_U8 data_ota7290b_66[] = { 0x42, 0x01 }; +static CVI_U8 data_ota7290b_67[] = { 0x43, 0x40 }; +static CVI_U8 data_ota7290b_68[] = { 0x44, 0x05 }; +static CVI_U8 data_ota7290b_69[] = { 0x45, 0xe8 }; +static CVI_U8 data_ota7290b_70[] = { 0x46, 0x16 }; +static CVI_U8 data_ota7290b_71[] = { 0x47, 0x00 }; +static CVI_U8 data_ota7290b_72[] = { 0x48, 0x00 }; +static CVI_U8 data_ota7290b_73[] = { 0x49, 0x88 }; +static CVI_U8 data_ota7290b_74[] = { 0x4a, 0x08 }; +static CVI_U8 data_ota7290b_75[] = { 0x4b, 0x05 }; +static CVI_U8 data_ota7290b_76[] = { 0x4c, 0x03 }; +static CVI_U8 data_ota7290b_77[] = { 0x4d, 0xd0 }; +static CVI_U8 data_ota7290b_78[] = { 0x4e, 0x13 }; +static CVI_U8 data_ota7290b_79[] = { 0x4f, 0xff }; +static CVI_U8 data_ota7290b_80[] = { 0x50, 0x0a }; +static CVI_U8 data_ota7290b_81[] = { 0x51, 0x53 }; +static CVI_U8 data_ota7290b_82[] = { 0x52, 0x26 }; +static CVI_U8 data_ota7290b_83[] = { 0x53, 0x22 }; +static CVI_U8 data_ota7290b_84[] = { 0x54, 0x09 }; +static CVI_U8 data_ota7290b_85[] = { 0x55, 0x22 }; +static CVI_U8 data_ota7290b_86[] = { 0x56, 0x00 }; +static CVI_U8 data_ota7290b_87[] = { 0x57, 0x1c }; +static CVI_U8 data_ota7290b_88[] = { 0x58, 0x03 }; +static CVI_U8 data_ota7290b_89[] = { 0x59, 0x3f }; +static CVI_U8 data_ota7290b_90[] = { 0x5a, 0x28 }; +static CVI_U8 data_ota7290b_91[] = { 0x5b, 0x01 }; +static CVI_U8 data_ota7290b_92[] = { 0x5c, 0xcc }; +static CVI_U8 data_ota7290b_93[] = { 0x5d, 0x21 }; +static CVI_U8 data_ota7290b_94[] = { 0x5e, 0x84 }; +static CVI_U8 data_ota7290b_95[] = { 0x5f, 0x84 }; +static CVI_U8 data_ota7290b_96[] = { 0x60, 0x8e }; +static CVI_U8 data_ota7290b_97[] = { 0x61, 0x89 }; +static CVI_U8 data_ota7290b_98[] = { 0x62, 0xf0 }; +static CVI_U8 data_ota7290b_99[] = { 0x63, 0xb9 }; +static CVI_U8 data_ota7290b_100[] = { 0x64, 0xc6 }; +static CVI_U8 data_ota7290b_101[] = { 0x65, 0x96 }; +static CVI_U8 data_ota7290b_102[] = { 0x66, 0x0a }; +static CVI_U8 data_ota7290b_103[] = { 0x67, 0x62 }; +static CVI_U8 data_ota7290b_104[] = { 0x68, 0x90 }; +static CVI_U8 data_ota7290b_105[] = { 0x69, 0x12 }; +static CVI_U8 data_ota7290b_106[] = { 0x6a, 0x42 }; +static CVI_U8 data_ota7290b_107[] = { 0x6b, 0x48 }; +static CVI_U8 data_ota7290b_108[] = { 0x6c, 0xe8 }; +static CVI_U8 data_ota7290b_109[] = { 0x6d, 0x98 }; +static CVI_U8 data_ota7290b_110[] = { 0x6e, 0x08 }; +static CVI_U8 data_ota7290b_111[] = { 0x6f, 0x9f }; +static CVI_U8 data_ota7290b_112[] = { 0x70, 0x6b }; +static CVI_U8 data_ota7290b_113[] = { 0x71, 0x6c }; +static CVI_U8 data_ota7290b_114[] = { 0x72, 0xa9 }; +static CVI_U8 data_ota7290b_115[] = { 0x73, 0x20 }; +static CVI_U8 data_ota7290b_116[] = { 0x74, 0x06 }; +static CVI_U8 data_ota7290b_117[] = { 0x75, 0x29 }; +static CVI_U8 data_ota7290b_118[] = { 0x76, 0x00 }; +static CVI_U8 data_ota7290b_119[] = { 0x77, 0x00 }; +static CVI_U8 data_ota7290b_120[] = { 0x78, 0x0f }; +static CVI_U8 data_ota7290b_121[] = { 0x79, 0xe0 }; +static CVI_U8 data_ota7290b_122[] = { 0x7a, 0x01 }; +static CVI_U8 data_ota7290b_123[] = { 0x7b, 0xff }; +static CVI_U8 data_ota7290b_124[] = { 0x7c, 0xff }; +static CVI_U8 data_ota7290b_125[] = { 0x7d, 0xff }; +static CVI_U8 data_ota7290b_126[] = { 0x7e, 0x4f }; +static CVI_U8 data_ota7290b_127[] = { 0x7f, 0xfe }; +static CVI_U8 data_ota7290b_128[] = { 0xb1, 0x02 }; +static CVI_U8 data_ota7290b_129[] = { 0x00, 0xff }; +static CVI_U8 data_ota7290b_130[] = { 0x01, 0x05 }; +static CVI_U8 data_ota7290b_131[] = { 0x02, 0xa0 }; +static CVI_U8 data_ota7290b_132[] = { 0x03, 0x00 }; +static CVI_U8 data_ota7290b_133[] = { 0x04, 0x54 }; +static CVI_U8 data_ota7290b_134[] = { 0x05, 0x38 }; +static CVI_U8 data_ota7290b_135[] = { 0x06, 0xa0 }; +static CVI_U8 data_ota7290b_136[] = { 0x07, 0x0a }; +static CVI_U8 data_ota7290b_137[] = { 0x08, 0xc0 }; +static CVI_U8 data_ota7290b_138[] = { 0x09, 0x00 }; +static CVI_U8 data_ota7290b_139[] = { 0x0a, 0x00 }; +static CVI_U8 data_ota7290b_140[] = { 0x0b, 0x14 }; +static CVI_U8 data_ota7290b_141[] = { 0x0c, 0xe6 }; +static CVI_U8 data_ota7290b_142[] = { 0x0d, 0x0d }; +static CVI_U8 data_ota7290b_143[] = { 0x0f, 0x08 }; +static CVI_U8 data_ota7290b_144[] = { 0x10, 0x79 }; +static CVI_U8 data_ota7290b_145[] = { 0x11, 0x38 }; +static CVI_U8 data_ota7290b_146[] = { 0x12, 0x73 }; +static CVI_U8 data_ota7290b_147[] = { 0x13, 0xb3 }; +static CVI_U8 data_ota7290b_148[] = { 0x14, 0x29 }; +static CVI_U8 data_ota7290b_149[] = { 0x15, 0x80 }; +static CVI_U8 data_ota7290b_150[] = { 0x16, 0x07 }; +static CVI_U8 data_ota7290b_151[] = { 0x17, 0x8a }; +static CVI_U8 data_ota7290b_152[] = { 0x18, 0x8d }; +static CVI_U8 data_ota7290b_153[] = { 0x19, 0xbf }; +static CVI_U8 data_ota7290b_154[] = { 0x1a, 0x69 }; +static CVI_U8 data_ota7290b_155[] = { 0x1b, 0x0e }; +static CVI_U8 data_ota7290b_156[] = { 0x1c, 0xff }; +static CVI_U8 data_ota7290b_157[] = { 0x1d, 0xff }; +static CVI_U8 data_ota7290b_158[] = { 0x1e, 0xff }; +static CVI_U8 data_ota7290b_159[] = { 0x1f, 0xff }; +static CVI_U8 data_ota7290b_160[] = { 0x20, 0xff }; +static CVI_U8 data_ota7290b_161[] = { 0x21, 0xff }; +static CVI_U8 data_ota7290b_162[] = { 0x22, 0xff }; +static CVI_U8 data_ota7290b_163[] = { 0x23, 0xff }; +static CVI_U8 data_ota7290b_164[] = { 0x24, 0xff }; +static CVI_U8 data_ota7290b_165[] = { 0x25, 0xff }; +static CVI_U8 data_ota7290b_166[] = { 0x26, 0xff }; +static CVI_U8 data_ota7290b_167[] = { 0x27, 0x1f }; +static CVI_U8 data_ota7290b_168[] = { 0x28, 0xff }; +static CVI_U8 data_ota7290b_169[] = { 0x29, 0xff }; +static CVI_U8 data_ota7290b_170[] = { 0x2a, 0xff }; +static CVI_U8 data_ota7290b_171[] = { 0x2b, 0xff }; +static CVI_U8 data_ota7290b_172[] = { 0x2c, 0xff }; +static CVI_U8 data_ota7290b_173[] = { 0x2d, 0x07 }; +static CVI_U8 data_ota7290b_174[] = { 0x33, 0x06 }; +static CVI_U8 data_ota7290b_175[] = { 0x35, 0x7e }; +static CVI_U8 data_ota7290b_176[] = { 0x36, 0x06 }; +static CVI_U8 data_ota7290b_177[] = { 0x38, 0x7e }; +static CVI_U8 data_ota7290b_178[] = { 0x3a, 0x80 }; +static CVI_U8 data_ota7290b_179[] = { 0x3b, 0x01 }; +static CVI_U8 data_ota7290b_180[] = { 0x3c, 0x00 }; +static CVI_U8 data_ota7290b_181[] = { 0x3d, 0x2a }; +static CVI_U8 data_ota7290b_182[] = { 0x3e, 0x00 }; +static CVI_U8 data_ota7290b_183[] = { 0x3f, 0x40 }; +static CVI_U8 data_ota7290b_184[] = { 0x40, 0x05 }; +static CVI_U8 data_ota7290b_185[] = { 0x41, 0x00 }; +static CVI_U8 data_ota7290b_186[] = { 0x42, 0xa8 }; +static CVI_U8 data_ota7290b_187[] = { 0x43, 0x00 }; +static CVI_U8 data_ota7290b_188[] = { 0x44, 0x00 }; +static CVI_U8 data_ota7290b_189[] = { 0x45, 0x05 }; +static CVI_U8 data_ota7290b_190[] = { 0x46, 0x00 }; +static CVI_U8 data_ota7290b_191[] = { 0x47, 0x00 }; +static CVI_U8 data_ota7290b_192[] = { 0x48, 0x9b }; +static CVI_U8 data_ota7290b_193[] = { 0x49, 0xd2 }; +static CVI_U8 data_ota7290b_194[] = { 0x4a, 0x81 }; +static CVI_U8 data_ota7290b_195[] = { 0x4b, 0x02 }; +static CVI_U8 data_ota7290b_196[] = { 0x4c, 0x15 }; +static CVI_U8 data_ota7290b_197[] = { 0x4d, 0xc0 }; +static CVI_U8 data_ota7290b_198[] = { 0x4e, 0x0f }; +static CVI_U8 data_ota7290b_199[] = { 0x4f, 0x61 }; +static CVI_U8 data_ota7290b_200[] = { 0x50, 0x78 }; +static CVI_U8 data_ota7290b_201[] = { 0x51, 0x7a }; +static CVI_U8 data_ota7290b_202[] = { 0x52, 0x34 }; +static CVI_U8 data_ota7290b_203[] = { 0x53, 0x99 }; +static CVI_U8 data_ota7290b_204[] = { 0x54, 0xa2 }; +static CVI_U8 data_ota7290b_205[] = { 0x55, 0x02 }; +static CVI_U8 data_ota7290b_206[] = { 0x56, 0x14 }; +static CVI_U8 data_ota7290b_207[] = { 0x57, 0xb8 }; +static CVI_U8 data_ota7290b_208[] = { 0x58, 0xdc }; +static CVI_U8 data_ota7290b_209[] = { 0x59, 0x34 }; +static CVI_U8 data_ota7290b_210[] = { 0x5a, 0x1e }; +static CVI_U8 data_ota7290b_211[] = { 0x5b, 0x8f }; +static CVI_U8 data_ota7290b_212[] = { 0x5c, 0xc7 }; +static CVI_U8 data_ota7290b_213[] = { 0x5d, 0xe3 }; +static CVI_U8 data_ota7290b_214[] = { 0x5e, 0xf1 }; +static CVI_U8 data_ota7290b_215[] = { 0x5f, 0x78 }; +static CVI_U8 data_ota7290b_216[] = { 0x60, 0x3c }; +static CVI_U8 data_ota7290b_217[] = { 0x61, 0x36 }; +static CVI_U8 data_ota7290b_218[] = { 0x62, 0x1e }; +static CVI_U8 data_ota7290b_219[] = { 0x63, 0x1b }; +static CVI_U8 data_ota7290b_220[] = { 0x64, 0x8f }; +static CVI_U8 data_ota7290b_221[] = { 0x65, 0xc7 }; +static CVI_U8 data_ota7290b_222[] = { 0x66, 0xe3 }; +static CVI_U8 data_ota7290b_223[] = { 0x67, 0x31 }; +static CVI_U8 data_ota7290b_224[] = { 0x68, 0x0c }; +static CVI_U8 data_ota7290b_225[] = { 0x69, 0x89 }; +static CVI_U8 data_ota7290b_226[] = { 0x6a, 0x30 }; +static CVI_U8 data_ota7290b_227[] = { 0x6b, 0x8c }; +static CVI_U8 data_ota7290b_228[] = { 0x6c, 0x8d }; +static CVI_U8 data_ota7290b_229[] = { 0x6d, 0x8d }; +static CVI_U8 data_ota7290b_230[] = { 0x6e, 0x8d }; +static CVI_U8 data_ota7290b_231[] = { 0x6f, 0x8d }; +static CVI_U8 data_ota7290b_232[] = { 0x70, 0xc7 }; +static CVI_U8 data_ota7290b_233[] = { 0x71, 0xe3 }; +static CVI_U8 data_ota7290b_234[] = { 0x72, 0x31 }; +static CVI_U8 data_ota7290b_235[] = { 0x73, 0x00 }; +static CVI_U8 data_ota7290b_236[] = { 0x74, 0x00 }; +static CVI_U8 data_ota7290b_237[] = { 0x75, 0x00 }; +static CVI_U8 data_ota7290b_238[] = { 0x76, 0x00 }; +static CVI_U8 data_ota7290b_239[] = { 0x77, 0x00 }; +static CVI_U8 data_ota7290b_240[] = { 0x78, 0x00 }; +static CVI_U8 data_ota7290b_241[] = { 0x79, 0x00 }; +static CVI_U8 data_ota7290b_242[] = { 0x7a, 0xc6 }; +static CVI_U8 data_ota7290b_243[] = { 0x7b, 0xc6 }; +static CVI_U8 data_ota7290b_244[] = { 0x7c, 0xc6 }; +static CVI_U8 data_ota7290b_245[] = { 0x7d, 0xc6 }; +static CVI_U8 data_ota7290b_246[] = { 0x7e, 0xc6 }; +static CVI_U8 data_ota7290b_247[] = { 0x7f, 0xe3 }; +static CVI_U8 data_ota7290b_248[] = { 0x0b, 0x00 }; +static CVI_U8 data_ota7290b_249[] = { 0xb1, 0x03 }; +static CVI_U8 data_ota7290b_250[] = { 0x2c, 0x2c }; +static CVI_U8 data_ota7290b_251[] = { 0xb1, 0x00 }; +static CVI_U8 data_ota7290b_252[] = { 0x89, 0x03 }; +const struct dsc_instr dsi_init_cmds_ota7290b_320x1280[] = { + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_0 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_2 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_3 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_4 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_5 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_6 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_7 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_8 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_11 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_16 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_17 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_18 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_19 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_20 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_21 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_22 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_23 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_24 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_25 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_26 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_27 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_28 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_29 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_30 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_31 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_32 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_33 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_34 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_35 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_36 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_37 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_38 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_39 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_40 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_41 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_42 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_43 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_44 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_45 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_46 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_47 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_48 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_49 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_50 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_51 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_52 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_53 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_54 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_55 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_56 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_57 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_58 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_59 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_60 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_61 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_62 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_63 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_64 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_65 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_66 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_67 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_68 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_69 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_70 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_71 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_72 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_73 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_74 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_75 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_76 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_77 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_78 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_79 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_80 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_81 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_82 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_83 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_84 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_85 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_86 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_87 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_88 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_89 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_90 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_91 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_92 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_93 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_94 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_95 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_96 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_97 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_98 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_99 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_100 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_101 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_102 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_103 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_104 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_105 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_106 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_107 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_108 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_109 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_110 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_111 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_112 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_113 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_114 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_115 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_116 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_117 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_118 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_119 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_120 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_121 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_122 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_123 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_124 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_125 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_126 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_127 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_128 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_129 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_130 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_131 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_132 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_133 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_134 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_135 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_136 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_137 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_138 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_139 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_140 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_141 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_142 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_143 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_144 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_145 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_146 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_147 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_148 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_149 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_150 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_151 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_152 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_153 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_154 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_155 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_156 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_157 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_158 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_159 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_160 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_161 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_162 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_163 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_164 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_165 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_166 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_167 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_168 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_169 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_170 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_171 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_172 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_173 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_174 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_175 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_176 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_177 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_178 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_179 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_180 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_181 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_182 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_183 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_184 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_185 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_186 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_187 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_188 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_189 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_190 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_191 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_192 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_193 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_194 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_195 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_196 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_197 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_198 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_199 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_200 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_201 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_202 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_203 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_204 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_205 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_206 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_207 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_208 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_209 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_210 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_211 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_212 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_213 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_214 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_215 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_216 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_217 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_218 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_219 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_220 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_221 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_222 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_223 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_224 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_225 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_226 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_227 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_228 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_229 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_230 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_231 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_232 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_233 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_234 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_235 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_236 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_237 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_238 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_239 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_240 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_241 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_242 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_243 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_244 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_245 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_246 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_247 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_248 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_249 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_250 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_251 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_252 } +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_OTA7290B_H_ diff --git a/middleware/v2/component/panel/cv181x/dsi_ota7290b_1920.h b/middleware/v2/component/panel/cv181x/dsi_ota7290b_1920.h new file mode 100644 index 000000000..4483cf2b2 --- /dev/null +++ b/middleware/v2/component/panel/cv181x/dsi_ota7290b_1920.h @@ -0,0 +1,554 @@ +#ifndef _MIPI_TX_PARAM_OTA7290B_1920_H_ +#define _MIPI_TX_PARAM_OTA7290B_1920_H_ + +#include +#include + +// Not support BTA +const struct combo_dev_cfg_s dev_cfg_ota7290b_440x1920 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_3, MIPI_TX_LANE_2, MIPI_TX_LANE_CLK, MIPI_TX_LANE_1, MIPI_TX_LANE_0}, + .lane_pn_swap = {true, true, true, true, true}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = 30, + .vid_hbp_pixels = 50, + .vid_hfp_pixels = 150, + .vid_hline_pixels = 440, + .vid_vsa_lines = 20, + .vid_vbp_lines = 30, + .vid_vfp_lines = 150, + .vid_active_lines = 1920, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 85224, +}; + +const struct hs_settle_s hs_timing_cfg_ota7290b_440x1920 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_ota7290b_1920_0[] = { 0x11, 0x00 }; +static CVI_U8 data_ota7290b_1920_1[] = { 0xb0, 0x5a }; +static CVI_U8 data_ota7290b_1920_2[] = { 0xb0, 0x5a }; +static CVI_U8 data_ota7290b_1920_3[] = { 0xb1, 0x00 }; +static CVI_U8 data_ota7290b_1920_4[] = { 0x89, 0x01 }; +#ifdef _MIPI_TX_BIST_MODE_ +static CVI_U8 data_ota7290b_1920_5[] = { 0x91, 0x16 }; +#else +static CVI_U8 data_ota7290b_1920_5[] = { 0x91, 0x17 }; +#endif +static CVI_U8 data_ota7290b_1920_6[] = { 0xb1, 0x03 }; +static CVI_U8 data_ota7290b_1920_7[] = { 0x2c, 0x28 }; +static CVI_U8 data_ota7290b_1920_8[] = { 0x00, 0xb7 }; +static CVI_U8 data_ota7290b_1920_9[] = { 0x01, 0x1b }; +static CVI_U8 data_ota7290b_1920_10[] = { 0x02, 0x00 }; +static CVI_U8 data_ota7290b_1920_11[] = { 0x03, 0x00 }; +static CVI_U8 data_ota7290b_1920_12[] = { 0x04, 0x00 }; +static CVI_U8 data_ota7290b_1920_13[] = { 0x05, 0x00 }; +static CVI_U8 data_ota7290b_1920_14[] = { 0x06, 0x00 }; +static CVI_U8 data_ota7290b_1920_15[] = { 0x07, 0x00 }; +static CVI_U8 data_ota7290b_1920_16[] = { 0x08, 0x00 }; +static CVI_U8 data_ota7290b_1920_17[] = { 0x09, 0x00 }; +static CVI_U8 data_ota7290b_1920_18[] = { 0x0a, 0x01 }; +static CVI_U8 data_ota7290b_1920_19[] = { 0x0b, 0x3c }; +static CVI_U8 data_ota7290b_1920_20[] = { 0x0c, 0x00 }; +static CVI_U8 data_ota7290b_1920_21[] = { 0x0d, 0x00 }; +static CVI_U8 data_ota7290b_1920_22[] = { 0x0e, 0x24 }; +static CVI_U8 data_ota7290b_1920_23[] = { 0x0f, 0x1c }; +static CVI_U8 data_ota7290b_1920_24[] = { 0x10, 0xc9 }; +static CVI_U8 data_ota7290b_1920_25[] = { 0x11, 0x60 }; +static CVI_U8 data_ota7290b_1920_26[] = { 0x12, 0x70 }; +static CVI_U8 data_ota7290b_1920_27[] = { 0x13, 0x01 }; +static CVI_U8 data_ota7290b_1920_28[] = { 0x14, 0xe3 }; +static CVI_U8 data_ota7290b_1920_29[] = { 0x15, 0xff }; +static CVI_U8 data_ota7290b_1920_30[] = { 0x16, 0x3d }; +static CVI_U8 data_ota7290b_1920_31[] = { 0x17, 0x0e }; +static CVI_U8 data_ota7290b_1920_32[] = { 0x18, 0x01 }; +static CVI_U8 data_ota7290b_1920_33[] = { 0x19, 0x00 }; +static CVI_U8 data_ota7290b_1920_34[] = { 0x1a, 0x00 }; +static CVI_U8 data_ota7290b_1920_35[] = { 0x1b, 0xfc }; +static CVI_U8 data_ota7290b_1920_36[] = { 0x1c, 0x0b }; +static CVI_U8 data_ota7290b_1920_37[] = { 0x1d, 0xa0 }; +static CVI_U8 data_ota7290b_1920_38[] = { 0x1e, 0x03 }; +static CVI_U8 data_ota7290b_1920_39[] = { 0x1f, 0x04 }; +static CVI_U8 data_ota7290b_1920_40[] = { 0x20, 0x0c }; +static CVI_U8 data_ota7290b_1920_41[] = { 0x21, 0x00 }; +static CVI_U8 data_ota7290b_1920_42[] = { 0x22, 0x04 }; +static CVI_U8 data_ota7290b_1920_43[] = { 0x23, 0x81 }; +static CVI_U8 data_ota7290b_1920_44[] = { 0x24, 0x1f }; +static CVI_U8 data_ota7290b_1920_45[] = { 0x25, 0x10 }; +static CVI_U8 data_ota7290b_1920_46[] = { 0x26, 0x9b }; +static CVI_U8 data_ota7290b_1920_47[] = { 0x2d, 0x01 }; +static CVI_U8 data_ota7290b_1920_48[] = { 0x2e, 0x84 }; +static CVI_U8 data_ota7290b_1920_49[] = { 0x2f, 0x00 }; +static CVI_U8 data_ota7290b_1920_50[] = { 0x30, 0x02 }; +static CVI_U8 data_ota7290b_1920_51[] = { 0x31, 0x08 }; +static CVI_U8 data_ota7290b_1920_52[] = { 0x32, 0x01 }; +static CVI_U8 data_ota7290b_1920_53[] = { 0x33, 0x1c }; +static CVI_U8 data_ota7290b_1920_54[] = { 0x34, 0x70 }; +static CVI_U8 data_ota7290b_1920_55[] = { 0x35, 0xff }; +static CVI_U8 data_ota7290b_1920_56[] = { 0x36, 0xff }; +static CVI_U8 data_ota7290b_1920_57[] = { 0x37, 0xff }; +static CVI_U8 data_ota7290b_1920_58[] = { 0x38, 0xff }; +static CVI_U8 data_ota7290b_1920_59[] = { 0x39, 0xff }; +static CVI_U8 data_ota7290b_1920_60[] = { 0x3a, 0x05 }; +static CVI_U8 data_ota7290b_1920_61[] = { 0x3b, 0x00 }; +static CVI_U8 data_ota7290b_1920_62[] = { 0x3c, 0x00 }; +static CVI_U8 data_ota7290b_1920_63[] = { 0x3d, 0x00 }; +static CVI_U8 data_ota7290b_1920_64[] = { 0x3e, 0x0f }; +static CVI_U8 data_ota7290b_1920_65[] = { 0x3f, 0x8c }; +static CVI_U8 data_ota7290b_1920_66[] = { 0x40, 0x2a }; +static CVI_U8 data_ota7290b_1920_67[] = { 0x41, 0xfc }; +static CVI_U8 data_ota7290b_1920_68[] = { 0x42, 0x01 }; +static CVI_U8 data_ota7290b_1920_69[] = { 0x43, 0x40 }; +static CVI_U8 data_ota7290b_1920_70[] = { 0x44, 0x05 }; +static CVI_U8 data_ota7290b_1920_71[] = { 0x45, 0xe8 }; +static CVI_U8 data_ota7290b_1920_72[] = { 0x46, 0x16 }; +static CVI_U8 data_ota7290b_1920_73[] = { 0x47, 0x00 }; +static CVI_U8 data_ota7290b_1920_74[] = { 0x48, 0x00 }; +static CVI_U8 data_ota7290b_1920_75[] = { 0x49, 0x88 }; +static CVI_U8 data_ota7290b_1920_76[] = { 0x4a, 0x08 }; +static CVI_U8 data_ota7290b_1920_77[] = { 0x4b, 0x05 }; +static CVI_U8 data_ota7290b_1920_78[] = { 0x4c, 0x03 }; +static CVI_U8 data_ota7290b_1920_79[] = { 0x4d, 0xd0 }; +static CVI_U8 data_ota7290b_1920_80[] = { 0x4e, 0x13 }; +static CVI_U8 data_ota7290b_1920_81[] = { 0x4f, 0xff }; +static CVI_U8 data_ota7290b_1920_82[] = { 0x50, 0x0a }; +static CVI_U8 data_ota7290b_1920_83[] = { 0x51, 0x53 }; +static CVI_U8 data_ota7290b_1920_84[] = { 0x52, 0x26 }; +static CVI_U8 data_ota7290b_1920_85[] = { 0x53, 0x22 }; +static CVI_U8 data_ota7290b_1920_86[] = { 0x54, 0x09 }; +static CVI_U8 data_ota7290b_1920_87[] = { 0x55, 0x22 }; +static CVI_U8 data_ota7290b_1920_88[] = { 0x56, 0x00 }; +static CVI_U8 data_ota7290b_1920_89[] = { 0x57, 0x1c }; +static CVI_U8 data_ota7290b_1920_90[] = { 0x58, 0x03 }; +static CVI_U8 data_ota7290b_1920_91[] = { 0x59, 0x3f }; +static CVI_U8 data_ota7290b_1920_92[] = { 0x5a, 0x28 }; +static CVI_U8 data_ota7290b_1920_93[] = { 0x5b, 0x01 }; +static CVI_U8 data_ota7290b_1920_94[] = { 0x5c, 0xcc }; +static CVI_U8 data_ota7290b_1920_95[] = { 0x5d, 0x20 }; +static CVI_U8 data_ota7290b_1920_96[] = { 0x5e, 0xe8 }; +static CVI_U8 data_ota7290b_1920_97[] = { 0x5f, 0x1d }; +static CVI_U8 data_ota7290b_1920_98[] = { 0x60, 0xe1 }; +static CVI_U8 data_ota7290b_1920_99[] = { 0x61, 0x73 }; +static CVI_U8 data_ota7290b_1920_100[] = { 0x62, 0x8d }; +static CVI_U8 data_ota7290b_1920_101[] = { 0x63, 0x2d }; +static CVI_U8 data_ota7290b_1920_102[] = { 0x64, 0x25 }; +static CVI_U8 data_ota7290b_1920_103[] = { 0x65, 0x82 }; +static CVI_U8 data_ota7290b_1920_104[] = { 0x66, 0x09 }; +static CVI_U8 data_ota7290b_1920_105[] = { 0x67, 0x21 }; +static CVI_U8 data_ota7290b_1920_106[] = { 0x68, 0x84 }; +static CVI_U8 data_ota7290b_1920_107[] = { 0x69, 0x10 }; +static CVI_U8 data_ota7290b_1920_108[] = { 0x6a, 0x42 }; +static CVI_U8 data_ota7290b_1920_109[] = { 0x6b, 0x08 }; +static CVI_U8 data_ota7290b_1920_110[] = { 0x6c, 0x21 }; +static CVI_U8 data_ota7290b_1920_111[] = { 0x6d, 0x84 }; +static CVI_U8 data_ota7290b_1920_112[] = { 0x6e, 0x10 }; +static CVI_U8 data_ota7290b_1920_113[] = { 0x6f, 0x42 }; +static CVI_U8 data_ota7290b_1920_114[] = { 0x70, 0x08 }; +static CVI_U8 data_ota7290b_1920_115[] = { 0x71, 0x21 }; +static CVI_U8 data_ota7290b_1920_116[] = { 0x72, 0x84 }; +static CVI_U8 data_ota7290b_1920_117[] = { 0x73, 0x10 }; +static CVI_U8 data_ota7290b_1920_118[] = { 0x74, 0x42 }; +static CVI_U8 data_ota7290b_1920_119[] = { 0x75, 0x08 }; +static CVI_U8 data_ota7290b_1920_120[] = { 0x76, 0x00 }; +static CVI_U8 data_ota7290b_1920_121[] = { 0x77, 0x00 }; +static CVI_U8 data_ota7290b_1920_122[] = { 0x78, 0x0f }; +static CVI_U8 data_ota7290b_1920_123[] = { 0x79, 0xe0 }; +static CVI_U8 data_ota7290b_1920_124[] = { 0x7a, 0x01 }; +static CVI_U8 data_ota7290b_1920_125[] = { 0x7b, 0xff }; +static CVI_U8 data_ota7290b_1920_126[] = { 0x7c, 0xff }; +static CVI_U8 data_ota7290b_1920_127[] = { 0x7d, 0x0c }; +static CVI_U8 data_ota7290b_1920_128[] = { 0x7e, 0x41 }; +static CVI_U8 data_ota7290b_1920_129[] = { 0x7f, 0xfe }; +static CVI_U8 data_ota7290b_1920_130[] = { 0xb1, 0x02 }; +static CVI_U8 data_ota7290b_1920_131[] = { 0x00, 0xff }; +static CVI_U8 data_ota7290b_1920_132[] = { 0x01, 0x05 }; +static CVI_U8 data_ota7290b_1920_133[] = { 0x02, 0xdc }; +static CVI_U8 data_ota7290b_1920_134[] = { 0x03, 0x00 }; +static CVI_U8 data_ota7290b_1920_135[] = { 0x04, 0x3e }; +static CVI_U8 data_ota7290b_1920_136[] = { 0x05, 0x4e }; +static CVI_U8 data_ota7290b_1920_137[] = { 0x06, 0x90 }; +static CVI_U8 data_ota7290b_1920_138[] = { 0x07, 0x10 }; +static CVI_U8 data_ota7290b_1920_139[] = { 0x08, 0xc0 }; +static CVI_U8 data_ota7290b_1920_140[] = { 0x09, 0x01 }; +static CVI_U8 data_ota7290b_1920_141[] = { 0x0a, 0x00 }; +static CVI_U8 data_ota7290b_1920_142[] = { 0x0b, 0x14 }; +static CVI_U8 data_ota7290b_1920_143[] = { 0x0c, 0xe6 }; +static CVI_U8 data_ota7290b_1920_144[] = { 0x0d, 0x0d }; +static CVI_U8 data_ota7290b_1920_145[] = { 0x0f, 0x08 }; +static CVI_U8 data_ota7290b_1920_146[] = { 0x10, 0xf9 }; +static CVI_U8 data_ota7290b_1920_147[] = { 0x11, 0xf5 }; +static CVI_U8 data_ota7290b_1920_148[] = { 0x12, 0xa2 }; +static CVI_U8 data_ota7290b_1920_149[] = { 0x13, 0x03 }; +static CVI_U8 data_ota7290b_1920_150[] = { 0x14, 0x5e }; +static CVI_U8 data_ota7290b_1920_151[] = { 0x15, 0xcf }; +static CVI_U8 data_ota7290b_1920_152[] = { 0x16, 0x63 }; +static CVI_U8 data_ota7290b_1920_153[] = { 0x17, 0x01 }; +static CVI_U8 data_ota7290b_1920_154[] = { 0x18, 0xe9 }; +static CVI_U8 data_ota7290b_1920_155[] = { 0x19, 0x5e }; +static CVI_U8 data_ota7290b_1920_156[] = { 0x1a, 0x59 }; +static CVI_U8 data_ota7290b_1920_157[] = { 0x1b, 0x0e }; +static CVI_U8 data_ota7290b_1920_158[] = { 0x1c, 0xff }; +static CVI_U8 data_ota7290b_1920_159[] = { 0x1d, 0xff }; +static CVI_U8 data_ota7290b_1920_160[] = { 0x1e, 0xff }; +static CVI_U8 data_ota7290b_1920_161[] = { 0x1f, 0xff }; +static CVI_U8 data_ota7290b_1920_162[] = { 0x20, 0xff }; +static CVI_U8 data_ota7290b_1920_163[] = { 0x21, 0xff }; +static CVI_U8 data_ota7290b_1920_164[] = { 0x22, 0xff }; +static CVI_U8 data_ota7290b_1920_165[] = { 0x23, 0xff }; +static CVI_U8 data_ota7290b_1920_166[] = { 0x24, 0xff }; +static CVI_U8 data_ota7290b_1920_167[] = { 0x25, 0xff }; +static CVI_U8 data_ota7290b_1920_168[] = { 0x26, 0xff }; +static CVI_U8 data_ota7290b_1920_169[] = { 0x27, 0x1f }; +static CVI_U8 data_ota7290b_1920_170[] = { 0x28, 0xff }; +static CVI_U8 data_ota7290b_1920_171[] = { 0x29, 0xff }; +static CVI_U8 data_ota7290b_1920_172[] = { 0x2a, 0xff }; +static CVI_U8 data_ota7290b_1920_173[] = { 0x2b, 0xff }; +static CVI_U8 data_ota7290b_1920_174[] = { 0x2c, 0xff }; +static CVI_U8 data_ota7290b_1920_175[] = { 0x2d, 0x07 }; +static CVI_U8 data_ota7290b_1920_176[] = { 0x33, 0x00 }; +static CVI_U8 data_ota7290b_1920_177[] = { 0x35, 0x7e }; +static CVI_U8 data_ota7290b_1920_178[] = { 0x36, 0x00 }; +static CVI_U8 data_ota7290b_1920_179[] = { 0x38, 0x7e }; +static CVI_U8 data_ota7290b_1920_180[] = { 0x3a, 0x80 }; +static CVI_U8 data_ota7290b_1920_181[] = { 0x3b, 0x01 }; +static CVI_U8 data_ota7290b_1920_182[] = { 0x3c, 0xc0 }; +static CVI_U8 data_ota7290b_1920_183[] = { 0x3d, 0x2d }; +static CVI_U8 data_ota7290b_1920_184[] = { 0x3e, 0x00 }; +static CVI_U8 data_ota7290b_1920_185[] = { 0x3f, 0xb8 }; +static CVI_U8 data_ota7290b_1920_186[] = { 0x40, 0x05 }; +static CVI_U8 data_ota7290b_1920_187[] = { 0x41, 0x00 }; +static CVI_U8 data_ota7290b_1920_188[] = { 0x42, 0xb7 }; +static CVI_U8 data_ota7290b_1920_189[] = { 0x43, 0x00 }; +static CVI_U8 data_ota7290b_1920_190[] = { 0x44, 0xe0 }; +static CVI_U8 data_ota7290b_1920_191[] = { 0x45, 0x06 }; +static CVI_U8 data_ota7290b_1920_192[] = { 0x46, 0x00 }; +static CVI_U8 data_ota7290b_1920_193[] = { 0x47, 0x00 }; +static CVI_U8 data_ota7290b_1920_194[] = { 0x48, 0x9b }; +static CVI_U8 data_ota7290b_1920_195[] = { 0x49, 0xd2 }; +static CVI_U8 data_ota7290b_1920_196[] = { 0x4a, 0x71 }; +static CVI_U8 data_ota7290b_1920_197[] = { 0x4b, 0xe3 }; +static CVI_U8 data_ota7290b_1920_198[] = { 0x4c, 0x16 }; +static CVI_U8 data_ota7290b_1920_199[] = { 0x4d, 0xc0 }; +static CVI_U8 data_ota7290b_1920_200[] = { 0x4e, 0x0f }; +static CVI_U8 data_ota7290b_1920_201[] = { 0x4f, 0x61 }; +static CVI_U8 data_ota7290b_1920_202[] = { 0x50, 0x78 }; +static CVI_U8 data_ota7290b_1920_203[] = { 0x51, 0x7a }; +static CVI_U8 data_ota7290b_1920_204[] = { 0x52, 0x34 }; +static CVI_U8 data_ota7290b_1920_205[] = { 0x53, 0x99 }; +static CVI_U8 data_ota7290b_1920_206[] = { 0x54, 0xa2 }; +static CVI_U8 data_ota7290b_1920_207[] = { 0x55, 0x02 }; +static CVI_U8 data_ota7290b_1920_208[] = { 0x56, 0x24 }; +static CVI_U8 data_ota7290b_1920_209[] = { 0x57, 0xf8 }; +static CVI_U8 data_ota7290b_1920_210[] = { 0x58, 0xfc }; +static CVI_U8 data_ota7290b_1920_211[] = { 0x59, 0xf4 }; +static CVI_U8 data_ota7290b_1920_212[] = { 0x5a, 0xff }; +static CVI_U8 data_ota7290b_1920_213[] = { 0x5b, 0xff }; +static CVI_U8 data_ota7290b_1920_214[] = { 0x5c, 0xff }; +static CVI_U8 data_ota7290b_1920_215[] = { 0x5d, 0xb2 }; +static CVI_U8 data_ota7290b_1920_216[] = { 0x5e, 0xff }; +static CVI_U8 data_ota7290b_1920_217[] = { 0x5f, 0xff }; +static CVI_U8 data_ota7290b_1920_218[] = { 0x60, 0x8f }; +static CVI_U8 data_ota7290b_1920_219[] = { 0x61, 0x62 }; +static CVI_U8 data_ota7290b_1920_220[] = { 0x62, 0xb5 }; +static CVI_U8 data_ota7290b_1920_221[] = { 0x63, 0xb2 }; +static CVI_U8 data_ota7290b_1920_222[] = { 0x64, 0x5a }; +static CVI_U8 data_ota7290b_1920_223[] = { 0x65, 0xad }; +static CVI_U8 data_ota7290b_1920_224[] = { 0x66, 0x56 }; +static CVI_U8 data_ota7290b_1920_225[] = { 0x67, 0x2b }; +static CVI_U8 data_ota7290b_1920_226[] = { 0x68, 0x0c }; +static CVI_U8 data_ota7290b_1920_227[] = { 0x69, 0x01 }; +static CVI_U8 data_ota7290b_1920_228[] = { 0x6a, 0x01 }; +static CVI_U8 data_ota7290b_1920_229[] = { 0x6b, 0xfc }; +static CVI_U8 data_ota7290b_1920_230[] = { 0x6c, 0xfd }; +static CVI_U8 data_ota7290b_1920_231[] = { 0x6d, 0xfd }; +static CVI_U8 data_ota7290b_1920_232[] = { 0x6e, 0xfd }; +static CVI_U8 data_ota7290b_1920_233[] = { 0x6f, 0xfd }; +static CVI_U8 data_ota7290b_1920_234[] = { 0x70, 0xff }; +static CVI_U8 data_ota7290b_1920_235[] = { 0x71, 0xff }; +static CVI_U8 data_ota7290b_1920_236[] = { 0x72, 0x3f }; +static CVI_U8 data_ota7290b_1920_237[] = { 0x73, 0x00 }; +static CVI_U8 data_ota7290b_1920_238[] = { 0x74, 0x00 }; +static CVI_U8 data_ota7290b_1920_239[] = { 0x75, 0x00 }; +static CVI_U8 data_ota7290b_1920_240[] = { 0x76, 0x00 }; +static CVI_U8 data_ota7290b_1920_241[] = { 0x77, 0x00 }; +static CVI_U8 data_ota7290b_1920_242[] = { 0x78, 0x00 }; +static CVI_U8 data_ota7290b_1920_243[] = { 0x79, 0x00 }; +static CVI_U8 data_ota7290b_1920_244[] = { 0x7a, 0xdc }; +static CVI_U8 data_ota7290b_1920_245[] = { 0x7b, 0xdc }; +static CVI_U8 data_ota7290b_1920_246[] = { 0x7c, 0xdc }; +static CVI_U8 data_ota7290b_1920_247[] = { 0x7d, 0xdc }; +static CVI_U8 data_ota7290b_1920_248[] = { 0x7e, 0xdc }; +static CVI_U8 data_ota7290b_1920_249[] = { 0x7f, 0x6e }; +static CVI_U8 data_ota7290b_1920_250[] = { 0x0b, 0x04 }; +static CVI_U8 data_ota7290b_1920_251[] = { 0xb1, 0x03 }; +static CVI_U8 data_ota7290b_1920_252[] = { 0x2c, 0x2c }; +static CVI_U8 data_ota7290b_1920_253[] = { 0xb1, 0x00 }; +static CVI_U8 data_ota7290b_1920_254[] = { 0x89, 0x03 }; +static CVI_U8 data_ota7290b_1920_255[] = { 0x29, 0x00 }; + +const struct dsc_instr dsi_init_cmds_ota7290b_440x1920[] = { + {.delay = 250, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_0 }, + {.delay = 50, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_1 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_2 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_3 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_4 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_5 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_6 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_7 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_8 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_11 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_16 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_17 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_18 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_19 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_20 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_21 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_22 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_23 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_24 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_25 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_26 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_27 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_28 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_29 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_30 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_31 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_32 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_33 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_34 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_35 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_36 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_37 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_38 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_39 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_40 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_41 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_42 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_43 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_44 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_45 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_46 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_47 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_48 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_49 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_50 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_51 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_52 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_53 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_54 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_55 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_56 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_57 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_58 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_59 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_60 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_61 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_62 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_63 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_64 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_65 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_66 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_67 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_68 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_69 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_70 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_71 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_72 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_73 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_74 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_75 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_76 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_77 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_78 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_79 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_80 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_81 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_82 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_83 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_84 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_85 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_86 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_87 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_88 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_89 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_90 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_91 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_92 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_93 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_94 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_95 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_96 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_97 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_98 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_99 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_100 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_101 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_102 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_103 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_104 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_105 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_106 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_107 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_108 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_109 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_110 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_111 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_112 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_113 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_114 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_115 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_116 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_117 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_118 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_119 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_120 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_121 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_122 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_123 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_124 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_125 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_126 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_127 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_128 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_129 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_130 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_131 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_132 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_133 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_134 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_135 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_136 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_137 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_138 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_139 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_140 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_141 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_142 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_143 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_144 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_145 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_146 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_147 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_148 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_149 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_150 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_151 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_152 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_153 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_154 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_155 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_156 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_157 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_158 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_159 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_160 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_161 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_162 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_163 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_164 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_165 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_166 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_167 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_168 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_169 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_170 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_171 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_172 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_173 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_174 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_175 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_176 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_177 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_178 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_179 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_180 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_181 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_182 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_183 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_184 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_185 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_186 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_187 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_188 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_189 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_190 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_191 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_192 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_193 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_194 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_195 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_196 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_197 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_198 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_199 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_200 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_201 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_202 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_203 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_204 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_205 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_206 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_207 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_208 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_209 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_210 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_211 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_212 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_213 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_214 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_215 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_216 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_217 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_218 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_219 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_220 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_221 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_222 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_223 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_224 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_225 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_226 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_227 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_228 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_229 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_230 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_231 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_232 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_233 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_234 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_235 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_236 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_237 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_238 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_239 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_240 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_241 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_242 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_243 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_244 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_245 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_246 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_247 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_248 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_249 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_250 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_251 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_252 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_253 }, + {.delay = 200, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_254 }, + {.delay = 50, .data_type = 0x15, .size = 2, .data = data_ota7290b_1920_255 } +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_OTA7290B_1920_H_ diff --git a/middleware/v2/component/panel/cv181x/dsi_st7701.h b/middleware/v2/component/panel/cv181x/dsi_st7701.h new file mode 100644 index 000000000..a38a4a341 --- /dev/null +++ b/middleware/v2/component/panel/cv181x/dsi_st7701.h @@ -0,0 +1,161 @@ +#ifndef _MIPI_TX_PARAM_ST_7701_H_ +#define _MIPI_TX_PARAM_ST_7701_H_ + +#include +#include + +#define PANEL_NAME "NETEASE-2" + +#define ST7701_NETEASE_VACT 800 +#define ST7701_NETEASE_VSA 10 +#define ST7701_NETEASE_VBP 20 +#define ST7701_NETEASE_VFP 20 + +#define ST7701_NETEASE_HACT 480 +#define ST7701_NETEASE_HSA 10 +#define ST7701_NETEASE_HBP 50 +#define ST7701_NETEASE_HFP 50 + +#define PIXEL_CLK(x) ((x##_VACT + x##_VSA + x##_VBP + x##_VFP) \ + * (x##_HACT + x##_HSA + x##_HBP + x##_HFP) * 60 / 1000) + +const struct combo_dev_cfg_s dev_cfg_st7701_480x800 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_1, MIPI_TX_LANE_0, MIPI_TX_LANE_CLK, -1, -1}, + .lane_pn_swap = {false, false, false, false, false}, + .output_mode = OUTPUT_MODE_DSI_VIDEO, + .video_mode = BURST_MODE, + .output_format = OUT_FORMAT_RGB_24_BIT, + .sync_info = { + .vid_hsa_pixels = ST7701_NETEASE_HSA, + .vid_hbp_pixels = ST7701_NETEASE_HBP, + .vid_hfp_pixels = ST7701_NETEASE_HFP, + .vid_hline_pixels = ST7701_NETEASE_HACT, + .vid_vsa_lines = ST7701_NETEASE_VSA, + .vid_vbp_lines = ST7701_NETEASE_VBP, + .vid_vfp_lines = ST7701_NETEASE_VFP, + .vid_active_lines = ST7701_NETEASE_VACT, + .vid_vsa_pos_polarity = true, + .vid_hsa_pos_polarity = false, + }, + .pixel_clk = PIXEL_CLK(ST7701_NETEASE), +}; + +const struct hs_settle_s hs_timing_cfg_st7701_480x800 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_st7701_0[] = { 0xff, 0x77, 0x01, 0x00, 0x00, 0x13 }; +static CVI_U8 data_st7701_1[] = { 0xef, 0x08 }; +static CVI_U8 data_st7701_2[] = { 0xff, 0x77, 0x01, 0x00, 0x00, 0x10 }; +static CVI_U8 data_st7701_3[] = { 0xc0, 0x63, 0x00 }; +static CVI_U8 data_st7701_4[] = { 0xc1, 0x11, 0x0c }; +static CVI_U8 data_st7701_5[] = { 0xc2, 0x07, 0x08 }; +static CVI_U8 data_st7701_6[] = { 0xcc, 0x10 }; +static CVI_U8 data_st7701_7[] = { + 0xb0, 0x00, 0x0c, 0x13, 0x0d, 0x10, 0x06, 0x01, 0x08, 0x07, + 0x1e, 0x04, 0x13, 0x10, 0x2d, 0x31, 0x10 +}; +static CVI_U8 data_st7701_8[] = { + 0xb1, 0x00, 0x0c, 0x13, 0x0d, 0x10, 0x06, 0x02, 0x08, 0x07, + 0x1f, 0x05, 0x12, 0x10, 0x27, 0x31, 0x1f +}; +static CVI_U8 data_st7701_9[] = { 0xff, 0x77, 0x01, 0x00, 0x00, 0x11 }; +static CVI_U8 data_st7701_10[] = { 0xb0, 0x70 }; +static CVI_U8 data_st7701_11[] = { 0xb1, 0x93 }; +static CVI_U8 data_st7701_12[] = { 0xb2, 0x87 }; +static CVI_U8 data_st7701_13[] = { 0xb3, 0x80 }; +static CVI_U8 data_st7701_14[] = { 0xb5, 0x49 }; +static CVI_U8 data_st7701_15[] = { 0xb7, 0x87 }; +static CVI_U8 data_st7701_16[] = { 0xb8, 0x21 }; +static CVI_U8 data_st7701_17[] = { 0xb9, 0x10, 0x1f }; +static CVI_U8 data_st7701_18[] = { 0xbb, 0x03 }; +static CVI_U8 data_st7701_19[] = { 0xc0, 0x89 }; +static CVI_U8 data_st7701_20[] = { 0xc1, 0x08 }; +static CVI_U8 data_st7701_21[] = { 0xc2, 0x08 }; +static CVI_U8 data_st7701_22[] = { 0xc8, 0xbe }; +static CVI_U8 data_st7701_23[] = { 0xd0, 0x88 }; +static CVI_U8 data_st7701_24[] = { + 0xe0, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0c +}; +static CVI_U8 data_st7701_25[] = { + 0xe1, 0x05, 0x8c, 0x07, 0x8c, 0x06, 0x8c, 0x08, 0x8c, 0x00, + 0x44, 0x44 +}; +static CVI_U8 data_st7701_26[] = { + 0xe2, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00 +}; +static CVI_U8 data_st7701_27[] = { 0xe3, 0x00, 0x00, 0x33, 0x33 }; +static CVI_U8 data_st7701_28[] = { 0xe4, 0x44, 0x44 }; +static CVI_U8 data_st7701_29[] = { + 0xe5, 0x0d, 0x3f, 0x0c, 0xa0, 0x0f, 0x41, 0x0c, 0xa0, 0x09, + 0x3b, 0x0c, 0xa0, 0x0b, 0x3d, 0x0c, 0xa0 +}; +static CVI_U8 data_st7701_30[] = { 0xe6, 0x00, 0x00, 0x33, 0x33 }; +static CVI_U8 data_st7701_31[] = { 0xe7, 0x44, 0x44 }; +static CVI_U8 data_st7701_32[] = { + 0xe8, 0x0e, 0x40, 0x0c, 0xa0, 0x10, 0x42, 0x0c, 0xa0, 0x0a, + 0x3c, 0x0c, 0xa0, 0x0c, 0x3e, 0x0c, 0xa0 +}; +static CVI_U8 data_st7701_33[] = { + 0xeb, 0x00, 0x01, 0xe4, 0xe4, 0x44, 0x00 +}; +static CVI_U8 data_st7701_34[] = { + 0xed, 0xf3, 0xc1, 0xba, 0x0f, 0x66, 0x77, 0x44, 0x55, 0x55, + 0x44, 0x77, 0x66, 0xf0, 0xab, 0x1c, 0x3f +}; +static CVI_U8 data_st7701_35[] = { + 0xef, 0x10, 0x0d, 0x04, 0x08, 0x3f, 0x1f +}; +static CVI_U8 data_st7701_36[] = { 0xff, 0x77, 0x01, 0x00, 0x00, 0x13 }; +static CVI_U8 data_st7701_37[] = { 0x11 }; +static CVI_U8 data_st7701_38[] = { 0x29 }; +static CVI_U8 data_st7701_39[] = { 0x36, 0x00 }; +static CVI_U8 data_st7701_40[] = { 0x35, 0x00 }; + +const struct dsc_instr dsi_init_cmds_st7701_480x800[] = { + {.delay = 0, .data_type = 0x39, .size = 6, .data = data_st7701_0 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_1 }, + {.delay = 0, .data_type = 0x39, .size = 6, .data = data_st7701_2 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_3 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_4 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_5 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_6 }, + {.delay = 0, .data_type = 0x39, .size = 17, .data = data_st7701_7 }, + {.delay = 0, .data_type = 0x39, .size = 17, .data = data_st7701_8 }, + {.delay = 0, .data_type = 0x39, .size = 6, .data = data_st7701_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_11 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_16 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_17 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_18 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_19 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_20 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_21 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_22 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_23 }, + {.delay = 0, .data_type = 0x39, .size = 7, .data = data_st7701_24 }, + {.delay = 0, .data_type = 0x39, .size = 12, .data = data_st7701_25 }, + {.delay = 0, .data_type = 0x39, .size = 13, .data = data_st7701_26 }, + {.delay = 0, .data_type = 0x39, .size = 5, .data = data_st7701_27 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_28 }, + {.delay = 0, .data_type = 0x39, .size = 17, .data = data_st7701_29 }, + {.delay = 0, .data_type = 0x39, .size = 5, .data = data_st7701_30 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_31 }, + {.delay = 0, .data_type = 0x39, .size = 17, .data = data_st7701_32 }, + {.delay = 0, .data_type = 0x39, .size = 7, .data = data_st7701_33 }, + {.delay = 0, .data_type = 0x39, .size = 17, .data = data_st7701_34 }, + {.delay = 0, .data_type = 0x39, .size = 7, .data = data_st7701_35 }, + {.delay = 0, .data_type = 0x39, .size = 6, .data = data_st7701_36 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_st7701_37 }, + {.delay = 20, .data_type = 0x05, .size = 1, .data = data_st7701_38 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_39 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_40 } +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_ST_7701_H_ diff --git a/middleware/v2/component/panel/cv181x/i80_st7789v.h b/middleware/v2/component/panel/cv181x/i80_st7789v.h new file mode 100644 index 000000000..3cd891c6e --- /dev/null +++ b/middleware/v2/component/panel/cv181x/i80_st7789v.h @@ -0,0 +1,94 @@ +#ifndef _I80_PARAM_ST7789V_H_ +#define _I80_PARAM_ST7789V_H_ + +#include + +#define COMMAND 0 +#define DATA 1 + +const VO_I80_CFG_S stI80Cfg = { + .lane_s = {.CS = 0, .RS = 1, .WR = 2, .RD = 3}, + .fmt = VO_I80_FORMAT_RGB565, + .cycle_time = 200, +}; + +const VO_I80_INSTR_S init_cmds[] = { + {.delay = 0, .data_type = COMMAND, .data = 0x11}, + {.delay = 0, .data_type = COMMAND, .data = 0x35}, + {.delay = 0, .data_type = DATA, .data = 0x00}, + {.delay = 0, .data_type = COMMAND, .data = 0x36}, + {.delay = 0, .data_type = DATA, .data = 0x00}, + {.delay = 0, .data_type = COMMAND, .data = 0x3A}, + {.delay = 0, .data_type = DATA, .data = 0x05}, + {.delay = 0, .data_type = COMMAND, .data = 0xB2}, + {.delay = 0, .data_type = DATA, .data = 0x0C}, + {.delay = 0, .data_type = DATA, .data = 0x0C}, + {.delay = 0, .data_type = DATA, .data = 0x00}, + {.delay = 0, .data_type = DATA, .data = 0x33}, + {.delay = 0, .data_type = DATA, .data = 0x33}, + {.delay = 0, .data_type = COMMAND, .data = 0xB7}, + {.delay = 0, .data_type = DATA, .data = 0x75}, + {.delay = 0, .data_type = COMMAND, .data = 0xBB}, + {.delay = 0, .data_type = DATA, .data = 0x19}, + {.delay = 0, .data_type = COMMAND, .data = 0xC0}, + {.delay = 0, .data_type = DATA, .data = 0x2C}, + {.delay = 0, .data_type = COMMAND, .data = 0xC2}, + {.delay = 0, .data_type = DATA, .data = 0x01}, + {.delay = 0, .data_type = COMMAND, .data = 0xC3}, + {.delay = 0, .data_type = DATA, .data = 0x0C}, + {.delay = 0, .data_type = COMMAND, .data = 0xC4}, + {.delay = 0, .data_type = DATA, .data = 0x20}, + {.delay = 0, .data_type = COMMAND, .data = 0xC6}, + {.delay = 0, .data_type = DATA, .data = 0x0F}, + {.delay = 0, .data_type = COMMAND, .data = 0xD0}, + {.delay = 0, .data_type = DATA, .data = 0xA4}, + {.delay = 0, .data_type = DATA, .data = 0xA1}, + {.delay = 0, .data_type = COMMAND, .data = 0xE0}, + {.delay = 0, .data_type = DATA, .data = 0xD0}, + {.delay = 0, .data_type = DATA, .data = 0x05}, + {.delay = 0, .data_type = DATA, .data = 0x0D}, + {.delay = 0, .data_type = DATA, .data = 0x13}, + {.delay = 0, .data_type = DATA, .data = 0x14}, + {.delay = 0, .data_type = DATA, .data = 0x2D}, + {.delay = 0, .data_type = DATA, .data = 0x3C}, + {.delay = 0, .data_type = DATA, .data = 0x52}, + {.delay = 0, .data_type = DATA, .data = 0x49}, + {.delay = 0, .data_type = DATA, .data = 0x13}, + {.delay = 0, .data_type = DATA, .data = 0x0B}, + {.delay = 0, .data_type = DATA, .data = 0x09}, + {.delay = 0, .data_type = DATA, .data = 0x1A}, + {.delay = 0, .data_type = DATA, .data = 0x1B}, + {.delay = 0, .data_type = COMMAND, .data = 0xE1}, + {.delay = 0, .data_type = DATA, .data = 0xD0}, + {.delay = 0, .data_type = DATA, .data = 0x05}, + {.delay = 0, .data_type = DATA, .data = 0x0C}, + {.delay = 0, .data_type = DATA, .data = 0x13}, + {.delay = 0, .data_type = DATA, .data = 0x14}, + {.delay = 0, .data_type = DATA, .data = 0x2F}, + {.delay = 0, .data_type = DATA, .data = 0x4C}, + {.delay = 0, .data_type = DATA, .data = 0x41}, + {.delay = 0, .data_type = DATA, .data = 0x4E}, + {.delay = 0, .data_type = DATA, .data = 0x2A}, + {.delay = 0, .data_type = DATA, .data = 0x1D}, + {.delay = 0, .data_type = DATA, .data = 0x1D}, + {.delay = 0, .data_type = DATA, .data = 0x1B}, + {.delay = 0, .data_type = DATA, .data = 0x1B}, + + {.delay = 0, .data_type = COMMAND, .data = 0x29}, + + {.delay = 0, .data_type = COMMAND, .data = 0x2A}, + {.delay = 0, .data_type = DATA, .data = 0x0 },//Xstart + {.delay = 0, .data_type = DATA, .data = 0x0 }, + {.delay = 0, .data_type = DATA, .data = 0x0 },//Xend + {.delay = 0, .data_type = DATA, .data = 0xEF}, + + {.delay = 0, .data_type = COMMAND, .data = 0x2B}, + {.delay = 0, .data_type = DATA, .data = 0x0 },//Ystart + {.delay = 0, .data_type = DATA, .data = 0x0 }, + {.delay = 0, .data_type = DATA, .data = 0x01},//Yend + {.delay = 0, .data_type = DATA, .data = 0x3F}, + + {.delay = 0, .data_type = COMMAND, .data = 0x2C}, +}; + +#endif // _I80_PARAM_ST7789V_H_ diff --git a/middleware/v2/ko/3rd/cvi_wiegand_gpio.ko b/middleware/v2/ko/3rd/cvi_wiegand_gpio.ko new file mode 100644 index 000000000..259f5f7e4 Binary files /dev/null and b/middleware/v2/ko/3rd/cvi_wiegand_gpio.ko differ diff --git a/middleware/v2/ko/cv180x_base.ko b/middleware/v2/ko/cv180x_base.ko new file mode 100644 index 000000000..4cb9e83a7 Binary files /dev/null and b/middleware/v2/ko/cv180x_base.ko differ diff --git a/middleware/v2/ko/cv180x_clock_cooling.ko b/middleware/v2/ko/cv180x_clock_cooling.ko new file mode 100644 index 000000000..95874f337 Binary files /dev/null and b/middleware/v2/ko/cv180x_clock_cooling.ko differ diff --git a/middleware/v2/ko/cv180x_dwa.ko b/middleware/v2/ko/cv180x_dwa.ko new file mode 100644 index 000000000..2a6ad3d0f Binary files /dev/null and b/middleware/v2/ko/cv180x_dwa.ko differ diff --git a/middleware/v2/ko/cv180x_fast_image.ko b/middleware/v2/ko/cv180x_fast_image.ko new file mode 100644 index 000000000..b4236fd52 Binary files /dev/null and b/middleware/v2/ko/cv180x_fast_image.ko differ diff --git a/middleware/v2/ko/cv180x_jpeg.ko b/middleware/v2/ko/cv180x_jpeg.ko new file mode 100644 index 000000000..f9aeece5d Binary files /dev/null and b/middleware/v2/ko/cv180x_jpeg.ko differ diff --git a/middleware/v2/ko/cv180x_mon.ko b/middleware/v2/ko/cv180x_mon.ko new file mode 100644 index 000000000..34c3b9d8d Binary files /dev/null and b/middleware/v2/ko/cv180x_mon.ko differ diff --git a/middleware/v2/ko/cv180x_pwm.ko b/middleware/v2/ko/cv180x_pwm.ko new file mode 100644 index 000000000..5820e9769 Binary files /dev/null and b/middleware/v2/ko/cv180x_pwm.ko differ diff --git a/middleware/v2/ko/cv180x_rgn.ko b/middleware/v2/ko/cv180x_rgn.ko new file mode 100644 index 000000000..39dff205c Binary files /dev/null and b/middleware/v2/ko/cv180x_rgn.ko differ diff --git a/middleware/v2/ko/cv180x_rtc.ko b/middleware/v2/ko/cv180x_rtc.ko new file mode 100644 index 000000000..9a114fd41 Binary files /dev/null and b/middleware/v2/ko/cv180x_rtc.ko differ diff --git a/middleware/v2/ko/cv180x_rtos_cmdqu.ko b/middleware/v2/ko/cv180x_rtos_cmdqu.ko new file mode 100644 index 000000000..feebe94cd Binary files /dev/null and b/middleware/v2/ko/cv180x_rtos_cmdqu.ko differ diff --git a/middleware/v2/ko/cv180x_saradc.ko b/middleware/v2/ko/cv180x_saradc.ko new file mode 100644 index 000000000..efedfed1d Binary files /dev/null and b/middleware/v2/ko/cv180x_saradc.ko differ diff --git a/middleware/v2/ko/cv180x_sys.ko b/middleware/v2/ko/cv180x_sys.ko new file mode 100644 index 000000000..fd714c4a6 Binary files /dev/null and b/middleware/v2/ko/cv180x_sys.ko differ diff --git a/middleware/v2/ko/cv180x_tpu.ko b/middleware/v2/ko/cv180x_tpu.ko new file mode 100644 index 000000000..9cf6b57c3 Binary files /dev/null and b/middleware/v2/ko/cv180x_tpu.ko differ diff --git a/middleware/v2/ko/cv180x_vcodec.ko b/middleware/v2/ko/cv180x_vcodec.ko new file mode 100644 index 000000000..bbd66660f Binary files /dev/null and b/middleware/v2/ko/cv180x_vcodec.ko differ diff --git a/middleware/v2/ko/cv180x_vi.ko b/middleware/v2/ko/cv180x_vi.ko new file mode 100644 index 000000000..fb8ba79d7 Binary files /dev/null and b/middleware/v2/ko/cv180x_vi.ko differ diff --git a/middleware/v2/ko/cv180x_vpss.ko b/middleware/v2/ko/cv180x_vpss.ko new file mode 100644 index 000000000..e17517a93 Binary files /dev/null and b/middleware/v2/ko/cv180x_vpss.ko differ diff --git a/middleware/v2/ko/cv180x_wdt.ko b/middleware/v2/ko/cv180x_wdt.ko new file mode 100644 index 000000000..7789152c5 Binary files /dev/null and b/middleware/v2/ko/cv180x_wdt.ko differ diff --git a/middleware/v2/ko/cvi_mipi_rx.ko b/middleware/v2/ko/cvi_mipi_rx.ko new file mode 100644 index 000000000..e221e59b2 Binary files /dev/null and b/middleware/v2/ko/cvi_mipi_rx.ko differ diff --git a/middleware/v2/ko/cvi_vc_driver.ko b/middleware/v2/ko/cvi_vc_driver.ko new file mode 100644 index 000000000..bea5358ff Binary files /dev/null and b/middleware/v2/ko/cvi_vc_driver.ko differ diff --git a/middleware/v2/ko/cvi_wiegand.ko b/middleware/v2/ko/cvi_wiegand.ko new file mode 100644 index 000000000..2fb555043 Binary files /dev/null and b/middleware/v2/ko/cvi_wiegand.ko differ diff --git a/middleware/v2/ko/cviaudio_core.ko b/middleware/v2/ko/cviaudio_core.ko new file mode 100644 index 000000000..98ca654b4 Binary files /dev/null and b/middleware/v2/ko/cviaudio_core.ko differ diff --git a/middleware/v2/ko/snsr_i2c.ko b/middleware/v2/ko/snsr_i2c.ko new file mode 100644 index 000000000..a19b070b2 Binary files /dev/null and b/middleware/v2/ko/snsr_i2c.ko differ diff --git a/middleware/v2/ko_shrink/3rd/cvi_wiegand_gpio.ko b/middleware/v2/ko_shrink/3rd/cvi_wiegand_gpio.ko new file mode 100644 index 000000000..a06f3cf26 Binary files /dev/null and b/middleware/v2/ko_shrink/3rd/cvi_wiegand_gpio.ko differ diff --git a/middleware/v2/ko_shrink/cv180x_base.ko b/middleware/v2/ko_shrink/cv180x_base.ko new file mode 100644 index 000000000..da4e70683 Binary files /dev/null and b/middleware/v2/ko_shrink/cv180x_base.ko differ diff --git a/middleware/v2/ko_shrink/cv180x_clock_cooling.ko b/middleware/v2/ko_shrink/cv180x_clock_cooling.ko new file mode 100644 index 000000000..46399eaea Binary files /dev/null and b/middleware/v2/ko_shrink/cv180x_clock_cooling.ko differ diff --git a/middleware/v2/ko_shrink/cv180x_dwa.ko b/middleware/v2/ko_shrink/cv180x_dwa.ko new file mode 100644 index 000000000..fb8bce50d Binary files /dev/null and b/middleware/v2/ko_shrink/cv180x_dwa.ko differ diff --git a/middleware/v2/ko_shrink/cv180x_fast_image.ko b/middleware/v2/ko_shrink/cv180x_fast_image.ko new file mode 100644 index 000000000..9d9f140b0 Binary files /dev/null and b/middleware/v2/ko_shrink/cv180x_fast_image.ko differ diff --git a/middleware/v2/ko_shrink/cv180x_jpeg.ko b/middleware/v2/ko_shrink/cv180x_jpeg.ko new file mode 100644 index 000000000..f9aeece5d Binary files /dev/null and b/middleware/v2/ko_shrink/cv180x_jpeg.ko differ diff --git a/middleware/v2/ko_shrink/cv180x_mon.ko b/middleware/v2/ko_shrink/cv180x_mon.ko new file mode 100644 index 000000000..32d2c5299 Binary files /dev/null and b/middleware/v2/ko_shrink/cv180x_mon.ko differ diff --git a/middleware/v2/ko_shrink/cv180x_pwm.ko b/middleware/v2/ko_shrink/cv180x_pwm.ko new file mode 100644 index 000000000..2b9451aee Binary files /dev/null and b/middleware/v2/ko_shrink/cv180x_pwm.ko differ diff --git a/middleware/v2/ko_shrink/cv180x_rgn.ko b/middleware/v2/ko_shrink/cv180x_rgn.ko new file mode 100644 index 000000000..33284b611 Binary files /dev/null and b/middleware/v2/ko_shrink/cv180x_rgn.ko differ diff --git a/middleware/v2/ko_shrink/cv180x_rtc.ko b/middleware/v2/ko_shrink/cv180x_rtc.ko new file mode 100644 index 000000000..9a114fd41 Binary files /dev/null and b/middleware/v2/ko_shrink/cv180x_rtc.ko differ diff --git a/middleware/v2/ko_shrink/cv180x_rtos_cmdqu.ko b/middleware/v2/ko_shrink/cv180x_rtos_cmdqu.ko new file mode 100644 index 000000000..826647d52 Binary files /dev/null and b/middleware/v2/ko_shrink/cv180x_rtos_cmdqu.ko differ diff --git a/middleware/v2/ko_shrink/cv180x_saradc.ko b/middleware/v2/ko_shrink/cv180x_saradc.ko new file mode 100644 index 000000000..dd9d89633 Binary files /dev/null and b/middleware/v2/ko_shrink/cv180x_saradc.ko differ diff --git a/middleware/v2/ko_shrink/cv180x_sys.ko b/middleware/v2/ko_shrink/cv180x_sys.ko new file mode 100644 index 000000000..348583bf9 Binary files /dev/null and b/middleware/v2/ko_shrink/cv180x_sys.ko differ diff --git a/middleware/v2/ko_shrink/cv180x_tpu.ko b/middleware/v2/ko_shrink/cv180x_tpu.ko new file mode 100644 index 000000000..3a96eca0a Binary files /dev/null and b/middleware/v2/ko_shrink/cv180x_tpu.ko differ diff --git a/middleware/v2/ko_shrink/cv180x_vcodec.ko b/middleware/v2/ko_shrink/cv180x_vcodec.ko new file mode 100644 index 000000000..71f0ca7df Binary files /dev/null and b/middleware/v2/ko_shrink/cv180x_vcodec.ko differ diff --git a/middleware/v2/ko_shrink/cv180x_vi.ko b/middleware/v2/ko_shrink/cv180x_vi.ko new file mode 100644 index 000000000..357c2728e Binary files /dev/null and b/middleware/v2/ko_shrink/cv180x_vi.ko differ diff --git a/middleware/v2/ko_shrink/cv180x_vpss.ko b/middleware/v2/ko_shrink/cv180x_vpss.ko new file mode 100644 index 000000000..dcdeb3554 Binary files /dev/null and b/middleware/v2/ko_shrink/cv180x_vpss.ko differ diff --git a/middleware/v2/ko_shrink/cv180x_wdt.ko b/middleware/v2/ko_shrink/cv180x_wdt.ko new file mode 100644 index 000000000..7789152c5 Binary files /dev/null and b/middleware/v2/ko_shrink/cv180x_wdt.ko differ diff --git a/middleware/v2/ko_shrink/cvi_mipi_rx.ko b/middleware/v2/ko_shrink/cvi_mipi_rx.ko new file mode 100644 index 000000000..cd3792687 Binary files /dev/null and b/middleware/v2/ko_shrink/cvi_mipi_rx.ko differ diff --git a/middleware/v2/ko_shrink/cvi_vc_driver.ko b/middleware/v2/ko_shrink/cvi_vc_driver.ko new file mode 100644 index 000000000..15ec4195a Binary files /dev/null and b/middleware/v2/ko_shrink/cvi_vc_driver.ko differ diff --git a/middleware/v2/ko_shrink/cvi_wiegand.ko b/middleware/v2/ko_shrink/cvi_wiegand.ko new file mode 100644 index 000000000..d596b6bd6 Binary files /dev/null and b/middleware/v2/ko_shrink/cvi_wiegand.ko differ diff --git a/middleware/v2/ko_shrink/cviaudio_core.ko b/middleware/v2/ko_shrink/cviaudio_core.ko new file mode 100644 index 000000000..98ca654b4 Binary files /dev/null and b/middleware/v2/ko_shrink/cviaudio_core.ko differ diff --git a/middleware/v2/ko_shrink/snsr_i2c.ko b/middleware/v2/ko_shrink/snsr_i2c.ko new file mode 100644 index 000000000..43caaa8ac Binary files /dev/null and b/middleware/v2/ko_shrink/snsr_i2c.ko differ diff --git a/middleware/v2/lib_glibc_riscv64/3rd/cli b/middleware/v2/lib_glibc_riscv64/3rd/cli new file mode 100644 index 000000000..1ecf9591b Binary files /dev/null and b/middleware/v2/lib_glibc_riscv64/3rd/cli differ diff --git a/middleware/v2/lib_glibc_riscv64/libcvi_json-c.so.5 b/middleware/v2/lib_glibc_riscv64/libcvi_json-c.so.5 new file mode 120000 index 000000000..4342b3293 --- /dev/null +++ b/middleware/v2/lib_glibc_riscv64/libcvi_json-c.so.5 @@ -0,0 +1 @@ +libcvi_json-c.so.5.1.0 \ No newline at end of file diff --git a/middleware/v2/lib_glibc_riscv64/libcvi_json-c.so.5.1.0 b/middleware/v2/lib_glibc_riscv64/libcvi_json-c.so.5.1.0 new file mode 100644 index 000000000..cb2aff4e2 Binary files /dev/null and b/middleware/v2/lib_glibc_riscv64/libcvi_json-c.so.5.1.0 differ diff --git a/middleware/v2/lib_glibc_riscv64/libjson-c.so.5 b/middleware/v2/lib_glibc_riscv64/libjson-c.so.5 new file mode 120000 index 000000000..20aa3a5b7 --- /dev/null +++ b/middleware/v2/lib_glibc_riscv64/libjson-c.so.5 @@ -0,0 +1 @@ +libjson-c.so.5.1.0 \ No newline at end of file diff --git a/middleware/v2/lib_glibc_riscv64/libjson-c.so.5.1.0 b/middleware/v2/lib_glibc_riscv64/libjson-c.so.5.1.0 new file mode 100644 index 000000000..a4b8229f0 Binary files /dev/null and b/middleware/v2/lib_glibc_riscv64/libjson-c.so.5.1.0 differ diff --git a/middleware/v2/lib_glibc_riscv64/libssl.so.1.1 b/middleware/v2/lib_glibc_riscv64/libssl.so.1.1 new file mode 100755 index 000000000..bf552d010 Binary files /dev/null and b/middleware/v2/lib_glibc_riscv64/libssl.so.1.1 differ diff --git a/middleware/v2/lib_glibc_riscv64/libz.so.1 b/middleware/v2/lib_glibc_riscv64/libz.so.1 new file mode 120000 index 000000000..95e0ebd56 --- /dev/null +++ b/middleware/v2/lib_glibc_riscv64/libz.so.1 @@ -0,0 +1 @@ +libz.so.1.2.11 \ No newline at end of file diff --git a/middleware/v2/lib_glibc_riscv64/libz.so.1.2.11 b/middleware/v2/lib_glibc_riscv64/libz.so.1.2.11 new file mode 100644 index 000000000..045d89dda Binary files /dev/null and b/middleware/v2/lib_glibc_riscv64/libz.so.1.2.11 differ diff --git a/middleware/v2/lib_musl_riscv64/3rd/cli b/middleware/v2/lib_musl_riscv64/3rd/cli new file mode 100644 index 000000000..741454a15 Binary files /dev/null and b/middleware/v2/lib_musl_riscv64/3rd/cli differ diff --git a/middleware/v2/lib_musl_riscv64/libz.so.1 b/middleware/v2/lib_musl_riscv64/libz.so.1 new file mode 120000 index 000000000..95e0ebd56 --- /dev/null +++ b/middleware/v2/lib_musl_riscv64/libz.so.1 @@ -0,0 +1 @@ +libz.so.1.2.11 \ No newline at end of file diff --git a/middleware/v2/lib_musl_riscv64/libz.so.1.2.11 b/middleware/v2/lib_musl_riscv64/libz.so.1.2.11 new file mode 100644 index 000000000..332537ca5 Binary files /dev/null and b/middleware/v2/lib_musl_riscv64/libz.so.1.2.11 differ diff --git a/middleware/v2/pkgconfig/cvi_audio.pc b/middleware/v2/pkgconfig/cvi_audio.pc new file mode 100644 index 000000000..38ee45990 --- /dev/null +++ b/middleware/v2/pkgconfig/cvi_audio.pc @@ -0,0 +1,10 @@ +mw_dir=middleware +includedir=${mw_dir}/include +libdir=${mw_dir}/lib +3rd_lib_dir=${libdir}/3rd + +Name: CVITEK System lib +Description: AUDIO libs +Version: 2.0 +Cflags: -I${includedir}/ +Libs: -L${libdir} -ldl -lcvi_audio -lcvi_vqe -lcvi_VoiceEngine -lcvi_RES1 -L${3rd_lib_dir} -ltinyalsa -lrt -lpthread -lcvi_ssp -lcli diff --git a/middleware/v2/pkgconfig/cvi_common.pc b/middleware/v2/pkgconfig/cvi_common.pc new file mode 100644 index 000000000..554d45d26 --- /dev/null +++ b/middleware/v2/pkgconfig/cvi_common.pc @@ -0,0 +1,9 @@ +mw_dir=middleware +includedir=${mw_dir}/include +libdir=${mw_dir}/lib + +Name: CVITEK System lib +Description: SYS / VPU / ISP / VENC / BIN libs +Version: 2.0 +Cflags: -I${includedir} -I${includedir}/isp/cv181x +Libs: -L${libdir} -lsys -lvpu -lvenc -lcvi_bin -lcvi_bin_isp -lisp -lisp_algo -lae -laf -lawb -lsns_full -latomic diff --git a/middleware/v2/pkgconfig/cvi_ive.pc b/middleware/v2/pkgconfig/cvi_ive.pc new file mode 100644 index 000000000..610b4e53a --- /dev/null +++ b/middleware/v2/pkgconfig/cvi_ive.pc @@ -0,0 +1,9 @@ +mw_dir=middleware +includedir=${mw_dir}/include +libdir=${mw_dir}/lib + +Name: CVITEK System lib +Description: IVE libs +Version: 2.0 +Cflags: -I${includedir}/ +Libs: -L${libdir} -lsys -lcvi_ive -latomic diff --git a/middleware/v2/pkgconfig/cvi_misc.pc b/middleware/v2/pkgconfig/cvi_misc.pc new file mode 100644 index 000000000..508836c77 --- /dev/null +++ b/middleware/v2/pkgconfig/cvi_misc.pc @@ -0,0 +1,10 @@ +mw_dir=middleware +includedir=${mw_dir}/sample +libdir=${mw_dir}/lib + +Name: CVITEK System lib +Description: MISC libs +Version: 2.0 +Cflags: -I${includedir}/common +Requires: cvi_common +Libs: -L${libdir} -lmisc diff --git a/middleware/v2/pkgconfig/cvi_sample.pc b/middleware/v2/pkgconfig/cvi_sample.pc new file mode 100644 index 000000000..c27e2b16f --- /dev/null +++ b/middleware/v2/pkgconfig/cvi_sample.pc @@ -0,0 +1,10 @@ +mw_dir=middleware +includedir=${mw_dir}/sample +libdir=${mw_dir}/lib + +Name: CVITEK System lib +Description: SAMPLE libs +Version: 2.0 +Cflags: -I${includedir}/common -I${mw_dir}/3rdparty/inih +Requires: cvi_common cvi_audio cvi_vdec cvi_misc +Libs: -L${libdir} -lsample -L${libdir}/3rd -lini diff --git a/middleware/v2/pkgconfig/cvi_vdec.pc b/middleware/v2/pkgconfig/cvi_vdec.pc new file mode 100644 index 000000000..9759b2611 --- /dev/null +++ b/middleware/v2/pkgconfig/cvi_vdec.pc @@ -0,0 +1,11 @@ +mw_dir=middleware +includedir=${mw_dir}/include +libdir=${mw_dir}/lib +3rd_lib_dir=${libdir}/3rd + +Name: CVITEK System lib +Description: VDEC libs +Version: 2.0 +Cflags: -I${includedir}/ +Libs: -L${libdir} -lsys -lvdec + diff --git a/middleware/v2/sample/Makefile b/middleware/v2/sample/Makefile new file mode 100644 index 000000000..4e8fa983e --- /dev/null +++ b/middleware/v2/sample/Makefile @@ -0,0 +1,14 @@ + +all: + @echo "##############################" + @echo "# #" + @echo "# Compiling 'samples'... #" + @echo "# #" + @echo "##############################" + @cd common; make all || exit 1; cd ../; + @for x in `find -L ./ -maxdepth 2 -mindepth 2 -name "Makefile" `; \ + do cd `dirname $$x`; if [ $$? ]; then $(MAKE) all || exit 1; cd ../; fi; done + +clean: + @for x in `find -L ./ -maxdepth 2 -mindepth 2 -name "Makefile" `; \ + do cd `dirname $$x`; if [ $$? ]; then $(MAKE) clean; cd ../; fi; done diff --git a/middleware/v2/sample/audio/Makefile b/middleware/v2/sample/audio/Makefile new file mode 100644 index 000000000..a647a9b5f --- /dev/null +++ b/middleware/v2/sample/audio/Makefile @@ -0,0 +1,239 @@ +SHELL = /bin/bash +STATIC = 0 +ifeq ($(PARAM_FILE), ) +ifeq ($(MW_VER), ) +PARAM_FILE:=../../Makefile.param +include $(PARAM_FILE) +else +PARAM_FILE:=../../../$(shell echo $(MW_VER))/Makefile.param +include $(PARAM_FILE) +endif +endif + +include ../sample.mk + +SDIR = $(PWD) +3PARTY_INCLUDE = include/include +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(COMM_INC) -I$(3PARTY_INCLUDE) -Iaac_sample +INCS += -I$(MW_INC)/../3rdparty/libmad/include +INCS += -I$(MW_INC)/../3rdparty/lame/include +ifeq ($(CVIARCH), $(filter $(CVIARCH), CV181X CV180X)) +INCS += -I$(PWD)/include -I$(KERNEL_INC) +ifneq ($(CONFIG_ENABLE_SDK_ASAN), y) +USE_CVIAUDIO_STATIC = no +endif +else +INCS += -I$(PWD)/include +USE_CVIAUDIO_STATIC = no +endif + +ifeq ($(USE_CVIAUDIO_STATIC), yes) +SRCS = $(filter-out $(SDIR)/cvi_audio_dl_adp.c, $(wildcard $(SDIR)/*.c)) +endif +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) + +USE_ION_MEM = no +USE_ALSA = no +USE_TINYALSA = yes +USE_NE10 = no +USE_SYSTRACE = no +USE_ALGO = yes +USE_CVI_AEC = yes +SUPPORT_EXTERNAL_AAC = yes +USE_SYS_GLOBAL_LOG = no +MULTI_PROCESS_SUPPORT_AUDIO = no +USE_NEXT_SSP_DUAL = yes +USE_SONIC_LIB = no + +DEFINES = -DCHIP_CV1835 +DEFINES += -DCVI_MODIFIED +DEFINES += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +DEFINES += -DUSE_ALSA +DEFINES += -DUSE_ALGO_SOURCE +ifeq ($(USE_NE10), yes) +DEFINES += -DUSE_NE10_FFT +endif +ifeq ($(USE_ION_MEM), yes) +DEFINES += -DION_MEM +endif +ifeq ($(USE_SYS_GLOBAL_LOG), yes) +DEFINES += -DAUDIO_PRINT_WITH_GLOBAL_COMM_LOG +endif +ifeq ($(USE_CVI_AEC), no) +DEFINES += -DEXTERNAL_AEC +else +#DEFINES += -DUSE_CVI_AEC +endif +ifeq ($(SUPPORT_EXTERNAL_AAC), yes) +DEFINES += -DSUPPORT_EXTERNAL_AAC +endif + +ifeq ($(USE_NEXT_SSP_DUAL), yes) +DEFINES += -DNEXT_SSP_ALGO +endif + +ifeq ($(USE_CVIAUDIO_STATIC), yes) +DEFINES += -DCVIAUDIO_STATIC +STATIC_FLAG = -static +else +STATIC_FALG = +endif + +ifeq ($(USE_SONIC_LIB), yes) +DEFINES += -DUSE_SONIC_LIB +endif + +ifeq ($(CVIARCH), $(filter $(CVIARCH), CV181X CV180X)) +DEFINES += -DAUD_SUPPORT_KERNEL_MODE +endif + + +TEST_INCLUDES = +TEST_INCLUDES += $(INCS) +ifeq ($(USE_ALSA), yes) +INCS += -Iinclude/alsa +endif +ifeq ($(USE_TINYALSA), yes) +INCS += -Iinclude/tinyalsa +endif +ifeq ($(SUPPORT_EXTERNAL_AAC), yes) +TEST_INCLUDES += -I ./aac_sample +endif + +INCS += -I ./include/ + +AEC_TEST_LDLIBS += -lcvi_vqe +ifeq ($(CVIARCH), $(filter $(CVIARCH), CV181X CV180X)) +AEC_TEST_LDLIBS += -lsys +endif + +MP3_PLAYER_OBJ = ./cvi_mp3_player/cvi_mp3_player.o +TEST_OBJ = cvi_sample_audio.o cvi_audio_parse_param.o +ifeq ($(USE_CVIAUDIO_STATIC), no) +TEST_OBJ += cvi_audio_dl_adp.o +endif +TEST_OBJ_KER_MODE = cvi_sample_audio_rtos.o + +LDLIBS = +LDLIBS += -lcvi_audio +LDLIBS += -lcvi_vqe +LDLIBS += -lcvi_VoiceEngine +LDLIBS += -lcvi_RES1 +LDLIBS += -lcvi_ssp + +ifeq ($(USE_CVIAUDIO_STATIC), yes) +LDLIBS += -lcvi_ssp +endif + +ifeq ($(USE_ALSA), yes) +LDLIBS += -lasound +endif +ifeq ($(USE_TINYALSA), yes) +LDLIBS += -ltinyalsa +endif +ifeq ($(USE_SYS_GLOBAL_LOG), yes) +LDLIBS += -lvpu -lsys +endif + +ifeq ($(SUPPORT_EXTERNAL_AAC), yes) +TEST_OBJ += ./aac_sample/cvi_audio_aac_adp.o +LDLIBS += -laacdec2 +LDLIBS += -laacsbrdec2 +LDLIBS += -laacenc2 +LDLIBS += -laaccomm2 +LDLIBS += -laacsbrenc2 +endif +LDLIBS += -pthread +ifeq ($(CVIARCH), $(filter $(CVIARCH), CV181X CV180X)) +LDLIBS += -lsys +endif + +LDLIBS_WO_AAC = -lsys -latomic -lcvi_audio -lcvi_vqe -lcvi_VoiceEngine -lcvi_RES1 -ltinyalsa -lm -lpthread -ldl + +EXTRA_CFLAGS = -fPIC $(OPT_LEVEL) -Wno-implicit-function-declaration -I. $(INCS) $(DEFINES) +EXTRA_LDFLAGS = $(LDLIBS) -lm -lpthread -ldl + +MP3_EXTRA_LDFLAGS = -lcvi_mp3 -lmad -lcvi_audio -lm -lpthread -ldl -lcvi_VoiceEngine -lcvi_vqe -ltinyalsa -lcvi_RES1 + +EXTRA_CFLAGS += -DCLI_DEBUG_SUPPORT +EXTRA_LDFLAGS += -lcli + +ifeq ($(MULTI_PROCESS_SUPPORT_AUDIO), yes) +DEFINES += -DRPC_MULTI_PROCESS +DEFINES += -DRPC_MULTI_PROCESS_AUDIO +DEFINES += -DCVIAUDIO_STATIC +EXTRA_LDFLAGS += -lnanomsg +endif + +ifeq ($(SAMPLE_STATIC),1) +#softlink so lib will not be enough +#need to link all the audio related .a file +AEC_TEST_LDLIBS = $(LDLIBS) +else ifeq ($(USE_CVIAUDIO_STATIC), yes) +AEC_TEST_LDLIBS = $(LDLIBS) +endif + +AUDIO_ELFFLAGS := $(ELFFLAGS) +ELFFLAGS = $(filter-out -static, $(AUDIO_ELFFLAGS)) + +.PHONY : clean all + + +ifeq ($(MULTI_PROCESS_SUPPORT_AUDIO), yes) +ifeq ($(CONFIG_ENABLE_SDK_ASAN), y) +all : sample_audio check_and_leave sample_audio_asan +else +all : sample_audio check_and_leave sample_multi_process +endif +else +all : sample_audio check_and_leave +endif + + +%.o : %.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -o $@ -c $< + @echo [$(notdir $(CC))] $(notdir $@) + +sample_audio: $(TEST_OBJ) + @$(CXX) -o $@ $(TEST_OBJ) $(ELFFLAGS) $(STATIC_FLAG) $(EXTRA_LDFLAGS) + @echo -e $(BLUE)[LINK]$(END)[$(notdir $(CXX))] $(notdir $@) + +sample_audio_asan: $(TEST_OBJ) + @$(CXX) -o $@ $(TEST_OBJ) $(ELFFLAGS) $(EXTRA_LDFLAGS_WITH_ASAN) $(EXTRA_LDFLAGS) + @echo -e $(BLUE)[LINK]$(END)[$(notdir $(CXX))] $(notdir $@) + +cvi_mp3player: $(MP3_PLAYER_OBJ) + @$(CXX) -o $@ $(MP3_PLAYER_OBJ) $(ELFFLAGS) $(EXTRA_LDFLAGS) $(MP3_EXTRA_LDFLAGS) + @echo -e $(BLUE)[LINK]$(END)[$(notdir $(CXX))] $(notdir $@) + @cp cvi_mp3player sample_mp3player + +sample_audio_rtos: $(TEST_OBJ_KER_MODE) + $(CXX) -o $@ $(TEST_OBJ_KER_MODE) $(ELFFLAGS) -static $(LDLIBS_WO_AAC) + @echo -e $(BLUE)[LINK]$(END)[$(notdir $(CXX))] $(notdir $@) + +check_and_leave: + @echo "audio check and leave..remove unnecessary libs" + @rm -rf $(MW_PATH)/lib/3rd/libmad* + @rm -rf $(MW_PATH)/lib/3rd/libmp3lame* + +sample_multi_process: + cd ./multiprocess_case/down_example; make clean;make + cd ./multiprocess_case/up_example; make clean;make + +clean: + @echo "sample/audio/clean in" $(MW_PATH) + @rm -f $(OBJS) $(DEPS) $(TEST_OBJ) $(MP3_PLAYER_OBJ) + @rm -rf sample_audio* + @rm -rf *.o + @rm -rf cvi_mp3player + @rm -rf sample_mp3* + @rm -rf ./cvi_mp3_player/*.d + @rm -rf cvi_mp3recorder + @rm -rf ssp_NotchTest* + @rm -rf $(MW_PATH)/lib/3rd/libmad* + @rm -rf $(MW_PATH)/lib/3rd/libmp3lame* + @rm -rf $(MW_PATH)/lib/3rd/libcvi_mp3* + +-include $(DEPS) diff --git a/middleware/v2/sample/audio/aac_sample/Makefile b/middleware/v2/sample/audio/aac_sample/Makefile new file mode 100644 index 000000000..a04f8b5b0 --- /dev/null +++ b/middleware/v2/sample/audio/aac_sample/Makefile @@ -0,0 +1,350 @@ +.PHONY: CREATE_DIR + +#SDK_VER ?= uclibc +#SDK_VER ?= 64bit +#SDK_VER ?= musl_riscv64 +## GCC COMPILER ## +##TOOLPATH=~/master_repo3/host-tools/gcc/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin +#TOOLPATH=../../../../host-tools/gcc/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin +#CROSS_COMPILE=$(TOOLPATH)/aarch64-linux-gnu- +#TOOLPATH=../../../../host-tools/gcc/arm-cvitek-linux-uclibcgnueabihf/bin +#CROSS_COMPILE=$(TOOLPATH)/arm-cvitek-linux-uclibcgnueabihf- + +# KERNEL_INC := $(KERNEL_PATH)/build/$(PROJECT_FULLNAME)/riscv/usr/include +# TOOLPATH=../../../../host-tools/gcc/riscv64-linux-musl-x86_64/bin +# CROSS_COMPILE=$(TOOLPATH)/riscv64-unknown-linux-musl- +# CC = $(CROSS_COMPILE)gcc +# CXX = $(CROSS_COMPILE)g++ +# AR = $(CROSS_COMPILE)ar +# LD = $(CROSS_COMPILE)ld +# STRIP = $(CROSS_COMPILE)strip +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) +ifeq ($(MW_VER), ) +PARAM_FILE:=../../../Makefile.param +include $(PARAM_FILE) +else +PARAM_FILE:=../../../../$(shell echo $(MW_VER))/Makefile.param +include $(PARAM_FILE) +endif +endif + + +FDK_AAC_DIR=./fdkaac +CUR = $(PWD) + +#aac common -------------------------------------------start +AACCOMM_SRC = +AACCOMM_SRC += $(wildcard $(PWD)/fdkaac/libSYS/src/*.cpp) +AACCOMM_SRC += $(wildcard $(PWD)/fdkaac/libPCMutils/src/*.cpp) +AACCOMM_SRC += $(wildcard $(PWD)/fdkaac/libFDK/src/*.cpp) + +AACCOMM_INCS = +AACCOMM_INCS += -I ./fdkaac/libFDK/include/ +AACCOMM_INCS += -I ./fdkaac/libSYS/include/ +AACCOMM_INCS += -I ./fdkaac/libPCMutils/include/ +AACCOMM_INCS += -I $(KERNEL_INC) +OBJS_COMM = $(AACCOMM_SRC:.cpp=.o) +#aac encoder -------------------------------------------end + +#aac sbr encoder -------------------------------------------start +AACSBRENC_SRC = +AACSBRENC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libSBRenc/src/*.cpp) +AACSBRENC_SRC += $(AACSBRENC_SRC_EXTRA) + +OBJS_SBRENC = $(AACSBRENC_SRC:.cpp=.o) +#aac sbr encoder -------------------------------------------end + +#sbr decoder -------------------------------------------start +AACSBRDEC_SRC = +AACSBRDEC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libSBRdec/src/*.cpp) +AACSBRDEC_SRC += $(AACSBRDEC_SRC_EXTRA) +OBJS_SBRDEC = $(AACSBRDEC_SRC:.cpp=.o) +#sbr decoder -------------------------------------------end + +#aac encoder -------------------------------------------start +SYS_SRC = \ + libSYS/src/genericStds.cpp \ + libSYS/src/syslib_channelMapDescr.cpp + +AACENC_SRC = $(wildcard $(PWD)/fdkaac/libAACenc/src/*.cpp) +AACENC_SRC_EXTRA = $(wildcard $(PWD)/fdkaac/libSACenc/src/*.cpp) +#AACENC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libSBRenc/src/*.cpp) +AACENC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libMpegTPEnc/src/*.cpp) +##AACENC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libSYS/src/*.cpp) +##AACENC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libPCMutils/src/*.cpp) +##AACENC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libFDK/src/*.cpp) + +AACENC_SRC += $(AACENC_SRC_EXTRA) +AACENC_SRC += ./aacenc_interface.cpp + +AACENC_INCS = +AACENC_INCS += -I ./fdkaac/libFDK/include/ +AACENC_INCS += -I ./fdkaac/libSYS/include/ +AACENC_INCS += -I ./fdkaac/libMpegTPEnc/include/ +AACENC_INCS += -I ./fdkaac/libSBRenc/include/ +AACENC_INCS += -I ./fdkaac/libAACenc/include/ +AACENC_INCS += -I ./fdkaac/libSACenc/include/ +AACENC_INCS += -I ./fdkaac/libPCMutils/include/ +AACENC_INCS += -I $(KERNEL_INC) +OBJS_ENC = $(AACENC_SRC:.cpp=.o) +#aac encoder -------------------------------------------end + +#aac decoder -------------------------------------------start +AACDEC_SRC = $(wildcard $(PWD)/fdkaac/libAACdec/src/*.cpp) +##AACDEC_SRC_EXTRA = $(wildcard $(PWD)/fdkaac/libFDK/src/*.cpp) +##AACDEC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libSYS/src/*.cpp) +AACDEC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libArithCoding/src/*.cpp) +AACDEC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libMpegTPDec/src/*.cpp) +#AACDEC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libSBRdec/src/*.cpp) +##AACDEC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libPCMutils/src/*.cpp) +AACDEC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libDRCdec/src/*.cpp) +AACDEC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libSACdec/src/*.cpp) + +AACDEC_SRC += $(AACDEC_SRC_EXTRA) +AACDEC_SRC += ./aacdec_interface.cpp + +AACDEC_INCS = +AACDEC_INCS += -I ./fdkaac/libFDK/include/ +AACDEC_INCS += -I ./fdkaac/libSYS/include/ +AACDEC_INCS += -I ./fdkaac/libAACdec/include/ +AACDEC_INCS += -I ./fdkaac/libArithCoding/include/ +AACDEC_INCS += -I ./fdkaac/libAACdec/src/ +AACDEC_INCS += -I ./fdkaac/libMpegTPDec/include/ +AACDEC_INCS += -I ./fdkaac/libSBRdec/include/ +AACDEC_INCS += -I ./fdkaac/libPCMutils/include/ +AACDEC_INCS += -I ./fdkaac/libDRCdec/include/ +AACDEC_INCS += -I ./fdkaac/libSACdec/include/ +AACDEC_INCS += -I $(KERNEL_INC) + +OBJS_DEC = $(AACDEC_SRC:.cpp=.o) +#aac decoder -------------------------------------------end + +#AAC test sample code --------------------------start +AAC_TEST = $(PWD)/sample_audio_aac +AAC_TEST_SRC += $(PWD)/cvi_audio_aac_adp.c +AAC_TEST_SRC += $(PWD)/../cvi_audio_dl_adp.c + +MW_LIB ?= $(PWD)/../../../lib +AAC_LDFLAGS = +AAC_LDFLAGS += -L$(MW_LIB) -L$(MW_LIB)/3rd +ifeq ($(SDK_VER), 64bit) +AAC_LDFLAGS += -L $(PWD)/64bit +endif +ifeq ($(SDK_VER), 32bit) +AAC_LDFLAGS += -L $(PWD)/32bit +endif + +ifeq ($(SDK_VER), uclibc) +AAC_LDFLAGS += -L $(PWD)/uclibc +endif + +ifeq ($(SDK_VER), glibc_riscv64) +AAC_LDFLAGS += -L $(PWD)/riscv64 +endif + +ifeq ($(SDK_VER), musl_riscv64) +AAC_LDFLAGS += -L $(PWD)/musl_riscv64 +endif + +AAC_LDLIBS = +AAC_LDLIBS += -lpthread +AAC_LDLIBS += -lm -ldl +AAC_LDLIBS += -lstdc++ +AAC_LDLIBS += -laacdec2 +AAC_LDLIBS += -laacenc2 +AAC_LDLIBS += -laaccomm2 +AAC_LDLIBS += -laacsbrdec2 +AAC_LDLIBS += -laacsbrenc2 + + +#AAC_INCLUDES = -I$(MW_INC) +AAC_INCLUDES = +AAC_INCLUDES += -I ../../../include +AAC_INCLUDES += -I$(PWD) +AAC_INCLUDES += -I$(KERNEL_INC) +DEFINES += -DCVI_MODIFIED + +AAC_CFLAGS += -I . -fPIC -Wno-unused-result -Wno-format -Wl,--fatal-warning $(AAC_INCLUDES) $(DEFINES) + +ifeq ($(SDK_VER), 64bit) +AACENC_TARGET = $(CUR)/64bit/libaacenc2.a +AACENC_TARGET_S = $(CUR)/64bit/libaacenc2.so + +AACDEC_TARGET = $(CUR)/64bit/libaacdec2.a +AACDEC_TARGET_S = $(CUR)/64bit/libaacdec2.so + +AACCOMM_TARGET = $(CUR)/64bit/libaaccomm2.a +AACCOMM_TARGET_S = $(CUR)/64bit/libaaccomm2.so + +AACSBRENC_TARGET = $(CUR)/64bit/libaacsbrenc2.a +AACSBRENC_TARGET_S = $(CUR)/64bit/libaacsbrenc2.so + +AACSBRDEC_TARGET = $(CUR)/64bit/libaacsbrdec2.a +AACSBRDEC_TARGET_S = $(CUR)/64bit/libaacsbrdec2.so + +TARGET_FLD = $(MW_LIB)/../modules/audio/lib +PREBUILD_FLD = ./64bit +endif + +ifeq ($(SDK_VER), 32bit) +AACENC_TARGET = $(CUR)/32bit/libaacenc2.a +AACENC_TARGET_S = $(CUR)/32bit/libaacenc2.so + +AACDEC_TARGET = $(CUR)/32bit/libaacdec2.a +AACDEC_TARGET_S = $(CUR)/32bit/libaacdec2.so + +AACCOMM_TARGET = $(CUR)/32bit/libaaccomm2.a +AACCOMM_TARGET_S = $(CUR)/32bit/libaaccomm2.so + +AACSBRENC_TARGET = $(CUR)/32bit/libaacsbrenc2.a +AACSBRENC_TARGET_S = $(CUR)/32bit/libaacsbrenc2.so + +AACSBRDEC_TARGET = $(CUR)/32bit/libaacsbrdec2.a +AACSBRDEC_TARGET_S = $(CUR)/32bit/libaacsbrdec2.so + +TARGET_FLD = $(MW_LIB)/../modules/audio/lib_32 +PREBUILD_FLD = ./32bit +endif + +ifeq ($(SDK_VER), uclibc) +AACENC_TARGET = $(CUR)/uclibc/libaacenc2.a +AACENC_TARGET_S = $(CUR)/uclibc/libaacenc2.so + +AACDEC_TARGET = $(CUR)/uclibc/libaacdec2.a +AACDEC_TARGET_S = $(CUR)/uclibc/libaacdec2.so + +AACCOMM_TARGET = $(CUR)/uclibc/libaaccomm2.a +AACCOMM_TARGET_S = $(CUR)/uclibc/libaaccomm2.so + +AACSBRENC_TARGET = $(CUR)/uclibc/libaacsbrenc2.a +AACSBRENC_TARGET_S = $(CUR)/uclibc/libaacsbrenc2.so + +AACSBRDEC_TARGET = $(CUR)/uclibc/libaacsbrdec2.a +AACSBRDEC_TARGET_S = $(CUR)/uclibc/libaacsbrdec2.so + +TARGET_FLD = $(MW_LIB)/../modules/audio/uclibc +PREBUILD_FLD = ./uclibc +endif + +ifeq ($(SDK_VER), glibc_riscv64) +AACENC_TARGET = $(CUR)/riscv64/libaacenc2.a +AACENC_TARGET_S = $(CUR)/riscv64/libaacenc2.so + +AACDEC_TARGET = $(CUR)/riscv64/libaacdec2.a +AACDEC_TARGET_S = $(CUR)/riscv64/libaacdec2.so + +AACCOMM_TARGET = $(CUR)/riscv64/libaaccomm2.a +AACCOMM_TARGET_S = $(CUR)/riscv64/libaaccomm2.so + +AACSBRENC_TARGET = $(CUR)/riscv64/libaacsbrenc2.a +AACSBRENC_TARGET_S = $(CUR)/riscv64/libaacsbrenc2.so + +AACSBRDEC_TARGET = $(CUR)/riscv64/libaacsbrdec2.a +AACSBRDEC_TARGET_S = $(CUR)/riscv64/libaacsbrdec2.so + +TARGET_FLD = $(MW_LIB)/../modules/audio/riscv64 +PREBUILD_FLD = ./riscv64 +endif + +ifeq ($(SDK_VER), musl_riscv64) +AACENC_TARGET = $(CUR)/$(SDK_VER)/libaacenc2.a +AACENC_TARGET_S = $(CUR)/$(SDK_VER)/libaacenc2.so + +AACDEC_TARGET = $(CUR)/$(SDK_VER)/libaacdec2.a +AACDEC_TARGET_S = $(CUR)/$(SDK_VER)/libaacdec2.so + +AACCOMM_TARGET = $(CUR)/$(SDK_VER)/libaaccomm2.a +AACCOMM_TARGET_S = $(CUR)/$(SDK_VER)/libaaccomm2.so + +AACSBRENC_TARGET = $(CUR)/$(SDK_VER)/libaacsbrenc2.a +AACSBRENC_TARGET_S = $(CUR)/$(SDK_VER)/libaacsbrenc2.so + +AACSBRDEC_TARGET = $(CUR)/$(SDK_VER)/libaacsbrdec2.a +AACSBRDEC_TARGET_S = $(CUR)/$(SDK_VER)/libaacsbrdec2.so + +TARGET_FLD = $(MW_LIB)/../modules/audio/$(SDK_VER) +PREBUILD_FLD = ./$(SDK_VER) +endif + + +ARFLAGS = rcs +ARFLAGS_S = -shared -fPIC -o +CFLAGS = -fPIC -c -Os -ffunction-sections -fdata-sections +CFLAGS += -DCVI_MODIFIED + +AAC_TEST_LIB = $(AAC_LDLIBS) + + + +BUILDLIST= +BUILDLIST += $(AACENC_TARGET) +BUILDLIST += $(AACDEC_TARGET) +BUILDLIST += $(AACCOMM_TARGET) +BUILDLIST += $(AACSBRENC_TARGET) +BUILDLIST += $(AACSBRDEC_TARGET) +BUILDLIST += $(AAC_TEST) + +OBJECTPATHS_ENCSRC=$(addprefix $(PWD)/,$(notdir $(OBJS_ENC))) +OBJECTPATHS_DECSRC=$(addprefix $(PWD)/,$(notdir $(OBJS_DEC))) +OBJECTPATHS_COMMSRC=$(addprefix $(PWD)/,$(notdir $(OBJS_COMM))) +OBJECTPATHS_SBRENCSRC=$(addprefix $(PWD)/,$(notdir $(OBJS_SBRENC))) +OBJECTPATHS_SBRDECSRC=$(addprefix $(PWD)/,$(notdir $(OBJS_SBRDEC))) +all:$(BUILDLIST) + + +$(OBJS_ENC): + $(CC) $(AACENC_SRC) $(CFLAGS) $(AACENC_INCS) + + +$(OBJS_DEC): + $(CC) $(AACDEC_SRC) $(CFLAGS) $(AACDEC_INCS) + + +$(OBJS_COMM): + $(CC) $(AACCOMM_SRC) $(CFLAGS) $(AACCOMM_INCS) + +$(OBJS_SBRENC): + $(CC) $(AACSBRENC_SRC) $(CFLAGS) $(AACENC_INCS) + +$(OBJS_SBRDEC): + $(CC) $(AACSBRDEC_SRC) $(CFLAGS) $(AACDEC_INCS) + + +$(AACENC_TARGET) : $(OBJS_ENC) + $(AR) $(ARFLAGS) $(AACENC_TARGET) $(OBJECTPATHS_ENCSRC) + $(CC) $(ARFLAGS_S) $(AACENC_TARGET_S) $(OBJECTPATHS_ENCSRC) + $(STRIP) $(AACENC_TARGET_S) + rm -rf $(OBJECTPATHS_ENCSRC) + +$(AACDEC_TARGET) : $(OBJS_DEC) + $(AR) $(ARFLAGS) $(AACDEC_TARGET) $(OBJECTPATHS_DECSRC) + $(CC) $(ARFLAGS_S) $(AACDEC_TARGET_S) $(OBJECTPATHS_DECSRC) + $(STRIP) $(AACDEC_TARGET_S) + rm -rf $(OBJECTPATHS_DECSRC) + +$(AACCOMM_TARGET) : $(OBJS_COMM) + $(AR) $(ARFLAGS) $(AACCOMM_TARGET) $(OBJECTPATHS_COMMSRC) + $(CC) $(ARFLAGS_S) $(AACCOMM_TARGET_S) $(OBJECTPATHS_COMMSRC) + $(STRIP) $(AACCOMM_TARGET_S) + rm -rf $(OBJECTPATHS_COMMSRC) + +$(AACSBRENC_TARGET) : $(OBJS_SBRENC) + $(AR) $(ARFLAGS) $(AACSBRENC_TARGET) $(OBJECTPATHS_SBRENCSRC) + $(CC) $(ARFLAGS_S) $(AACSBRENC_TARGET_S) $(OBJECTPATHS_SBRENCSRC) + $(STRIP) $(AACSBRENC_TARGET_S) + rm -rf $(OBJECTPATHS_SBRENCSRC) + +$(AACSBRDEC_TARGET) : $(OBJS_SBRDEC) + $(AR) $(ARFLAGS) $(AACSBRDEC_TARGET) $(OBJECTPATHS_SBRDECSRC) + $(CC) $(ARFLAGS_S) $(AACSBRDEC_TARGET_S) $(OBJECTPATHS_SBRDECSRC) + $(STRIP) $(AACSBRDEC_TARGET_S) + rm -rf $(OBJECTPATHS_SBRDECSRC) + +$(AAC_TEST): $(AACENC_TARGET) $(AACDEC_TARGET) $(AACCOMM_TARGET) $(AACSBRENC_TARGET) $(AACSBRDEC_TARGET) + $(CC) -o $@ $(AAC_LDFLAGS) $(AAC_TEST_SRC) $(AAC_TEST_LIB) $(AAC_CFLAGS) + +.PHONY : clean +clean: + rm -f $(OBJECTPATHS_ENCSRC) $(OBJECTPATHS_DECSRC) $(OBJECTPATHS_COMMSRC) $(OBJECTPATHS_ENCSRC) $(OBJECTPATHS_SBRDECSRC) $(AAC_TEST) + diff --git a/middleware/v2/sample/audio/aac_sample/Makefile_old b/middleware/v2/sample/audio/aac_sample/Makefile_old new file mode 100644 index 000000000..32645dd78 --- /dev/null +++ b/middleware/v2/sample/audio/aac_sample/Makefile_old @@ -0,0 +1,189 @@ +.PHONY: CREATE_DIR + +#SDK_VER ?= uclibc +#SDK_VER ?= 64bit +## GCC COMPILER ## +##TOOLPATH=~/master_repo3/host-tools/gcc/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin +#TOOLPATH=../../../../host-tools/gcc/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin +#CROSS_COMPILE=$(TOOLPATH)/aarch64-linux-gnu- +#TOOLPATH=../../../../host-tools/gcc/arm-cvitek-linux-uclibcgnueabihf/bin +#CROSS_COMPILE=$(TOOLPATH)/arm-cvitek-linux-uclibcgnueabihf- +CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +AR = $(CROSS_COMPILE)ar +LD = $(CROSS_COMPILE)ld +STRIP = $(CROSS_COMPILE)strip + +FDK_AAC_DIR=./fdkaac +CUR = $(PWD) +#aac encoder -------------------------------------------start +SYS_SRC = \ + libSYS/src/genericStds.cpp \ + libSYS/src/syslib_channelMapDescr.cpp + +AACENC_SRC = $(wildcard $(PWD)/fdkaac/libAACenc/src/*.cpp) +AACENC_SRC_EXTRA = $(wildcard $(PWD)/fdkaac/libSACenc/src/*.cpp) +AACENC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libSBRenc/src/*.cpp) +AACENC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libMpegTPEnc/src/*.cpp) +AACENC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libSYS/src/*.cpp) +AACENC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libPCMutils/src/*.cpp) +AACENC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libFDK/src/*.cpp) +#AACENC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libFDK/src/arm/*.cpp) +AACENC_SRC += $(AACENC_SRC_EXTRA) +AACENC_SRC += ./aacenc_interface.cpp + +AACENC_INCS = +AACENC_INCS += -I ./fdkaac/libFDK/include/ +AACENC_INCS += -I ./fdkaac/libSYS/include/ +AACENC_INCS += -I ./fdkaac/libMpegTPEnc/include/ +AACENC_INCS += -I ./fdkaac/libSBRenc/include/ +AACENC_INCS += -I ./fdkaac/libAACenc/include/ +AACENC_INCS += -I ./fdkaac/libSACenc/include/ +AACENC_INCS += -I ./fdkaac/libPCMutils/include/ + +OBJS_ENC = $(AACENC_SRC:.cpp=.o) +#aac encoder -------------------------------------------end +#aac decoder -------------------------------------------start +AACDEC_SRC = $(wildcard $(PWD)/fdkaac/libAACdec/src/*.cpp) +AACDEC_SRC_EXTRA = $(wildcard $(PWD)/fdkaac/libFDK/src/*.cpp) +AACDEC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libSYS/src/*.cpp) +AACDEC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libArithCoding/src/*.cpp) +AACDEC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libMpegTPDec/src/*.cpp) +AACDEC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libSBRdec/src/*.cpp) +AACDEC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libPCMutils/src/*.cpp) +AACDEC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libDRCdec/src/*.cpp) +AACDEC_SRC_EXTRA += $(wildcard $(PWD)/fdkaac/libSACdec/src/*.cpp) + +AACDEC_SRC += $(AACDEC_SRC_EXTRA) +AACDEC_SRC += ./aacdec_interface.cpp + +AACDEC_INCS = +AACDEC_INCS += -I ./fdkaac/libFDK/include/ +AACDEC_INCS += -I ./fdkaac/libSYS/include/ +AACDEC_INCS += -I ./fdkaac/libAACdec/include/ +AACDEC_INCS += -I ./fdkaac/libArithCoding/include/ +AACDEC_INCS += -I ./fdkaac/libAACdec/src/ +AACDEC_INCS += -I ./fdkaac/libMpegTPDec/include/ +AACDEC_INCS += -I ./fdkaac/libSBRdec/include/ +AACDEC_INCS += -I ./fdkaac/libPCMutils/include/ +AACDEC_INCS += -I ./fdkaac/libDRCdec/include/ +AACDEC_INCS += -I ./fdkaac/libSACdec/include/ + +OBJS_DEC = $(AACDEC_SRC:.cpp=.o) +#aac decoder -------------------------------------------end + +#AAC test sample code --------------------------start +AAC_TEST = $(PWD)/sample_audio_aac +AAC_TEST_SRC += $(PWD)/cvi_audio_aac_adp.c +AAC_TEST_SRC += $(PWD)/../cvi_audio_dl_adp.c +AAC_LDFLAGS = +AAC_LDFLAGS += -L$(MW_LIB) -L$(MW_LIB)/3rd +ifeq ($(SDK_VER), 64bit) +AAC_LDFLAGS += -L $(PWD)/64bit +endif +ifeq ($(SDK_VER), 32bit) +AAC_LDFLAGS += -L $(PWD)/32bit +endif + +ifeq ($(SDK_VER), uclibc) +AAC_LDFLAGS += -L $(PWD)/uclibc +endif + +AAC_LDLIBS = +AAC_LDLIBS += -lpthread +AAC_LDLIBS += -lm -ldl +AAC_LDLIBS += -lstdc++ +AAC_LDLIBS += -laacdec2 +AAC_LDLIBS += -laacenc2 + +#AAC_INCLUDES = -I$(MW_INC) +AAC_INCLUDES = +AAC_INCLUDES += -I$(PWD) +DEFINES += -DCVI_MODIFIED + +AAC_CFLAGS += -I . -I ../../../include/ -fPIC -Wno-unused-result -Wno-format -Wl,--fatal-warning $(AAC_INCLUDES) $(DEFINES) + +ifeq ($(SDK_VER), 64bit) +AACENC_TARGET = $(CUR)/64bit/libaacenc2.a +AACENC_TARGET_S = $(CUR)/64bit/libaacenc2.so + +AACDEC_TARGET = $(CUR)/64bit/libaacdec2.a +AACDEC_TARGET_S = $(CUR)/64bit/libaacdec2.so +TARGET_FLD = $(MW_LIB)/../modules/audio/lib +PREBUILD_FLD = ./64bit +endif + +ifeq ($(SDK_VER), 32bit) +AACENC_TARGET = $(CUR)/32bit/libaacenc2.a +AACENC_TARGET_S = $(CUR)/32bit/libaacenc2.so + +AACDEC_TARGET = $(CUR)/32bit/libaacdec2.a +AACDEC_TARGET_S = $(CUR)/32bit/libaacdec2.so +TARGET_FLD = $(MW_LIB)/../modules/audio/lib_32 +PREBUILD_FLD = ./32bit +endif + +ifeq ($(SDK_VER), uclibc) +AACENC_TARGET = $(CUR)/uclibc/libaacenc2.a +AACENC_TARGET_S = $(CUR)/uclibc/libaacenc2.so + +AACDEC_TARGET = $(CUR)/uclibc/libaacdec2.a +AACDEC_TARGET_S = $(CUR)/uclibc/libaacdec2.so +TARGET_FLD = $(MW_LIB)/../modules/audio/uclibc +PREBUILD_FLD = ./uclibc +endif + + + +ARFLAGS = rcs +ARFLAGS_S = -shared -fPIC -o +CFLAGS = -fPIC -c -Os -ffunction-sections -fdata-sections +CFLAGS += -DCVI_MODIFIED + +AAC_TEST_LIB = $(AAC_LDLIBS) + + + +BUILDLIST= +BUILDLIST += $(AACENC_TARGET) +BUILDLIST += $(AACDEC_TARGET) +#BUILDLIST += $(AAC_TEST) + +OBJECTPATHS_ENCSRC=$(addprefix $(PWD)/,$(notdir $(OBJS_ENC))) +OBJECTPATHS_DECSRC=$(addprefix $(PWD)/,$(notdir $(OBJS_DEC))) + +all:$(BUILDLIST) + + +$(OBJS_ENC): + $(CC) $(AACENC_SRC) $(CFLAGS) $(AACENC_INCS) +#$(OBJS_ENC) : %.o : %.cpp +# $(CC)$(AACENC_SRC) $(CFLAGS) $(INCS) $< -o $@ + +$(OBJS_DEC): + $(CC) $(AACDEC_SRC) $(CFLAGS) $(AACDEC_INCS) + + +$(AACENC_TARGET) : $(OBJS_ENC) + $(AR) $(ARFLAGS) $(AACENC_TARGET) $(OBJECTPATHS_ENCSRC) + $(CC) $(ARFLAGS_S) $(AACENC_TARGET_S) $(OBJECTPATHS_ENCSRC) + $(STRIP) $(AACENC_TARGET) + rm -rf $(OBJECTPATHS_ENCSRC) + +$(AACDEC_TARGET) : $(OBJS_DEC) + $(AR) $(ARFLAGS) $(AACDEC_TARGET) $(OBJECTPATHS_DECSRC) + $(CC) $(ARFLAGS_S) $(AACDEC_TARGET_S) $(OBJECTPATHS_DECSRC) + $(STRIP) $(AACDEC_TARGET) + rm -rf $(OBJECTPATHS_DECSRC) + +$(AAC_TEST): + $(CC) -o $@ $(AAC_LDFLAGS) $(AAC_TEST_SRC) $(AAC_TEST_LIB) $(AAC_CFLAGS) + + +.PHONY : clean +clean: + rm -f $(OBJECTPATHS_ENCSRC) $(OBJECTPATHS_DECSRC) $(AAC_TEST) + + + + diff --git a/middleware/v2/sample/audio/aac_sample/README.md b/middleware/v2/sample/audio/aac_sample/README.md new file mode 100644 index 000000000..a76a8eaaf --- /dev/null +++ b/middleware/v2/sample/audio/aac_sample/README.md @@ -0,0 +1,41 @@ +# audio AAC sample code +#### [Notice]: +The aac sample code is based on the 3rdparty library fdk_aac built by Cvitek tool-chain. +User Can download the source code to build out the library personally. +Or contact Cvitek FAE to get the library required into adjust embedded platform. +#### [COPYRIGHT LICENSE Claim]: +* From the fdk_aac license claim: +Redistribution and use in source and binary forms, with or without modification, are permitted without payment of copyright license fees provided that you satisfy the following conditions: +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or your modifications thereto in source code form. +See more through webpage: https://fedoraproject.org/wiki/Licensing/FDK-AAC +* From Cvitek: +Cvitek only suggest the using of fdk_aac codec for AAC transcode. We(Cvitek) do not provide the source code inside the SDK package. The usage of the AAC codec should follow the origin fdk_aac license rule . +Cvitek only provide the sample for usage of AAC codec. Further payment or copyright under business concern will not be the responsibility of Cvitek without contacting Cvitek product. + +#### [Build Code]: +You can: + - Contact the FAE of Cvitek to get the libs. + - Or check the [build by user] paragraph in below section. + - +#### +[Code flow/ Sample code]: +> Check the main function in cvi_audio_aac_adp.c +> User can see the encode and decode procedure. + + +This text you see here is *actually* written in Markdown! To get a feel for Markdown's syntax, type some text into the left window and watch the results in the right. + +#### [build by user] +-Download the toolchain for your project (ex. aarch64 / arm /...) +-Download fdk_aac source in current folder, and rename it to fdkaac. + All the source of fdk aac should under the folder of fdkaac. +-The fdk_aac version we used is 2.0.1, you can check the release note below: + (https://github.com/mstorsjo/fdk-aac/releases) +-make the directory 64bit, 32bit +-modified the makefile to setup the gcc toolchain path +-make clean; make +-the output locate in lib64/lib32 folders: libaacdec2.so, libaacenc2.so, + update to your embedded board and try the encode decode. + + + diff --git a/middleware/v2/sample/audio/aac_sample/aacdec_interface.cpp b/middleware/v2/sample/audio/aac_sample/aacdec_interface.cpp new file mode 100644 index 000000000..f22f718f6 --- /dev/null +++ b/middleware/v2/sample/audio/aac_sample/aacdec_interface.cpp @@ -0,0 +1,472 @@ +/* + * Copyright ., Ltd. 2019-2020. All rights reserved. + * + * File Name: aacdec_interface.c + * Description: audio transcode function interface as example + */ + +#include +#include +#include +#include +#include +#include "fdkaac/libAACdec/include/aacdecoder_lib.h" +#include "fdkaac/libAACenc/include/aacenc_lib.h" +#include "cvi_type.h" +#include "cvi_aacdec.h" + + +#define _VERSION_TAG_ "audio_aac_fdkaac_dec_20210407A" + +#ifndef AAC_MAX_NCHANS +#define AAC_MAX_NCHANS 2 +#endif +#define AAC_MAX_NSAMPS 1024 +#define AAC_MAINBUF_SIZE (768 * AAC_MAX_NCHANS) +/**aVersion, (const char *)_VERSION_TAG_); + printf("[%s][%s]\n", __func__, _VERSION_TAG_); + return 0; +} + + + +/** + *brief create and initial decoder device. + *attention + *N/A + *param[in] enTranType : transport type + *retval ::CVIAACDecoder : init success, return non-NULL handle. + *retval ::NULL : init failure, return NULL + *see + *N/A + */ +CVIAACDecoder AACInitDecoder(AACDECTransportType enTranType) +{ + HANDLE_AACDECODER decoder; + //AAC_DECODER_ERROR err; + + if (enTranType == AACDEC_ADTS) { + printf("[%s][%s]\n", __func__, _VERSION_TAG_); + decoder = aacDecoder_Open(TT_MP4_ADTS, 1); + printf("ADTS header decoder set\n"); + } else if (enTranType == AACDEC_LOAS) + decoder = aacDecoder_Open(TT_MP4_LOAS, 1); + else if (enTranType == AACDEC_LATM_MCP1) + decoder = aacDecoder_Open(TT_MP4_LATM_MCP1, 1); + else { + printf("[Warning]set TransportType[%d] to RawMode\n", (int)enTranType); + decoder = aacDecoder_Open(TT_MP4_RAW, 1); + printf("set to TT_MP4_RAW\n"); + + } + + + if (decoder == NULL) { + printf("[Error][%s][%d]\n", __func__, __LINE__); + return NULL; + } + + return (void *)decoder; + +} + + +/** + *brief destroy AAC-Decoder, free the memory. + *attention \n + *N/A + *param[in] CVIAACDecoder : AAC-Decoder handle + *see \n + *N/A + */ +CVI_VOID AACFreeDecoder(CVIAACDecoder CVIAACDecoder) +{ + if (CVIAACDecoder != NULL) + aacDecoder_Close((HANDLE_AACDECODER)CVIAACDecoder); + +} + + + +/** + *brief set RawMode before decode Raw Format aac bitstream(Reserved API, unused now.) + *attention \n + *N/A + *param[in] CVIAACDecoder : AAC-Decoder handle + *param[in] Chans : inout channels + *param[in] sampRate : input sample rate + *retval ::CVI_FAILURE : RESERVED API, always return CVI_FAILURE. + *see \n + *N/A + */ +CVI_S32 AACSetRawMode(CVIAACDecoder CVIAACDecoder, + CVI_S32 nChans, + CVI_S32 sampRate) +{ + UCHAR conf[4] = {0xFF, 0xFF, 0xFF, 0xFF}; + UCHAR* conf_array[1] = { conf }; + UINT length = 4; + //Step1: Find the config data + HANDLE_AACENCODER tmp_enchandle; + AACENC_InfoStruct tmp_info = { 0 }; + if (aacEncOpen(&tmp_enchandle, 0, nChans) != AACENC_OK) { + printf("[Error][%s][%d]\n", __func__, __LINE__); + return (-1); + } + + if (nChans == 1) { + if (aacEncoder_SetParam(tmp_enchandle, AACENC_CHANNELMODE, MODE_1) != AACENC_OK) { + printf("[Error]Unable to set the channel mode[%s][%d]\n", __func__, __LINE__); + return (-1); + } + } else { + if (aacEncoder_SetParam(tmp_enchandle, AACENC_CHANNELMODE, MODE_2) != AACENC_OK) { + printf("[Error]Unable to set the channel mode[%s][%d]\n", __func__, __LINE__); + return (-1); + } + } + + if (aacEncoder_SetParam(tmp_enchandle, AACENC_AOT, 2) != AACENC_OK) { + printf("[Error][%s][%d]\n", __func__, __LINE__); + return (-1); + } + + if (aacEncoder_SetParam(tmp_enchandle, AACENC_SAMPLERATE, sampRate) != AACENC_OK) { + printf("[Error]Unable to set the AOT[%s][%d]\n", __func__, __LINE__); + return (-1); + } + + if (aacEncoder_SetParam(tmp_enchandle, AACENC_AFTERBURNER, 1) != AACENC_OK) { + printf("[Error]Unable to set the afterburner mode[%s][%d]\n", __func__, __LINE__); + return (-1); + } + + if (aacEncEncode(tmp_enchandle, NULL, NULL, NULL, NULL) != AACENC_OK) { + printf("[Error]Unable to initialize the encoder[%s][%d]\n", __func__, __LINE__); + return (-1); + } + + if (aacEncInfo(tmp_enchandle, &tmp_info) != AACENC_OK) { + printf("[Error]Unable to get the encoder info[%s][%d]\n", __func__, __LINE__); + return (-1); + } + + memcpy(conf, tmp_info.confBuf, 4); + conf_array[1] = { conf }; + + printf("[%s]print out config size[%d] buffer[0x%x] [0x%x] [0x%x] [0x%x] [0x%x]\n", + __func__, tmp_info.confSize, + conf[0],conf[1], conf[2], conf[3], conf[4]); + + //Step2 : Update the config data + AAC_DECODER_ERROR err = AAC_DEC_OK; + + err = aacDecoder_ConfigRaw((HANDLE_AACDECODER)CVIAACDecoder, + conf_array, + &length); + + if (err != AAC_DEC_OK) { + printf("[Error][%s][%d]\n", __func__, __LINE__); + printf("err = [0x%x]\n", err); + } + + return 0; +} + +int get_one_ADTS_frame(unsigned char *buffer, size_t buf_size, size_t *data_size) +{ + size_t size = 0; + size_t save_buf_size = buf_size; + + if (!buffer || !data_size) + return -1; + + while (1) { + if (buf_size < 7) + return -1; + + if ((buffer[0] == 0xff) && ((buffer[1] & 0xf0) == 0xf0)) { + size |= ((buffer[3] & 0x03) << 11); //high 2 bit + size |= buffer[4]<<3; //middle 8 bit + size |= ((buffer[5] & 0xe0)>>5); //low 3bit + //printf("adts-->header[0x%x][0x%x][0x%x][0x%x]\n", buffer[0], buffer[1], buffer[2], buffer[3]); + break; + } + + --buf_size; + ++buffer; + } + + if (buf_size < size) { + printf("[%s] no header...\n", __func__); + return -1; + } + //memcpy(data, buffer, size); + //printf("aft getOneFrame[0x%x][0x%x][0x%x][0x%x]\n", data[0], data[1], data[2], data[3]); + *data_size = size;//parsing size from header + //printf("[%s]require size[%d] left check[%d]\n", __func__, size, (2048 - size)); + return (save_buf_size - size); //return bytes left +} + +/** + *brief look for valid AAC sync header + *attention \n + *N/A + *param[in] CVIAACDecoder : AAC-Decoder handle + *param[in/out] ppInbufPtr : address of the pointer of start-point of the bitstream + *param[in/out] pBytesLeft : pointer to BytesLeft that indicates bitstream numbers at input buffer + *retval ::<0 : err, always return ERR_AAC_INDATA_UNDERFLOW + *retval ::other : Success, return number bytes of current frame + *see \n + *N/A + */ +CVI_S32 AACDecodeFindSyncHeader(CVIAACDecoder CVIAACDecoder, + CVI_U8 **ppInbufPtr, + CVI_S32 *pBytesLeft) +{ +#if 0 +1024 990 sample for AAC_LC +2048 or 1920 for HE-AAC (v2) +512 or 480 for AAC-LD and AAC-ELD +768, 1024, 2048 or 4096 for USAC +#endif + + AAC_DECODER_ERROR err = AAC_DEC_OK; + UINT bytes_valid; + unsigned int input_sizebytes = *pBytesLeft; + int current_index = 0; + + unsigned char *inBufferArray[1]; + unsigned int inBuffReaded[1]; + + //step 1: wrap the input data to array + inBufferArray[0] = (unsigned char *)(*ppInbufPtr); + inBuffReaded[0] = input_sizebytes; + bytes_valid = input_sizebytes; + + + //step2 : fill the aacDecoder_Fill and check the return valid_bytes + err = aacDecoder_Fill((HANDLE_AACDECODER)CVIAACDecoder, + inBufferArray, + inBuffReaded, + &bytes_valid); + + printf("aacDecoder_Fill->bytes_valid[%d]\n", bytes_valid); + + if (err == AAC_DEC_OK) + printf("aacDecoder_Fill return ok\n"); + else { + printf("err=[%d]\n", (int)err); + current_index = input_sizebytes - bytes_valid; + *pBytesLeft = bytes_valid; + } + + return current_index; +} + + + +/** + *brief decoding AAC frame and output 1024(LC) OR + *2048(HEAAC/eAAC/eAAC+) 16bit PCM samples per channel. + *attention \n + *param[in] CVIAACDecoder : AAC-Decoder handle + *param[in] ppInbufPtr : address of the pointer of start-point of the bitstream + *param[in/out] pBytesLeft : pointer to BytesLeft that indicates + *bitstream numbers at input buffer,indicates the left bytes + *param[in] pOutPcm : the address of the out pcm buffer, + *pcm data in noninterlaced fotmat: L/L/L/... R/R/R/... + *retval :: SUCCESS : Success + *retval :: ERROR_CODE : FAILURE, return error_code. + *see \n + */ +CVI_S32 AACDecodeFrame(CVIAACDecoder CVIAACDecoder, + CVI_U8 **ppInbufPtr, + CVI_S32 *pBytesLeft, + CVI_S16 *pOutPcm) +{ + AAC_DECODER_ERROR err = AAC_DEC_OK; + CStreamInfo *theInfo = NULL; + unsigned char *inBufferArray[1]; + unsigned int inBuffReaded[1]; + unsigned int byte_left; + + //CVI_U8 *tmpcheck; + //tmpcheck = (CVI_U8 *)(*ppInbufPtr); + //printf("in [0x%x] [0x%x] [0x%x] inbytes[%d] \n", tmpcheck[0], tmpcheck[1], tmpcheck[2], *pBytesLeft); + + inBufferArray[0] = (unsigned char *)(*ppInbufPtr); + inBuffReaded[0] = *pBytesLeft; + byte_left = *pBytesLeft; +#if 0 + unsigned char fake_inputdata[10240] = {0}; + unsigned char fake_outputdata[10240] = {0}; + int inputbytes = byte_left; + + memcpy(fake_inputdata, inBufferArray[0] , inputbytes); +#endif + + err = aacDecoder_Fill((HANDLE_AACDECODER)CVIAACDecoder, + inBufferArray, + inBuffReaded, + &byte_left); + + if (err != AAC_DEC_OK) { + printf("[Error][%s][%d]\n", __func__, __LINE__); + printf("err = [0x%x]\n", err); + } else { + //printf("[xxxx]aacDecoder_Fill after byte left[%d]\n", byte_left); + //sleep(1); + } + +#if 0//AAC ADTS header check + + int fake = 0; + int fake_byteleft = 0; + printf("fake_inputdata[0x%x] [0x%x]\n", fake_inputdata[0], fake_inputdata[1]); + fake_byteleft = get_one_ADTS_frame( + fake_inputdata, + inputbytes, + (size_t *)&fake); + + if (fake_byteleft < 0) + printf("[xxxxx]fake_byteleft no header\n"); + else + printf("[xxxxxx]fake_byteleft[%d] data size[%d]\n", fake_byteleft, fake); +#else + //printf("no self check\n"); +#endif + + err = aacDecoder_DecodeFrame((HANDLE_AACDECODER)CVIAACDecoder, + (INT_PCM *) pOutPcm, + (1024 * 30), 0); + + + if (err != AAC_DEC_OK) { + printf("[Error][%s][%d]\n", __func__, __LINE__); + printf("err = [0x%x]\n", err); + if (err == AAC_DEC_NOT_ENOUGH_BITS) + printf("err[%s][%d]AAC_DEC_NOT_ENOUGH_BITS\n", __func__, __LINE__); + if (err == AAC_DEC_TRANSPORT_ERROR) + printf("err[%s][%d]AAC_DEC_TRANSPORT_ERROR\n", __func__, __LINE__); + + return err; + } else { + //for debug usage + //printf("out [0x%x] [0x%x] [0x%x]\n", pOutPcm[0], pOutPcm[1], pOutPcm[2]); + } + + + + theInfo = aacDecoder_GetStreamInfo((HANDLE_AACDECODER)CVIAACDecoder); + if (theInfo == NULL) { + printf("[Error]Get null info[%s][%d]\n", __func__, __LINE__); + //sleep(1); + } + //printf("aacDecoder_DecodeFrame theInfo->frameSize[%d]\n", + // theInfo->frameSize); + *pBytesLeft = byte_left; + + return 0; +} + + +/** + *brief get the frame information. + *attention \n + *param[in] CVIAACDecoder : AAC-Decoder handle + *param[out] aacFrameInfo : frame information + *retval :: CVI_SUCCESS : Success + *retval :: ERROR_CODE : FAILURE, return error_code. + *see \n + *N/A + */ +CVI_S32 AACGetLastFrameInfo(CVIAACDecoder CVIAACDecoder, + AACFrameInfo *aacFrameInfo) +{ + HANDLE_AACDECODER decoder = (HANDLE_AACDECODER)CVIAACDecoder; + + CStreamInfo* info = aacDecoder_GetStreamInfo(decoder); + + aacFrameInfo->bitRate = info->bitRate; + aacFrameInfo->nChans = info->numChannels; + aacFrameInfo->sampRateCore = info->aacSampleRate; + aacFrameInfo->sampRateOut = info->sampleRate; + aacFrameInfo->bitsPerSample = 16; + aacFrameInfo->outputSamps = info->frameSize; + aacFrameInfo->profile = info->profile; + aacFrameInfo->tnsUsed = 0; + aacFrameInfo->pnsUsed = 0; + aacFrameInfo->bytespassDec = info->numTotalBytes; + + // printf("aacDecoder_GetStreamInfo br[%d] ch[%d] sr[%d] total bytes pass[%ld]aacsr[%d]\n", + // info->bitRate, + // info->numChannels, + // info->sampleRate, + // info->numTotalBytes, + // info->aacSampleRate); + + return 0; +} + + +/** + *brief set eosflag. + *attention \n + *param[in] CVIAACDecoder : AAC-Decoder handle + *param[in] s32Eosflag : end flag + *retval :: CVI_SUCCESS : Success + *retval :: ERROR_CODE : FAILURE, return error_code. + *see \n + *N/A + */ + +CVI_S32 AACDecoderSetEosFlag(CVIAACDecoder CVIAACDecoder, + CVI_S32 s32Eosflag) +{ + //TODO: + return 0; +} + + + +/** + *brief flush internal codec state (after seeking, for example) + *attention \n + *param[in] CVIAACDecoder : AAC-Decoder handle + *retval :: CVI_SUCCESS : Success + *retval :: ERROR_CODE : FAILURE, return error_code. + *see \n + *N/A + */ +CVI_S32 AACFlushCodec(CVIAACDecoder CVIAACDecoder) +{ + //TODO: + return 0; +} \ No newline at end of file diff --git a/middleware/v2/sample/audio/aac_sample/aacenc_interface.cpp b/middleware/v2/sample/audio/aac_sample/aacenc_interface.cpp new file mode 100644 index 000000000..02b7d9483 --- /dev/null +++ b/middleware/v2/sample/audio/aac_sample/aacenc_interface.cpp @@ -0,0 +1,311 @@ +/* + * Copyright ., Ltd. 2019-2020. All rights reserved. + * + * File Name: aacenc_interface.c + * Description: audio transcode function interface as example + */ + +#include +#include +#include +#include +#include +#include "fdkaac/libAACenc/include/aacenc_lib.h" +#include "cvi_type.h" +#include "cvi_aacenc.h" + + +#define MAX_CHANNELS 2 +#define AACENC_BLOCKSIZE 1024 +#define _VERSION_TAG_ "audio_aac_fdkaac_enc_20210407" +#define AACLC_ENC_AOT 2 +#define HEAAC_ENC_AOT 5 +#define HEAAC_PLUS_ENC_AOT 29 +#define AACLD_ENC_AOT 23 +#define AACELD_ENC_AOT 39 + +int CodecArray[5] = { + AACLC_ENC_AOT, + HEAAC_ENC_AOT, + HEAAC_PLUS_ENC_AOT, + AACLD_ENC_AOT, + AACELD_ENC_AOT +}; + +int TransportTable[3] = { + TT_MP4_ADTS, + TT_MP4_LOAS, + TT_MP4_LATM_MCP1 +}; + + + +/** + *brief Get version information. + *attention \n + *N/A + *param[in] pVersion version describe struct + *retval ::CVI_SUCCESS : Success + *retval ::CVI_FAILURE : FAILURE + *see \n + *N/A + */ +CVI_S32 CVI_AACENC_GetVersion(AACENC_VERSION_S *pVersion) +{ + printf("[%s][%s]\n", __func__, _VERSION_TAG_); + strcpy((char *)pVersion->aVersion, (const char *)_VERSION_TAG_); + return 0; +} + +/** + *brief get reasonable default configuration. + *attention \n + *N/A + *param[in] pstConfig pointer to an configuration information structure + *retval ::CVI_SUCCESS : Success + *retval ::CVI_FAILURE : FAILURE + *see \n + *N/A + */ +int AACInitDefaultConfig(AACENC_CONFIG *pstConfig) +{ + +#if 0 +typedef struct { + AuQuality quality; + AuEncoderFormat coderFormat; + short bitsPerSample; + int sampleRate; /**